From 9c60c33cd614f23643298d40a5ecef82a6f2324c Mon Sep 17 00:00:00 2001 From: TATECK Date: Wed, 9 Feb 2022 03:05:24 +0900 Subject: [PATCH] =?UTF-8?q?=EC=B5=9C=EC=B4=88=20=EB=B0=B0=ED=8F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ver.02.2.2 --- AvocadoEdition/_common.php | 3 + AvocadoEdition/_head.php | 5 + AvocadoEdition/_tail.php | 5 + AvocadoEdition/adm/_common.php | 5 + AvocadoEdition/adm/action_delete.php | 29 + AvocadoEdition/adm/action_list.php | 202 + AvocadoEdition/adm/action_list_update.php | 30 + AvocadoEdition/adm/action_reply.php | 58 + AvocadoEdition/adm/admin.ajax.js | 3 + AvocadoEdition/adm/admin.head.php | 125 + AvocadoEdition/adm/admin.js | 129 + AvocadoEdition/adm/admin.lib.php | 475 + AvocadoEdition/adm/admin.menu100.php | 22 + AvocadoEdition/adm/admin.menu200.php | 12 + AvocadoEdition/adm/admin.menu300.php | 9 + AvocadoEdition/adm/admin.menu400.php | 21 + AvocadoEdition/adm/admin.menu500.php | 14 + AvocadoEdition/adm/admin.menu900.php | 10 + AvocadoEdition/adm/admin.tail.php | 59 + AvocadoEdition/adm/ajax.token.php | 14 + AvocadoEdition/adm/ajax/_common.php | 5 + AvocadoEdition/adm/auth_list.php | 252 + AvocadoEdition/adm/auth_list_delete.php | 27 + AvocadoEdition/adm/auth_update.php | 30 + AvocadoEdition/adm/banner_form.php | 140 + AvocadoEdition/adm/banner_form_update.php | 86 + AvocadoEdition/adm/banner_list.php | 120 + AvocadoEdition/adm/board_copy.php | 73 + AvocadoEdition/adm/board_copy_update.php | 205 + AvocadoEdition/adm/board_delete.inc.php | 33 + AvocadoEdition/adm/board_form.php | 920 + AvocadoEdition/adm/board_form_update.php | 411 + AvocadoEdition/adm/board_list.php | 211 + AvocadoEdition/adm/board_list_update.php | 67 + AvocadoEdition/adm/board_thumbnail_delete.php | 52 + AvocadoEdition/adm/boardgroup_form.php | 150 + AvocadoEdition/adm/boardgroup_form_update.php | 71 + AvocadoEdition/adm/boardgroup_list.php | 215 + AvocadoEdition/adm/boardgroup_list_update.php | 47 + AvocadoEdition/adm/boardgroupmember_form.php | 127 + AvocadoEdition/adm/boardgroupmember_list.php | 156 + .../adm/boardgroupmember_update.php | 70 + AvocadoEdition/adm/browscap.php | 45 + AvocadoEdition/adm/browscap_convert.php | 46 + AvocadoEdition/adm/browscap_converter.php | 75 + AvocadoEdition/adm/browscap_update.php | 24 + AvocadoEdition/adm/cache_file_delete.php | 48 + AvocadoEdition/adm/captcha_file_delete.php | 53 + AvocadoEdition/adm/character_article_list.php | 327 + .../adm/character_article_list_update.php | 124 + .../adm/character_article_update.php | 25 + AvocadoEdition/adm/character_delete.php | 36 + AvocadoEdition/adm/character_form.php | 449 + AvocadoEdition/adm/character_form_update.php | 238 + AvocadoEdition/adm/character_list.php | 317 + AvocadoEdition/adm/character_list_update.php | 108 + AvocadoEdition/adm/class_list.php | 214 + AvocadoEdition/adm/class_list_delete.php | 88 + AvocadoEdition/adm/class_update.php | 44 + AvocadoEdition/adm/community_form.php | 272 + AvocadoEdition/adm/community_form_update.php | 80 + AvocadoEdition/adm/config_form.php | 1195 + AvocadoEdition/adm/config_form_update.php | 159 + AvocadoEdition/adm/contentform.php | 207 + AvocadoEdition/adm/contentformupdate.php | 99 + AvocadoEdition/adm/contentlist.php | 98 + AvocadoEdition/adm/couple_list.php | 231 + AvocadoEdition/adm/couple_list_delete.php | 26 + AvocadoEdition/adm/couple_update.php | 31 + AvocadoEdition/adm/css/admin.css | 426 + AvocadoEdition/adm/css/admin.layout.css | 280 + AvocadoEdition/adm/css/theme.css | 9 + AvocadoEdition/adm/data_backup.php | 275 + AvocadoEdition/adm/data_backup_delete.php | 11 + AvocadoEdition/adm/data_backup_update.php | 95 + AvocadoEdition/adm/data_restore.php | 256 + AvocadoEdition/adm/data_restore_update.php | 35 + AvocadoEdition/adm/design_form.php | 1833 ++ AvocadoEdition/adm/design_form_css.php | 777 + AvocadoEdition/adm/design_form_update.php | 103 + AvocadoEdition/adm/emoticon_form_update.php | 28 + AvocadoEdition/adm/emoticon_list.php | 201 + AvocadoEdition/adm/emoticon_list_update.php | 36 + AvocadoEdition/adm/exp_list.php | 263 + AvocadoEdition/adm/exp_list_delete.php | 54 + AvocadoEdition/adm/exp_update.php | 49 + AvocadoEdition/adm/explorer_list.php | 273 + AvocadoEdition/adm/explorer_list_update.php | 46 + AvocadoEdition/adm/explorer_update.php | 40 + AvocadoEdition/adm/faqform.php | 98 + AvocadoEdition/adm/faqformupdate.php | 45 + AvocadoEdition/adm/faqlist.php | 95 + AvocadoEdition/adm/faqmasterform.php | 165 + AvocadoEdition/adm/faqmasterformupdate.php | 74 + AvocadoEdition/adm/faqmasterlist.php | 128 + AvocadoEdition/adm/file_list.php | 18 + AvocadoEdition/adm/head.sub.php | 62 + AvocadoEdition/adm/img/ajax_loader.gif | Bin 0 -> 45592 bytes AvocadoEdition/adm/img/check.png | Bin 0 -> 7401 bytes AvocadoEdition/adm/img/close.gif | Bin 0 -> 200 bytes AvocadoEdition/adm/img/close.png | Bin 0 -> 1086 bytes AvocadoEdition/adm/img/hd_bg.jpg | Bin 0 -> 8188 bytes AvocadoEdition/adm/img/link_icon.gif | Bin 0 -> 53 bytes AvocadoEdition/adm/img/logo.jpg | Bin 0 -> 6018 bytes AvocadoEdition/adm/img/logo.png | Bin 0 -> 2252 bytes AvocadoEdition/adm/img/service_img1.jpg | Bin 0 -> 6634 bytes AvocadoEdition/adm/img/service_img2.jpg | Bin 0 -> 7259 bytes AvocadoEdition/adm/img/sub_menu_ico.gif | Bin 0 -> 87 bytes AvocadoEdition/adm/img/svc_btn_01.jpg | Bin 0 -> 18856 bytes AvocadoEdition/adm/img/svc_btn_02.jpg | Bin 0 -> 3109 bytes AvocadoEdition/adm/img/svc_btn_03.jpg | Bin 0 -> 2703 bytes AvocadoEdition/adm/img/svc_btn_04.jpg | Bin 0 -> 3221 bytes AvocadoEdition/adm/img/svc_btn_05.jpg | Bin 0 -> 4763 bytes AvocadoEdition/adm/img/theme_img.jpg | Bin 0 -> 7992 bytes AvocadoEdition/adm/img/ts01.gif | Bin 0 -> 177 bytes AvocadoEdition/adm/img/ts02.gif | Bin 0 -> 188 bytes AvocadoEdition/adm/img/ts03.gif | Bin 0 -> 196 bytes AvocadoEdition/adm/img_list.php | 18 + AvocadoEdition/adm/index.php | 269 + AvocadoEdition/adm/intro_form.php | 121 + AvocadoEdition/adm/intro_form_update.php | 88 + AvocadoEdition/adm/intro_list.php | 120 + AvocadoEdition/adm/inventory_list.php | 254 + AvocadoEdition/adm/inventory_list_delete.php | 24 + AvocadoEdition/adm/inventory_update.php | 54 + AvocadoEdition/adm/item_form.php | 308 + AvocadoEdition/adm/item_form_update.php | 104 + AvocadoEdition/adm/item_list.php | 267 + AvocadoEdition/adm/item_list_update.php | 59 + AvocadoEdition/adm/level_form_update.php | 23 + AvocadoEdition/adm/level_list.php | 198 + AvocadoEdition/adm/level_list_update.php | 59 + AvocadoEdition/adm/mail_delete.php | 24 + AvocadoEdition/adm/mail_form.php | 84 + AvocadoEdition/adm/mail_list.php | 108 + AvocadoEdition/adm/mail_preview.php | 34 + AvocadoEdition/adm/mail_select_form.php | 122 + AvocadoEdition/adm/mail_select_list.php | 121 + AvocadoEdition/adm/mail_select_update.php | 87 + AvocadoEdition/adm/mail_test.php | 39 + AvocadoEdition/adm/mail_update.php | 39 + AvocadoEdition/adm/member_delete.php | 29 + AvocadoEdition/adm/member_form.php | 280 + AvocadoEdition/adm/member_form_update.php | 167 + AvocadoEdition/adm/member_list.php | 248 + AvocadoEdition/adm/member_list_delete.php | 37 + AvocadoEdition/adm/member_list_update.php | 92 + AvocadoEdition/adm/menu_form.php | 151 + AvocadoEdition/adm/menu_form_search.php | 111 + AvocadoEdition/adm/menu_list.php | 206 + AvocadoEdition/adm/menu_list_update.php | 70 + AvocadoEdition/adm/newwinform.php | 150 + AvocadoEdition/adm/newwinformupdate.php | 53 + AvocadoEdition/adm/newwinlist.php | 118 + AvocadoEdition/adm/order_list.php | 170 + AvocadoEdition/adm/order_list_delete.php | 21 + AvocadoEdition/adm/phpinfo.php | 10 + AvocadoEdition/adm/point_list.php | 252 + AvocadoEdition/adm/point_list_delete.php | 59 + AvocadoEdition/adm/point_update.php | 49 + AvocadoEdition/adm/poll_delete.php | 27 + AvocadoEdition/adm/poll_form.php | 123 + AvocadoEdition/adm/poll_form_update.php | 69 + AvocadoEdition/adm/poll_list.php | 163 + AvocadoEdition/adm/popular_list.php | 171 + AvocadoEdition/adm/popular_rank.php | 112 + AvocadoEdition/adm/qa_config.php | 263 + AvocadoEdition/adm/qa_config_update.php | 67 + AvocadoEdition/adm/quest_form.php | 178 + AvocadoEdition/adm/quest_form_update.php | 35 + AvocadoEdition/adm/quest_list.php | 242 + AvocadoEdition/adm/quest_list_update.php | 45 + AvocadoEdition/adm/recipi_list.php | 291 + AvocadoEdition/adm/recipi_list_update.php | 36 + AvocadoEdition/adm/recipi_update.php | 61 + AvocadoEdition/adm/sendmail_test.php | 65 + AvocadoEdition/adm/service.php | 49 + AvocadoEdition/adm/session_file_delete.php | 61 + AvocadoEdition/adm/shop_form.php | 374 + AvocadoEdition/adm/shop_form_update.php | 109 + AvocadoEdition/adm/shop_list.php | 275 + AvocadoEdition/adm/shop_list_update.php | 52 + AvocadoEdition/adm/side_list.php | 214 + AvocadoEdition/adm/side_list_delete.php | 88 + AvocadoEdition/adm/side_update.php | 44 + AvocadoEdition/adm/sql_write.sql | 71 + AvocadoEdition/adm/status_form_update.php | 22 + AvocadoEdition/adm/status_list.php | 231 + AvocadoEdition/adm/status_list_update.php | 61 + AvocadoEdition/adm/theme.js | 80 + AvocadoEdition/adm/theme.php | 78 + AvocadoEdition/adm/theme_config_load.php | 185 + AvocadoEdition/adm/theme_detail.php | 67 + AvocadoEdition/adm/theme_preview.php | 72 + AvocadoEdition/adm/theme_update.php | 94 + AvocadoEdition/adm/thumbnail_file_delete.php | 68 + AvocadoEdition/adm/title_has_list.php | 262 + AvocadoEdition/adm/title_has_list_delete.php | 24 + AvocadoEdition/adm/title_has_update.php | 72 + AvocadoEdition/adm/title_list.php | 230 + AvocadoEdition/adm/title_list_update.php | 80 + AvocadoEdition/adm/title_update.php | 43 + AvocadoEdition/adm/viewer_form.php | 256 + AvocadoEdition/adm/viewer_form_update.php | 62 + AvocadoEdition/adm/visit.sub.php | 57 + AvocadoEdition/adm/visit_browser.php | 97 + AvocadoEdition/adm/visit_date.php | 86 + AvocadoEdition/adm/visit_delete.php | 121 + AvocadoEdition/adm/visit_delete_update.php | 60 + AvocadoEdition/adm/visit_device.php | 101 + AvocadoEdition/adm/visit_domain.php | 104 + AvocadoEdition/adm/visit_hour.php | 82 + AvocadoEdition/adm/visit_list.php | 118 + AvocadoEdition/adm/visit_month.php | 90 + AvocadoEdition/adm/visit_os.php | 101 + AvocadoEdition/adm/visit_search.php | 149 + AvocadoEdition/adm/visit_week.php | 81 + AvocadoEdition/adm/visit_year.php | 86 + AvocadoEdition/adm/write_count.php | 210 + AvocadoEdition/ajax/_common.php | 3 + AvocadoEdition/ajax/_search_character.php | 35 + AvocadoEdition/ajax/_search_item.php | 44 + AvocadoEdition/ajax/_search_member.php | 36 + AvocadoEdition/ajax/_search_title.php | 34 + AvocadoEdition/ajax/board_call.php | 50 + AvocadoEdition/ajax/close_call.php | 9 + AvocadoEdition/ajax/close_memo.php | 8 + AvocadoEdition/ajax/inventory_popup.php | 111 + AvocadoEdition/ajax/load_board_call.php | 60 + AvocadoEdition/ajax/load_memo_call.php | 59 + AvocadoEdition/ajax/memo_call.MP3 | Bin 0 -> 107206 bytes AvocadoEdition/ajax/memo_call.php | 40 + AvocadoEdition/bbs/_common.php | 3 + AvocadoEdition/bbs/_head.php | 4 + AvocadoEdition/bbs/_head.sub.php | 4 + AvocadoEdition/bbs/_tail.php | 4 + AvocadoEdition/bbs/_tail.sub.php | 4 + AvocadoEdition/bbs/ajax.autosave.php | 20 + AvocadoEdition/bbs/ajax.autosavedel.php | 15 + AvocadoEdition/bbs/ajax.autosavelist.php | 21 + AvocadoEdition/bbs/ajax.autosaveload.php | 18 + AvocadoEdition/bbs/ajax.comment_token.php | 14 + AvocadoEdition/bbs/ajax.filter.php | 31 + AvocadoEdition/bbs/ajax.mb_email.php | 16 + AvocadoEdition/bbs/ajax.mb_hp.php | 10 + AvocadoEdition/bbs/ajax.mb_id.php | 16 + AvocadoEdition/bbs/ajax.mb_nick.php | 17 + AvocadoEdition/bbs/ajax.mb_recommend.php | 13 + AvocadoEdition/bbs/alert.php | 113 + AvocadoEdition/bbs/alert_close.php | 61 + AvocadoEdition/bbs/board.php | 247 + AvocadoEdition/bbs/board_head.php | 6 + AvocadoEdition/bbs/board_list_update.php | 21 + AvocadoEdition/bbs/board_tail.php | 6 + AvocadoEdition/bbs/character_list.php | 317 + AvocadoEdition/bbs/confirm.php | 44 + AvocadoEdition/bbs/content.php | 94 + AvocadoEdition/bbs/current_connect.php | 38 + AvocadoEdition/bbs/db_table.optimize.php | 69 + AvocadoEdition/bbs/delete.php | 139 + AvocadoEdition/bbs/delete_all.php | 160 + AvocadoEdition/bbs/delete_comment.php | 88 + AvocadoEdition/bbs/download.php | 122 + AvocadoEdition/bbs/email_certify.php | 30 + AvocadoEdition/bbs/email_stop.php | 19 + AvocadoEdition/bbs/faq.php | 98 + AvocadoEdition/bbs/formmail.php | 54 + AvocadoEdition/bbs/formmail_send.php | 60 + AvocadoEdition/bbs/good.php | 155 + AvocadoEdition/bbs/group.php | 58 + AvocadoEdition/bbs/index.php | 39 + AvocadoEdition/bbs/link.php | 27 + AvocadoEdition/bbs/list.mmb.php | 249 + AvocadoEdition/bbs/list.php | 245 + AvocadoEdition/bbs/login.php | 31 + AvocadoEdition/bbs/login_check.php | 98 + AvocadoEdition/bbs/logout.php | 27 + AvocadoEdition/bbs/member_confirm.php | 27 + AvocadoEdition/bbs/member_leave.php | 25 + AvocadoEdition/bbs/memo.php | 74 + AvocadoEdition/bbs/memo_delete.php | 27 + AvocadoEdition/bbs/memo_form.php | 42 + AvocadoEdition/bbs/memo_form_update.php | 81 + AvocadoEdition/bbs/memo_view.php | 71 + AvocadoEdition/bbs/move.php | 161 + AvocadoEdition/bbs/move_update.php | 218 + AvocadoEdition/bbs/new.php | 116 + AvocadoEdition/bbs/new_delete.php | 147 + AvocadoEdition/bbs/newwin.inc.php | 53 + AvocadoEdition/bbs/password.php | 64 + AvocadoEdition/bbs/password_check.php | 35 + AvocadoEdition/bbs/password_lost.php | 16 + AvocadoEdition/bbs/password_lost2.php | 75 + AvocadoEdition/bbs/password_lost_certify.php | 27 + AvocadoEdition/bbs/point.php | 27 + AvocadoEdition/bbs/poll.php | 11 + AvocadoEdition/bbs/poll_etc_update.php | 59 + AvocadoEdition/bbs/poll_etc_update_mail.php | 30 + AvocadoEdition/bbs/poll_result.php | 115 + AvocadoEdition/bbs/poll_update.php | 61 + AvocadoEdition/bbs/profile.php | 33 + AvocadoEdition/bbs/qadelete.php | 76 + AvocadoEdition/bbs/qadownload.php | 70 + AvocadoEdition/bbs/qahead.php | 13 + AvocadoEdition/bbs/qalist.php | 122 + AvocadoEdition/bbs/qatail.php | 15 + AvocadoEdition/bbs/qaview.php | 175 + AvocadoEdition/bbs/qawrite.php | 138 + AvocadoEdition/bbs/qawrite_update.php | 451 + AvocadoEdition/bbs/register.php | 24 + AvocadoEdition/bbs/register_email.php | 58 + AvocadoEdition/bbs/register_email_update.php | 51 + AvocadoEdition/bbs/register_form.php | 143 + AvocadoEdition/bbs/register_form_update.php | 463 + .../bbs/register_form_update_mail1.php | 39 + .../bbs/register_form_update_mail2.php | 35 + .../bbs/register_form_update_mail3.php | 39 + AvocadoEdition/bbs/register_result.php | 15 + AvocadoEdition/bbs/rss.php | 90 + AvocadoEdition/bbs/scrap.php | 60 + AvocadoEdition/bbs/scrap_delete.php | 11 + AvocadoEdition/bbs/scrap_popin.php | 60 + AvocadoEdition/bbs/scrap_popin_update.php | 110 + AvocadoEdition/bbs/search.php | 236 + AvocadoEdition/bbs/sns_send.php | 23 + AvocadoEdition/bbs/view.php | 142 + AvocadoEdition/bbs/view_comment.php | 127 + AvocadoEdition/bbs/view_image.php | 110 + AvocadoEdition/bbs/visit_browscap.inc.php | 21 + AvocadoEdition/bbs/visit_insert.inc.php | 69 + AvocadoEdition/bbs/write.php | 428 + AvocadoEdition/bbs/write_comment_update.php | 350 + .../bbs/write_comment_update.sns.php | 72 + AvocadoEdition/bbs/write_token.php | 13 + AvocadoEdition/bbs/write_update.php | 729 + AvocadoEdition/bbs/write_update_file.php | 724 + AvocadoEdition/bbs/write_update_mail.php | 30 + AvocadoEdition/bgm.php | 14 + AvocadoEdition/common.php | 713 + AvocadoEdition/config.php | 224 + AvocadoEdition/couple/_common.php | 3 + AvocadoEdition/couple/_head.php | 4 + AvocadoEdition/couple/_head.sub.php | 4 + AvocadoEdition/couple/_tail.php | 4 + AvocadoEdition/couple/_tail.sub.php | 4 + AvocadoEdition/couple/index.php | 55 + AvocadoEdition/couple/skin/list.skin.php | 31 + AvocadoEdition/css/closet.css | 48 + AvocadoEdition/css/couple.css | 13 + AvocadoEdition/css/default.css | 146 + AvocadoEdition/css/emoticon.css | 45 + AvocadoEdition/css/enter.css | 29 + AvocadoEdition/css/exp.css | 14 + .../css/fonts/MetalMania-Regular.eot | Bin 0 -> 98056 bytes .../css/fonts/MetalMania-Regular.ttf | Bin 0 -> 254568 bytes .../css/fonts/MetalMania-Regular.woff | Bin 0 -> 122728 bytes AvocadoEdition/css/fonts/icomoon.eot | Bin 0 -> 95804 bytes AvocadoEdition/css/fonts/icomoon.svg | 501 + AvocadoEdition/css/fonts/icomoon.ttf | Bin 0 -> 95640 bytes AvocadoEdition/css/fonts/icomoon.woff | Bin 0 -> 95716 bytes AvocadoEdition/css/images/ajax-loader.gif | Bin 0 -> 7825 bytes AvocadoEdition/css/images/icons-18-black.png | Bin 0 -> 58254 bytes AvocadoEdition/css/images/icons-18-white.png | Bin 0 -> 58717 bytes AvocadoEdition/css/images/icons-36-black.png | Bin 0 -> 66332 bytes AvocadoEdition/css/images/icons-36-white.png | Bin 0 -> 66763 bytes AvocadoEdition/css/index.css | 31 + AvocadoEdition/css/intro.css | 22 + AvocadoEdition/css/login.css | 25 + AvocadoEdition/css/main.css | 69 + AvocadoEdition/css/member.css | 120 + AvocadoEdition/css/mypage.css | 256 + AvocadoEdition/css/shop.css | 64 + AvocadoEdition/css/style.css | 436 + AvocadoEdition/css/swiper.css | 531 + AvocadoEdition/enter.php | 73 + AvocadoEdition/extend/_sample.config.php | 34 + AvocadoEdition/extend/banner.lib.php | 63 + AvocadoEdition/extend/character.lib.php | 117 + AvocadoEdition/extend/community.config.php | 295 + AvocadoEdition/extend/exp.lib.php | 68 + AvocadoEdition/extend/item.lib.php | 96 + AvocadoEdition/extend/menu.lib.php | 91 + AvocadoEdition/extend/mmb.lib.php | 158 + AvocadoEdition/extend/rank.lib.php | 66 + AvocadoEdition/extend/sideclass.lib.php | 52 + .../extend/smarteditor_upload_extend.php | 11 + AvocadoEdition/extend/status.lib.php | 113 + AvocadoEdition/extend/title.lib.php | 27 + AvocadoEdition/extend/user.config.php | 4 + AvocadoEdition/extend/version.extend.php | 6 + AvocadoEdition/head.php | 103 + AvocadoEdition/head.sub.php | 133 + AvocadoEdition/img/btn_search.jpg | Bin 0 -> 782 bytes AvocadoEdition/img/btn_top.png | Bin 0 -> 1998 bytes AvocadoEdition/img/captcha.png | Bin 0 -> 19945 bytes AvocadoEdition/img/ico_memo.png | Bin 0 -> 1175 bytes .../img/ico_menu_control_pannel.png | Bin 0 -> 981 bytes AvocadoEdition/img/shop/npc.png | Bin 0 -> 4767 bytes AvocadoEdition/img/temp_main_image.png | Bin 0 -> 3525 bytes AvocadoEdition/img/ts01.gif | Bin 0 -> 138 bytes AvocadoEdition/img/ts02.gif | Bin 0 -> 148 bytes AvocadoEdition/img/ts03.gif | Bin 0 -> 154 bytes AvocadoEdition/img/wrest.gif | Bin 0 -> 51 bytes AvocadoEdition/index.php | 55 + AvocadoEdition/install/AVOCADO.LICENSE.txt | 19 + AvocadoEdition/install/LICENSE.txt | 242 + AvocadoEdition/install/gnuboard5.sql | 1386 + AvocadoEdition/install/img/mooning.png | Bin 0 -> 63654 bytes AvocadoEdition/install/img/pat01.png | Bin 0 -> 32481 bytes AvocadoEdition/install/img/ricepaper_v3.png | Bin 0 -> 33222 bytes AvocadoEdition/install/index.php | 60 + AvocadoEdition/install/install.css | 39 + AvocadoEdition/install/install.inc.php | 96 + AvocadoEdition/install/install.inc2.php | 7 + AvocadoEdition/install/install_config.php | 162 + AvocadoEdition/install/install_db.php | 459 + AvocadoEdition/install/library.check.php | 9 + AvocadoEdition/intro.php | 45 + AvocadoEdition/inventory/_common.php | 3 + AvocadoEdition/inventory/_head.php | 4 + AvocadoEdition/inventory/_head.sub.php | 4 + AvocadoEdition/inventory/_tail.php | 4 + AvocadoEdition/inventory/_tail.sub.php | 4 + AvocadoEdition/inventory/detail_item.php | 19 + .../inventory/extend/_sample.config.php | 29 + .../inventory/inc/add_item_form.php | 38 + .../inventory/inc/send_item_form.php | 36 + AvocadoEdition/inventory/inventory_update.php | 54 + AvocadoEdition/inventory/item_form_update.php | 67 + AvocadoEdition/inventory/list.inc.php | 31 + AvocadoEdition/inventory/sell_item.php | 18 + AvocadoEdition/inventory/send_item.php | 15 + AvocadoEdition/inventory/skin/item.skin.php | 47 + AvocadoEdition/inventory/skin/list.skin.php | 30 + AvocadoEdition/inventory/use_item.php | 65 + AvocadoEdition/js/_custom.js | 115 + AvocadoEdition/js/autosave.js | 117 + AvocadoEdition/js/certify.js | 80 + AvocadoEdition/js/common.js | 803 + AvocadoEdition/js/html5.js | 3 + AvocadoEdition/js/jquery-1.12.3.min.js | 5 + AvocadoEdition/js/jquery-1.8.3.min.js | 2 + AvocadoEdition/js/jquery.cookie.js | 114 + AvocadoEdition/js/jquery.fancylist.js | 65 + AvocadoEdition/js/jquery.menu.js | 109 + AvocadoEdition/js/jquery.register_form.js | 92 + AvocadoEdition/js/jquery.rwdImageMaps.js | 67 + AvocadoEdition/js/jquery.sms_paging.js | 93 + AvocadoEdition/js/kakaolink.js | 10 + AvocadoEdition/js/md5.js | 165 + AvocadoEdition/js/modernizr.custom.70111.js | 4 + AvocadoEdition/js/swiper.js | 8317 ++++++ AvocadoEdition/js/viewimageresize.js | 96 + AvocadoEdition/js/wrest.js | 371 + AvocadoEdition/lib/Excel/oleread.inc.php | 271 + .../class.writeexcel_biffwriter.inc.php | 209 + .../class.writeexcel_format.inc.php | 695 + .../class.writeexcel_formula.inc.php | 1610 ++ .../class.writeexcel_olewriter.inc.php | 353 + .../class.writeexcel_workbook.inc.php | 1149 + .../class.writeexcel_workbookbig.inc.php | 55 + .../class.writeexcel_worksheet.inc.php | 2968 ++ AvocadoEdition/lib/Excel/reader.php | 1084 + AvocadoEdition/lib/common.lib.php | 3318 +++ AvocadoEdition/lib/connect.lib.php | 23 + AvocadoEdition/lib/editor.lib.php | 27 + AvocadoEdition/lib/icode.lms.lib.php | 249 + AvocadoEdition/lib/icode.sms.lib.php | 146 + AvocadoEdition/lib/json.lib.php | 79 + AvocadoEdition/lib/latest.lib.php | 64 + AvocadoEdition/lib/mailer.lib.php | 55 + AvocadoEdition/lib/naver_syndi.lib.php | 54 + AvocadoEdition/lib/outlogin.lib.php | 45 + AvocadoEdition/lib/pbkdf2.compat.php | 221 + AvocadoEdition/lib/poll.lib.php | 30 + AvocadoEdition/lib/popular.lib.php | 33 + AvocadoEdition/lib/register.lib.php | 185 + AvocadoEdition/lib/thumbnail.lib.php | 645 + AvocadoEdition/lib/visit.lib.php | 82 + AvocadoEdition/main.php | 63 + AvocadoEdition/member/_common.php | 3 + AvocadoEdition/member/_head.php | 4 + AvocadoEdition/member/_head.sub.php | 4 + AvocadoEdition/member/_tail.php | 4 + AvocadoEdition/member/_tail.sub.php | 4 + AvocadoEdition/member/closet.php | 64 + AvocadoEdition/member/exp.php | 99 + AvocadoEdition/member/index.php | 39 + AvocadoEdition/member/ready.php | 155 + AvocadoEdition/member/skin/list.skin.php | 52 + .../member/skin/ready_list.skin.php | 94 + AvocadoEdition/member/skin/viewer.skin.php | 269 + AvocadoEdition/member/viewer.php | 91 + AvocadoEdition/mypage/_common.php | 4 + AvocadoEdition/mypage/_head.php | 25 + AvocadoEdition/mypage/_head.sub.php | 4 + AvocadoEdition/mypage/_tail.php | 10 + AvocadoEdition/mypage/_tail.sub.php | 4 + AvocadoEdition/mypage/character/_common.php | 4 + AvocadoEdition/mypage/character/_head.php | 8 + AvocadoEdition/mypage/character/_head.sub.php | 4 + AvocadoEdition/mypage/character/_tail.php | 4 + AvocadoEdition/mypage/character/_tail.sub.php | 4 + .../mypage/character/character_delete.php | 34 + .../mypage/character/character_form.php | 382 + .../character/character_form_update.php | 273 + .../mypage/character/cloest.inc.php | 73 + .../mypage/character/cloest_path_update.php | 33 + .../mypage/character/closet_update.php | 79 + AvocadoEdition/mypage/character/index.php | 88 + .../mypage/character/maincharacter_update.php | 11 + .../mypage/character/relation_delete.php | 22 + .../mypage/character/relation_list.php | 206 + .../mypage/character/relation_update.php | 39 + .../mypage/character/status.inc.php | 257 + .../mypage/character/status_update.php | 42 + AvocadoEdition/mypage/character/title.inc.php | 44 + .../mypage/character/title_update.php | 8 + AvocadoEdition/mypage/character/viewer.php | 218 + AvocadoEdition/mypage/index.php | 134 + AvocadoEdition/mypage/log/_common.php | 4 + AvocadoEdition/mypage/log/_head.php | 8 + AvocadoEdition/mypage/log/_head.sub.php | 4 + AvocadoEdition/mypage/log/_tail.php | 4 + AvocadoEdition/mypage/log/_tail.sub.php | 4 + AvocadoEdition/mypage/log/index.php | 180 + AvocadoEdition/mypage/log/log_favorite.php | 143 + AvocadoEdition/mypage/memo/_common.php | 4 + AvocadoEdition/mypage/memo/_head.php | 4 + AvocadoEdition/mypage/memo/_head.sub.php | 4 + AvocadoEdition/mypage/memo/_tail.php | 4 + AvocadoEdition/mypage/memo/_tail.sub.php | 4 + AvocadoEdition/mypage/memo/ajax/_common.php | 4 + .../mypage/memo/ajax/ajax_latest_talk.php | 51 + .../mypage/memo/ajax/ajax_prev_talk.php | 49 + AvocadoEdition/mypage/memo/index.php | 87 + AvocadoEdition/mypage/memo/memo_delete.php | 27 + AvocadoEdition/mypage/memo/memo_form.php | 66 + AvocadoEdition/mypage/memo/memo_update.php | 18 + AvocadoEdition/mypage/memo/memo_view.php | 168 + AvocadoEdition/mypage/memo/memo_view.skin.php | 33 + AvocadoEdition/mypage/money/_common.php | 4 + AvocadoEdition/mypage/money/_head.php | 10 + AvocadoEdition/mypage/money/_head.sub.php | 4 + AvocadoEdition/mypage/money/_tail.php | 4 + AvocadoEdition/mypage/money/_tail.sub.php | 4 + AvocadoEdition/mypage/money/index.php | 127 + AvocadoEdition/mypage/money/money_update.php | 36 + AvocadoEdition/perms.sh | 17 + AvocadoEdition/plugin/PHPMailer/LICENSE | 504 + .../plugin/PHPMailer/PHPMailerAutoload.php | 49 + AvocadoEdition/plugin/PHPMailer/README.md | 184 + AvocadoEdition/plugin/PHPMailer/VERSION | 1 + AvocadoEdition/plugin/PHPMailer/changelog.md | 620 + .../plugin/PHPMailer/class.phpmailer.php | 4039 +++ .../plugin/PHPMailer/class.phpmaileroauth.php | 197 + .../PHPMailer/class.phpmaileroauthgoogle.php | 77 + .../plugin/PHPMailer/class.pop3.php | 407 + .../plugin/PHPMailer/class.smtp.php | 1249 + AvocadoEdition/plugin/PHPMailer/composer.json | 44 + AvocadoEdition/plugin/PHPMailer/composer.lock | 3576 +++ .../docs/Callback_function_notes.txt | 17 + .../PHPMailer/docs/DomainKeys_notes.txt | 55 + .../docs/Note_for_SMTP_debugging.txt | 17 + .../plugin/PHPMailer/docs/extending.html | 128 + AvocadoEdition/plugin/PHPMailer/docs/faq.html | 28 + .../plugin/PHPMailer/docs/pop3_article.txt | 50 + .../plugin/PHPMailer/examples/DKIM.phps | 38 + .../PHPMailer/examples/code_generator.phps | 597 + .../PHPMailer/examples/contactform.phps | 71 + .../plugin/PHPMailer/examples/contents.html | 17 + .../PHPMailer/examples/contentsutf8.html | 21 + .../plugin/PHPMailer/examples/exceptions.phps | 35 + .../plugin/PHPMailer/examples/gmail.phps | 75 + .../PHPMailer/examples/gmail_xoauth.phps | 85 + .../PHPMailer/examples/images/phpmailer.png | Bin 0 -> 5831 bytes .../examples/images/phpmailer_mini.png | Bin 0 -> 1842 bytes .../plugin/PHPMailer/examples/index.html | 48 + .../plugin/PHPMailer/examples/mail.phps | 31 + .../PHPMailer/examples/mailing_list.phps | 59 + .../PHPMailer/examples/pop_before_smtp.phps | 54 + .../PHPMailer/examples/scripts/XRegExp.js | 664 + .../examples/scripts/shAutoloader.js | 122 + .../PHPMailer/examples/scripts/shBrushPhp.js | 72 + .../PHPMailer/examples/scripts/shCore.js | 1 + .../PHPMailer/examples/scripts/shLegacy.js | 140 + .../PHPMailer/examples/send_file_upload.phps | 49 + .../examples/send_multiple_file_upload.phps | 51 + .../plugin/PHPMailer/examples/sendmail.phps | 33 + .../PHPMailer/examples/signed-mail.phps | 89 + .../plugin/PHPMailer/examples/smtp.phps | 54 + .../plugin/PHPMailer/examples/smtp_check.phps | 55 + .../PHPMailer/examples/smtp_no_auth.phps | 50 + .../PHPMailer/examples/ssl_options.phps | 74 + .../PHPMailer/examples/styles/shCore.css | 46 + .../examples/styles/shCoreDefault.css | 77 + .../examples/styles/shCoreDjango.css | 78 + .../examples/styles/shCoreEclipse.css | 80 + .../PHPMailer/examples/styles/shCoreEmacs.css | 76 + .../examples/styles/shCoreFadeToGrey.css | 77 + .../examples/styles/shCoreMDUltra.css | 76 + .../examples/styles/shCoreMidnight.css | 76 + .../PHPMailer/examples/styles/shCoreRDark.css | 76 + .../examples/styles/shThemeAppleScript.css | 21 + .../examples/styles/shThemeDefault.css | 31 + .../examples/styles/shThemeDjango.css | 32 + .../examples/styles/shThemeEclipse.css | 34 + .../examples/styles/shThemeEmacs.css | 30 + .../examples/styles/shThemeFadeToGrey.css | 31 + .../examples/styles/shThemeMDUltra.css | 30 + .../examples/styles/shThemeMidnight.css | 30 + .../examples/styles/shThemeRDark.css | 30 + .../examples/styles/shThemeVisualStudio.css | 31 + .../PHPMailer/examples/styles/wrapping.png | Bin 0 -> 631 bytes .../plugin/PHPMailer/extras/EasyPeasyICS.php | 148 + .../plugin/PHPMailer/extras/README.md | 17 + .../plugin/PHPMailer/extras/htmlfilter.php | 1159 + .../PHPMailer/extras/ntlm_sasl_client.php | 185 + .../plugin/PHPMailer/get_oauth_token.php | 162 + .../PHPMailer/language/phpmailer.lang-am.php | 26 + .../PHPMailer/language/phpmailer.lang-ar.php | 27 + .../PHPMailer/language/phpmailer.lang-az.php | 26 + .../PHPMailer/language/phpmailer.lang-be.php | 26 + .../PHPMailer/language/phpmailer.lang-bg.php | 26 + .../PHPMailer/language/phpmailer.lang-br.php | 28 + .../PHPMailer/language/phpmailer.lang-ca.php | 26 + .../PHPMailer/language/phpmailer.lang-ch.php | 26 + .../PHPMailer/language/phpmailer.lang-cs.php | 25 + .../PHPMailer/language/phpmailer.lang-cz.php | 25 + .../PHPMailer/language/phpmailer.lang-da.php | 26 + .../PHPMailer/language/phpmailer.lang-de.php | 25 + .../PHPMailer/language/phpmailer.lang-dk.php | 26 + .../PHPMailer/language/phpmailer.lang-el.php | 25 + .../PHPMailer/language/phpmailer.lang-eo.php | 25 + .../PHPMailer/language/phpmailer.lang-es.php | 26 + .../PHPMailer/language/phpmailer.lang-et.php | 27 + .../PHPMailer/language/phpmailer.lang-fa.php | 27 + .../PHPMailer/language/phpmailer.lang-fi.php | 27 + .../PHPMailer/language/phpmailer.lang-fo.php | 26 + .../PHPMailer/language/phpmailer.lang-fr.php | 29 + .../PHPMailer/language/phpmailer.lang-gl.php | 26 + .../PHPMailer/language/phpmailer.lang-he.php | 26 + .../PHPMailer/language/phpmailer.lang-hr.php | 26 + .../PHPMailer/language/phpmailer.lang-hu.php | 26 + .../PHPMailer/language/phpmailer.lang-id.php | 26 + .../PHPMailer/language/phpmailer.lang-it.php | 27 + .../PHPMailer/language/phpmailer.lang-ja.php | 27 + .../PHPMailer/language/phpmailer.lang-ka.php | 26 + .../PHPMailer/language/phpmailer.lang-ko.php | 26 + .../PHPMailer/language/phpmailer.lang-lt.php | 26 + .../PHPMailer/language/phpmailer.lang-lv.php | 26 + .../PHPMailer/language/phpmailer.lang-ms.php | 26 + .../PHPMailer/language/phpmailer.lang-nb.php | 25 + .../PHPMailer/language/phpmailer.lang-nl.php | 26 + .../PHPMailer/language/phpmailer.lang-no.php | 25 + .../PHPMailer/language/phpmailer.lang-pl.php | 26 + .../PHPMailer/language/phpmailer.lang-pt.php | 26 + .../language/phpmailer.lang-pt_br.php | 28 + .../PHPMailer/language/phpmailer.lang-ro.php | 26 + .../PHPMailer/language/phpmailer.lang-ru.php | 27 + .../PHPMailer/language/phpmailer.lang-se.php | 26 + .../PHPMailer/language/phpmailer.lang-sk.php | 26 + .../PHPMailer/language/phpmailer.lang-sl.php | 26 + .../PHPMailer/language/phpmailer.lang-sr.php | 26 + .../PHPMailer/language/phpmailer.lang-sv.php | 26 + .../PHPMailer/language/phpmailer.lang-tr.php | 29 + .../PHPMailer/language/phpmailer.lang-uk.php | 27 + .../PHPMailer/language/phpmailer.lang-vi.php | 26 + .../PHPMailer/language/phpmailer.lang-zh.php | 28 + .../language/phpmailer.lang-zh_cn.php | 27 + AvocadoEdition/plugin/browscap/Browscap.php | 1459 + .../editor/cheditor5/backup_template.xml | 380 + .../plugin/editor/cheditor5/cheditor.js | 7963 ++++++ .../editor/cheditor5/css/SourceCodePro.eot | Bin 0 -> 83743 bytes .../editor/cheditor5/css/SourceCodePro.woff | Bin 0 -> 89024 bytes .../plugin/editor/cheditor5/css/dialog.css | 185 + .../plugin/editor/cheditor5/css/editarea.css | 23 + .../editor/cheditor5/css/imageupload.css | 136 + .../plugin/editor/cheditor5/css/imageurl.css | 5 + .../plugin/editor/cheditor5/css/lightbox.css | 95 + .../plugin/editor/cheditor5/css/ui.css | 653 + .../plugin/editor/cheditor5/editor.lib.php | 158 + .../editor/cheditor5/icons/add_col_after.png | Bin 0 -> 187 bytes .../editor/cheditor5/icons/add_col_before.png | Bin 0 -> 190 bytes .../editor/cheditor5/icons/add_cols_after.png | Bin 0 -> 180 bytes .../cheditor5/icons/add_cols_before.png | Bin 0 -> 181 bytes .../editor/cheditor5/icons/add_row_after.png | Bin 0 -> 187 bytes .../editor/cheditor5/icons/add_row_before.png | Bin 0 -> 188 bytes .../editor/cheditor5/icons/add_rows_after.png | Bin 0 -> 187 bytes .../cheditor5/icons/add_rows_before.png | Bin 0 -> 187 bytes .../editor/cheditor5/icons/button/cancel.gif | Bin 0 -> 2265 bytes .../cheditor5/icons/button/color_picker.gif | Bin 0 -> 1436 bytes .../cheditor5/icons/button/color_picker.png | Bin 0 -> 1716 bytes .../icons/button/color_picker_disable.png | Bin 0 -> 1783 bytes .../editor/cheditor5/icons/button/delete.gif | Bin 0 -> 2294 bytes .../cheditor5/icons/button/delete_cross.gif | Bin 0 -> 2186 bytes .../cheditor5/icons/button/edit_cell.gif | Bin 0 -> 2572 bytes .../cheditor5/icons/button/edit_image.gif | Bin 0 -> 2572 bytes .../editor/cheditor5/icons/button/input.gif | Bin 0 -> 2274 bytes .../cheditor5/icons/button/input_color.gif | Bin 0 -> 1923 bytes .../cheditor5/icons/button/map_address.gif | Bin 0 -> 2293 bytes .../editor/cheditor5/icons/button/paste.gif | Bin 0 -> 2247 bytes .../editor/cheditor5/icons/button/play.gif | Bin 0 -> 2746 bytes .../editor/cheditor5/icons/button/preview.gif | Bin 0 -> 2136 bytes .../editor/cheditor5/icons/button/process.gif | Bin 0 -> 2265 bytes .../editor/cheditor5/icons/button/reset.gif | Bin 0 -> 2218 bytes .../editor/cheditor5/icons/button/submit.gif | Bin 0 -> 2249 bytes .../editor/cheditor5/icons/button/upload.gif | Bin 0 -> 2275 bytes .../plugin/editor/cheditor5/icons/checked.png | Bin 0 -> 1081 bytes .../editor/cheditor5/icons/color_picker.png | Bin 0 -> 811 bytes .../cheditor5/icons/color_picker_arrow.gif | Bin 0 -> 66 bytes .../cheditor5/icons/color_picker_cross.gif | Bin 0 -> 1922 bytes .../cheditor5/icons/color_picker_hs.png | Bin 0 -> 2684 bytes .../cheditor5/icons/color_picker_hv.png | Bin 0 -> 2865 bytes .../cheditor5/icons/color_picker_reset.png | Bin 0 -> 1768 bytes .../cheditor5/icons/color_picker_tick.png | Bin 0 -> 1096 bytes .../editor/cheditor5/icons/delete_element.png | Bin 0 -> 543 bytes .../editor/cheditor5/icons/delete_table.png | Bin 0 -> 1605 bytes .../plugin/editor/cheditor5/icons/dot.gif | Bin 0 -> 43 bytes .../cheditor5/icons/edit_mode_code_a.png | Bin 0 -> 1012 bytes .../cheditor5/icons/edit_mode_code_b.png | Bin 0 -> 1014 bytes .../cheditor5/icons/edit_mode_rich_a.png | Bin 0 -> 393 bytes .../cheditor5/icons/edit_mode_rich_b.png | Bin 0 -> 386 bytes .../cheditor5/icons/edit_mode_view_a.png | Bin 0 -> 538 bytes .../cheditor5/icons/edit_mode_view_b.png | Bin 0 -> 528 bytes .../plugin/editor/cheditor5/icons/em/1.gif | Bin 0 -> 1478 bytes .../plugin/editor/cheditor5/icons/em/10.gif | Bin 0 -> 1408 bytes .../plugin/editor/cheditor5/icons/em/11.gif | Bin 0 -> 1425 bytes .../plugin/editor/cheditor5/icons/em/12.gif | Bin 0 -> 1459 bytes .../plugin/editor/cheditor5/icons/em/13.gif | Bin 0 -> 1363 bytes .../plugin/editor/cheditor5/icons/em/14.gif | Bin 0 -> 2298 bytes .../plugin/editor/cheditor5/icons/em/15.gif | Bin 0 -> 1214 bytes .../plugin/editor/cheditor5/icons/em/16.gif | Bin 0 -> 1215 bytes .../plugin/editor/cheditor5/icons/em/17.gif | Bin 0 -> 1241 bytes .../plugin/editor/cheditor5/icons/em/18.gif | Bin 0 -> 1198 bytes .../plugin/editor/cheditor5/icons/em/19.gif | Bin 0 -> 1359 bytes .../plugin/editor/cheditor5/icons/em/2.gif | Bin 0 -> 640 bytes .../plugin/editor/cheditor5/icons/em/20.gif | Bin 0 -> 1717 bytes .../plugin/editor/cheditor5/icons/em/21.gif | Bin 0 -> 1657 bytes .../plugin/editor/cheditor5/icons/em/22.gif | Bin 0 -> 2209 bytes .../plugin/editor/cheditor5/icons/em/23.gif | Bin 0 -> 2266 bytes .../plugin/editor/cheditor5/icons/em/24.gif | Bin 0 -> 2010 bytes .../plugin/editor/cheditor5/icons/em/25.gif | Bin 0 -> 2775 bytes .../plugin/editor/cheditor5/icons/em/26.gif | Bin 0 -> 1476 bytes .../plugin/editor/cheditor5/icons/em/27.gif | Bin 0 -> 2080 bytes .../plugin/editor/cheditor5/icons/em/28.gif | Bin 0 -> 1310 bytes .../plugin/editor/cheditor5/icons/em/29.gif | Bin 0 -> 859 bytes .../plugin/editor/cheditor5/icons/em/3.gif | Bin 0 -> 1939 bytes .../plugin/editor/cheditor5/icons/em/30.gif | Bin 0 -> 2319 bytes .../plugin/editor/cheditor5/icons/em/31.gif | Bin 0 -> 1197 bytes .../plugin/editor/cheditor5/icons/em/32.gif | Bin 0 -> 1674 bytes .../plugin/editor/cheditor5/icons/em/33.gif | Bin 0 -> 1259 bytes .../plugin/editor/cheditor5/icons/em/34.gif | Bin 0 -> 1975 bytes .../plugin/editor/cheditor5/icons/em/35.gif | Bin 0 -> 1352 bytes .../plugin/editor/cheditor5/icons/em/36.gif | Bin 0 -> 3641 bytes .../plugin/editor/cheditor5/icons/em/37.gif | Bin 0 -> 2215 bytes .../plugin/editor/cheditor5/icons/em/38.gif | Bin 0 -> 1540 bytes .../plugin/editor/cheditor5/icons/em/39.gif | Bin 0 -> 2703 bytes .../plugin/editor/cheditor5/icons/em/4.gif | Bin 0 -> 2671 bytes .../plugin/editor/cheditor5/icons/em/40.gif | Bin 0 -> 1324 bytes .../plugin/editor/cheditor5/icons/em/41.gif | Bin 0 -> 1702 bytes .../plugin/editor/cheditor5/icons/em/42.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/43.gif | Bin 0 -> 1703 bytes .../plugin/editor/cheditor5/icons/em/44.gif | Bin 0 -> 1703 bytes .../plugin/editor/cheditor5/icons/em/45.gif | Bin 0 -> 2114 bytes .../plugin/editor/cheditor5/icons/em/46.gif | Bin 0 -> 1699 bytes .../plugin/editor/cheditor5/icons/em/47.gif | Bin 0 -> 1700 bytes .../plugin/editor/cheditor5/icons/em/48.gif | Bin 0 -> 1710 bytes .../plugin/editor/cheditor5/icons/em/49.gif | Bin 0 -> 1681 bytes .../plugin/editor/cheditor5/icons/em/5.gif | Bin 0 -> 1407 bytes .../plugin/editor/cheditor5/icons/em/50.gif | Bin 0 -> 1695 bytes .../plugin/editor/cheditor5/icons/em/51.gif | Bin 0 -> 2105 bytes .../plugin/editor/cheditor5/icons/em/52.gif | Bin 0 -> 1711 bytes .../plugin/editor/cheditor5/icons/em/53.gif | Bin 0 -> 1698 bytes .../plugin/editor/cheditor5/icons/em/54.gif | Bin 0 -> 1703 bytes .../plugin/editor/cheditor5/icons/em/55.gif | Bin 0 -> 1698 bytes .../plugin/editor/cheditor5/icons/em/56.gif | Bin 0 -> 1703 bytes .../plugin/editor/cheditor5/icons/em/57.gif | Bin 0 -> 1703 bytes .../plugin/editor/cheditor5/icons/em/58.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/59.gif | Bin 0 -> 1702 bytes .../plugin/editor/cheditor5/icons/em/6.gif | Bin 0 -> 2017 bytes .../plugin/editor/cheditor5/icons/em/60.gif | Bin 0 -> 2103 bytes .../plugin/editor/cheditor5/icons/em/61.gif | Bin 0 -> 2107 bytes .../plugin/editor/cheditor5/icons/em/62.gif | Bin 0 -> 1674 bytes .../plugin/editor/cheditor5/icons/em/63.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/64.gif | Bin 0 -> 2114 bytes .../plugin/editor/cheditor5/icons/em/65.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/66.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/67.gif | Bin 0 -> 1701 bytes .../plugin/editor/cheditor5/icons/em/68.gif | Bin 0 -> 1694 bytes .../plugin/editor/cheditor5/icons/em/69.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/7.gif | Bin 0 -> 2106 bytes .../plugin/editor/cheditor5/icons/em/70.gif | Bin 0 -> 1704 bytes .../plugin/editor/cheditor5/icons/em/71.gif | Bin 0 -> 1622 bytes .../plugin/editor/cheditor5/icons/em/72.gif | Bin 0 -> 1656 bytes .../plugin/editor/cheditor5/icons/em/73.gif | Bin 0 -> 2054 bytes .../plugin/editor/cheditor5/icons/em/74.gif | Bin 0 -> 2105 bytes .../plugin/editor/cheditor5/icons/em/75.gif | Bin 0 -> 2075 bytes .../plugin/editor/cheditor5/icons/em/76.gif | Bin 0 -> 1664 bytes .../plugin/editor/cheditor5/icons/em/77.gif | Bin 0 -> 1653 bytes .../plugin/editor/cheditor5/icons/em/78.gif | Bin 0 -> 1662 bytes .../plugin/editor/cheditor5/icons/em/79.gif | Bin 0 -> 1672 bytes .../plugin/editor/cheditor5/icons/em/8.gif | Bin 0 -> 1199 bytes .../plugin/editor/cheditor5/icons/em/80.gif | Bin 0 -> 1390 bytes .../plugin/editor/cheditor5/icons/em/9.gif | Bin 0 -> 1866 bytes .../editor/cheditor5/icons/fullscreen.png | Bin 0 -> 1305 bytes .../cheditor5/icons/fullscreen_actual.png | Bin 0 -> 1278 bytes .../cheditor5/icons/imageUpload/add.gif | Bin 0 -> 3020 bytes .../icons/imageUpload/cross-small.png | Bin 0 -> 2938 bytes .../cheditor5/icons/imageUpload/delete.png | Bin 0 -> 1717 bytes .../cheditor5/icons/imageUpload/dot.gif | Bin 0 -> 43 bytes .../cheditor5/icons/imageUpload/loader.gif | Bin 0 -> 1849 bytes .../icons/imageUpload/marker_bottom.gif | Bin 0 -> 43 bytes .../icons/imageUpload/marker_middle.gif | Bin 0 -> 49 bytes .../icons/imageUpload/marker_top.gif | Bin 0 -> 43 bytes .../icons/imageUpload/mouse_drag_img.gif | Bin 0 -> 316 bytes .../icons/imageUpload/remove_all.gif | Bin 0 -> 2970 bytes .../cheditor5/icons/image_align_center.png | Bin 0 -> 402 bytes .../cheditor5/icons/image_align_left.png | Bin 0 -> 396 bytes .../cheditor5/icons/image_align_left_wt.png | Bin 0 -> 423 bytes .../cheditor5/icons/image_align_right.png | Bin 0 -> 397 bytes .../cheditor5/icons/image_align_right_wt.png | Bin 0 -> 454 bytes .../editor/cheditor5/icons/image_resize.png | Bin 0 -> 531 bytes .../cheditor5/icons/image_wrap_text.png | Bin 0 -> 423 bytes .../editor/cheditor5/icons/magnifier-zoom.png | Bin 0 -> 2247 bytes .../editor/cheditor5/icons/readonlymode.png | Bin 0 -> 1983 bytes .../editor/cheditor5/icons/remove_col.png | Bin 0 -> 182 bytes .../editor/cheditor5/icons/remove_cols.png | Bin 0 -> 176 bytes .../editor/cheditor5/icons/remove_row.png | Bin 0 -> 185 bytes .../editor/cheditor5/icons/remove_rows.png | Bin 0 -> 181 bytes .../editor/cheditor5/icons/splitter.gif | Bin 0 -> 177 bytes .../cheditor5/icons/statusbar_bgline.gif | Bin 0 -> 45 bytes .../cheditor5/icons/table_delete_cell.png | Bin 0 -> 1536 bytes .../cheditor5/icons/table_delete_column.png | Bin 0 -> 1532 bytes .../cheditor5/icons/table_delete_row.png | Bin 0 -> 1562 bytes .../cheditor5/icons/table_insert_cell.png | Bin 0 -> 1526 bytes .../cheditor5/icons/table_insert_column.png | Bin 0 -> 1515 bytes .../cheditor5/icons/table_insert_row.png | Bin 0 -> 1530 bytes .../editor/cheditor5/icons/table_join.png | Bin 0 -> 1352 bytes .../cheditor5/icons/table_join_column.png | Bin 0 -> 1419 bytes .../editor/cheditor5/icons/table_join_row.png | Bin 0 -> 1466 bytes .../cheditor5/icons/table_split_column.png | Bin 0 -> 1322 bytes .../cheditor5/icons/table_split_row.png | Bin 0 -> 1396 bytes .../editor/cheditor5/icons/title_bar_bg.gif | Bin 0 -> 172 bytes .../editor/cheditor5/icons/title_bar_bg2.gif | Bin 0 -> 545 bytes .../cheditor5/icons/toolbar-background.png | Bin 0 -> 21437 bytes .../cheditor5/icons/toolbar-wrapper-bg.png | Bin 0 -> 1731 bytes .../plugin/editor/cheditor5/icons/toolbar.png | Bin 0 -> 13656 bytes .../editor/cheditor5/icons/viewmode_code.png | Bin 0 -> 2053 bytes .../cheditor5/icons/viewmode_preview.png | Bin 0 -> 2236 bytes .../editor/cheditor5/icons/watermark.png | Bin 0 -> 13496 bytes .../editor/cheditor5/imageUpload/_common.php | 3 + .../editor/cheditor5/imageUpload/config.php | 71 + .../editor/cheditor5/imageUpload/delete.php | 49 + .../editor/cheditor5/imageUpload/upload.php | 128 + .../editor/cheditor5/popup/color_picker.html | 19 + .../plugin/editor/cheditor5/popup/flash.html | 22 + .../cheditor5/popup/flash/ImagePreview.swf | Bin 0 -> 147221 bytes .../editor/cheditor5/popup/flash/chximage.swf | Bin 0 -> 63095 bytes .../editor/cheditor5/popup/google_map.html | 23 + .../plugin/editor/cheditor5/popup/icon.html | 15 + .../plugin/editor/cheditor5/popup/image.html | 76 + .../editor/cheditor5/popup/image.html5.html | 82 + .../editor/cheditor5/popup/image_url.html | 34 + .../editor/cheditor5/popup/js/AC_OETags.js | 247 + .../editor/cheditor5/popup/js/color_picker.js | 92 + .../editor/cheditor5/popup/js/dialog.js | 41 + .../plugin/editor/cheditor5/popup/js/flash.js | 95 + .../editor/cheditor5/popup/js/google_map.js | 143 + .../plugin/editor/cheditor5/popup/js/icon.js | 54 + .../editor/cheditor5/popup/js/image.html5.js | 1348 + .../plugin/editor/cheditor5/popup/js/image.js | 890 + .../cheditor5/popup/js/image_upload_flash.js | 279 + .../editor/cheditor5/popup/js/image_url.js | 244 + .../plugin/editor/cheditor5/popup/js/link.js | 125 + .../plugin/editor/cheditor5/popup/js/media.js | 46 + .../editor/cheditor5/popup/js/swfobject.js | 779 + .../editor/cheditor5/popup/js/symbol.js | 167 + .../plugin/editor/cheditor5/popup/js/table.js | 315 + .../editor/cheditor5/popup/js/table_modify.js | 640 + .../plugin/editor/cheditor5/popup/link.html | 70 + .../plugin/editor/cheditor5/popup/media.html | 40 + .../plugin/editor/cheditor5/popup/symbol.html | 26 + .../plugin/editor/cheditor5/popup/table.html | 178 + .../editor/cheditor5/popup/table_modify.html | 180 + .../plugin/editor/cheditor5/template.xml | 368 + .../editor/cheditor5/utils/crossdomain.xml | 6 + .../editor/smarteditor2/SmartEditor2Skin.html | 786 + .../smarteditor2/SmartEditor2_noframe.html | 841 + .../editor/smarteditor2/autosave.editor.js | 13 + .../plugin/editor/smarteditor2/config.js | 29 + .../editor/smarteditor2/css/smart_editor2.css | 175 + .../smarteditor2/css/smart_editor2_in.css | 37 + .../smarteditor2/css/smart_editor2_items.css | 462 + .../smarteditor2/css/smart_editor2_out.css | 12 + .../plugin/editor/smarteditor2/editor.lib.php | 166 + .../plugin/editor/smarteditor2/img/bg_b1.png | Bin 0 -> 115 bytes .../editor/smarteditor2/img/bg_button.gif | Bin 0 -> 526 bytes .../smarteditor2/img/bg_button_left.gif | Bin 0 -> 331 bytes .../smarteditor2/img/bg_button_right.gif | Bin 0 -> 1240 bytes .../editor/smarteditor2/img/bg_find_h3.gif | Bin 0 -> 159 bytes .../editor/smarteditor2/img/bg_help.gif | Bin 0 -> 2360 bytes .../editor/smarteditor2/img/bg_icon_tool.gif | Bin 0 -> 103 bytes .../editor/smarteditor2/img/bg_line1.gif | Bin 0 -> 43 bytes .../editor/smarteditor2/img/bg_quote2.gif | Bin 0 -> 56 bytes .../plugin/editor/smarteditor2/img/bg_set.gif | Bin 0 -> 941 bytes .../editor/smarteditor2/img/bg_text_tool.gif | Bin 0 -> 1123 bytes .../editor/smarteditor2/img/bg_tool2.gif | Bin 0 -> 104 bytes .../smarteditor2/img/editor_guideline_698.gif | Bin 0 -> 139 bytes .../smarteditor2/img/editor_guideline_890.gif | Bin 0 -> 155 bytes .../editor/smarteditor2/img/ico_extend.png | Bin 0 -> 270 bytes .../editor/smarteditor2/img/icon_set.gif | Bin 0 -> 4611 bytes .../editor/smarteditor2/img/ko_KR/btn_set.png | Bin 0 -> 1469116 bytes .../smarteditor2/img/ko_KR/bx_set_110302.gif | Bin 0 -> 34462 bytes .../smarteditor2/img/ko_KR/text_tool_set.png | Bin 0 -> 11403 bytes .../img/photoQuickPopup/bg_drag_image.png | Bin 0 -> 1227 bytes .../img/photoQuickPopup/btn_cancel.png | Bin 0 -> 718 bytes .../img/photoQuickPopup/btn_confirm.png | Bin 0 -> 553 bytes .../img/photoQuickPopup/btn_confirm2.png | Bin 0 -> 553 bytes .../img/photoQuickPopup/btn_del.png | Bin 0 -> 157 bytes .../img/photoQuickPopup/btn_find.png | Bin 0 -> 506 bytes .../smarteditor2/img/text_tool_set2.png | Bin 0 -> 7271 bytes .../editor/smarteditor2/js/HuskyEZCreator.js | 134 + .../js/SE2B_Configuration_General.js | 52 + .../js/SE2B_Configuration_Service.js | 71 + .../editor/smarteditor2/js/SE2BasicCreator.js | 95 + .../smarteditor2/js/SE2M_Configuration.js | 149 + .../editor/smarteditor2/js/jindo.min.js | 1 + .../editor/smarteditor2/js/jindo_component.js | 1 + .../editor/smarteditor2/js/lib/jindo2.all.js | 1 + .../smarteditor2/js/lib/jindo_component.js | 1 + .../editor/smarteditor2/js/smarteditor2.js | 22874 ++++++++++++++++ .../smarteditor2/js/smarteditor2.min.js | 17 + .../plugin/editor/smarteditor2/license.txt | 16 + .../plugin/hp_SE2M_AttachQuickPhoto.js | 106 + .../photo_uploader/popup/_common.php | 3 + .../popup/css/jquery.fileupload-noscript.css | 22 + .../css/jquery.fileupload-ui-noscript.css | 17 + .../popup/css/jquery.fileupload-ui.css | 57 + .../popup/css/jquery.fileupload.css | 36 + .../photo_uploader/popup/css/style.css | 99 + .../photo_uploader/popup/img/delete.png | Bin 0 -> 850 bytes .../photo_uploader/popup/img/loading.gif | Bin 0 -> 1924 bytes .../photo_uploader/popup/img/progressbar.gif | Bin 0 -> 3323 bytes .../popup/img/system_delete.png | Bin 0 -> 426 bytes .../photo_uploader/popup/index.html | 64 + .../photo_uploader/popup/js/basic.js | 346 + .../popup/js/jquery-1.8.3.min.js | 2 + .../photo_uploader/popup/js/jquery-ui.min.js | 5 + .../popup/js/jquery.fileupload-process.js | 172 + .../popup/js/jquery.fileupload-ui.js | 699 + .../popup/js/jquery.fileupload.js | 1462 + .../popup/js/jquery.iframe-transport.js | 214 + .../popup/js/jquery.ui.widget.js | 530 + .../photo_uploader/popup/php/JSON.php | 933 + .../popup/php/UploadHandler.php | 1459 + .../photo_uploader/popup/php/_common.php | 3 + .../photo_uploader/popup/php/index.php | 58 + .../swfupload/XPButtonUploadText_61x22.png | Bin 0 -> 1855 bytes .../popup/swfupload/fileprogress.js | 203 + .../popup/swfupload/handlers.js | 378 + .../popup/swfupload/jquery.swfupload.js | 82 + .../popup/swfupload/swfupload.js | 1002 + .../popup/swfupload/swfupload.queue.js | 99 + .../popup/swfupload/swfupload.swf | Bin 0 -> 12787 bytes .../plugin/editor/smarteditor2/readme.txt | 40 + .../editor/smarteditor2/release_notes.txt | 255 + .../plugin/editor/smarteditor2/shortcut.html | 23 + .../smarteditor2/smart_editor2_inputarea.html | 8 + .../smart_editor2_inputarea_ie8.html | 9 + .../editor/smarteditor2/src_include.txt | 7 + .../htmlpurifier/HTMLPurifier.standalone.php | 22099 +++++++++++++++ .../plugin/htmlpurifier/safeiframe.txt | 12 + .../ConfigSchema/Builder/ConfigSchema.php | 48 + .../HTMLPurifier/ConfigSchema/Builder/Xml.php | 144 + .../HTMLPurifier/ConfigSchema/Exception.php | 11 + .../HTMLPurifier/ConfigSchema/Interchange.php | 47 + .../ConfigSchema/Interchange/Directive.php | 89 + .../ConfigSchema/Interchange/Id.php | 58 + .../ConfigSchema/InterchangeBuilder.php | 226 + .../HTMLPurifier/ConfigSchema/Validator.php | 248 + .../ConfigSchema/ValidatorAtom.php | 130 + .../HTMLPurifier/ConfigSchema/schema.ser | Bin 0 -> 15598 bytes .../schema/Attr.AllowedClasses.txt | 8 + .../schema/Attr.AllowedFrameTargets.txt | 12 + .../ConfigSchema/schema/Attr.AllowedRel.txt | 9 + .../ConfigSchema/schema/Attr.AllowedRev.txt | 9 + .../schema/Attr.ClassUseCDATA.txt | 19 + .../schema/Attr.DefaultImageAlt.txt | 11 + .../schema/Attr.DefaultInvalidImage.txt | 9 + .../schema/Attr.DefaultInvalidImageAlt.txt | 8 + .../schema/Attr.DefaultTextDir.txt | 10 + .../ConfigSchema/schema/Attr.EnableID.txt | 16 + .../schema/Attr.ForbiddenClasses.txt | 8 + .../ConfigSchema/schema/Attr.ID.HTML5.txt | 10 + .../ConfigSchema/schema/Attr.IDBlacklist.txt | 5 + .../schema/Attr.IDBlacklistRegexp.txt | 9 + .../ConfigSchema/schema/Attr.IDPrefix.txt | 12 + .../schema/Attr.IDPrefixLocal.txt | 14 + .../schema/AutoFormat.AutoParagraph.txt | 31 + .../ConfigSchema/schema/AutoFormat.Custom.txt | 12 + .../schema/AutoFormat.DisplayLinkURI.txt | 11 + .../schema/AutoFormat.Linkify.txt | 12 + .../AutoFormat.PurifierLinkify.DocURL.txt | 12 + .../schema/AutoFormat.PurifierLinkify.txt | 12 + .../AutoFormat.RemoveEmpty.Predicate.txt | 14 + ...rmat.RemoveEmpty.RemoveNbsp.Exceptions.txt | 11 + .../AutoFormat.RemoveEmpty.RemoveNbsp.txt | 15 + .../schema/AutoFormat.RemoveEmpty.txt | 46 + ...utoFormat.RemoveSpansWithoutAttributes.txt | 11 + .../schema/CSS.AllowDuplicates.txt | 11 + .../schema/CSS.AllowImportant.txt | 8 + .../ConfigSchema/schema/CSS.AllowTricky.txt | 11 + .../ConfigSchema/schema/CSS.AllowedFonts.txt | 12 + .../schema/CSS.AllowedProperties.txt | 18 + .../ConfigSchema/schema/CSS.DefinitionRev.txt | 11 + .../schema/CSS.ForbiddenProperties.txt | 13 + .../ConfigSchema/schema/CSS.MaxImgLength.txt | 16 + .../ConfigSchema/schema/CSS.Proprietary.txt | 10 + .../ConfigSchema/schema/CSS.Trusted.txt | 9 + .../schema/Cache.DefinitionImpl.txt | 14 + .../schema/Cache.SerializerPath.txt | 13 + .../schema/Cache.SerializerPermissions.txt | 16 + .../schema/Core.AggressivelyFixLt.txt | 18 + .../schema/Core.AllowHostnameUnderscore.txt | 16 + .../schema/Core.CollectErrors.txt | 12 + .../schema/Core.ColorKeywords.txt | 29 + .../schema/Core.ConvertDocumentToFragment.txt | 14 + .../Core.DirectLexLineNumberSyncInterval.txt | 17 + .../schema/Core.DisableExcludes.txt | 14 + .../ConfigSchema/schema/Core.EnableIDNA.txt | 9 + .../ConfigSchema/schema/Core.Encoding.txt | 15 + .../schema/Core.EscapeInvalidChildren.txt | 12 + .../schema/Core.EscapeInvalidTags.txt | 7 + .../schema/Core.EscapeNonASCIICharacters.txt | 13 + .../schema/Core.HiddenElements.txt | 19 + .../ConfigSchema/schema/Core.Language.txt | 10 + .../ConfigSchema/schema/Core.LexerImpl.txt | 34 + .../schema/Core.MaintainLineNumbers.txt | 16 + .../schema/Core.NormalizeNewlines.txt | 11 + .../schema/Core.RemoveInvalidImg.txt | 12 + .../Core.RemoveProcessingInstructions.txt | 11 + .../schema/Core.RemoveScriptContents.txt | 12 + .../ConfigSchema/schema/Filter.Custom.txt | 11 + .../Filter.ExtractStyleBlocks.Escaping.txt | 14 + .../Filter.ExtractStyleBlocks.Scope.txt | 29 + .../Filter.ExtractStyleBlocks.TidyImpl.txt | 16 + .../schema/Filter.ExtractStyleBlocks.txt | 74 + .../ConfigSchema/schema/Filter.YouTube.txt | 16 + .../ConfigSchema/schema/HTML.Allowed.txt | 25 + .../schema/HTML.AllowedAttributes.txt | 19 + .../schema/HTML.AllowedComments.txt | 10 + .../schema/HTML.AllowedCommentsRegexp.txt | 15 + .../schema/HTML.AllowedElements.txt | 23 + .../schema/HTML.AllowedModules.txt | 20 + .../schema/HTML.Attr.Name.UseCDATA.txt | 11 + .../ConfigSchema/schema/HTML.BlockWrapper.txt | 18 + .../ConfigSchema/schema/HTML.CoreModules.txt | 23 + .../schema/HTML.CustomDoctype.txt | 9 + .../ConfigSchema/schema/HTML.DefinitionID.txt | 33 + .../schema/HTML.DefinitionRev.txt | 16 + .../ConfigSchema/schema/HTML.Doctype.txt | 11 + .../schema/HTML.FlashAllowFullScreen.txt | 11 + .../schema/HTML.ForbiddenAttributes.txt | 21 + .../schema/HTML.ForbiddenElements.txt | 20 + .../ConfigSchema/schema/HTML.MaxImgLength.txt | 14 + .../ConfigSchema/schema/HTML.Nofollow.txt | 7 + .../ConfigSchema/schema/HTML.Parent.txt | 12 + .../ConfigSchema/schema/HTML.Proprietary.txt | 12 + .../ConfigSchema/schema/HTML.SafeEmbed.txt | 13 + .../ConfigSchema/schema/HTML.SafeIframe.txt | 13 + .../ConfigSchema/schema/HTML.SafeObject.txt | 13 + .../schema/HTML.SafeScripting.txt | 10 + .../ConfigSchema/schema/HTML.Strict.txt | 9 + .../ConfigSchema/schema/HTML.TargetBlank.txt | 8 + .../schema/HTML.TargetNoreferrer.txt | 9 + .../ConfigSchema/schema/HTML.TidyAdd.txt | 8 + .../ConfigSchema/schema/HTML.TidyLevel.txt | 24 + .../ConfigSchema/schema/HTML.TidyRemove.txt | 8 + .../ConfigSchema/schema/HTML.Trusted.txt | 9 + .../ConfigSchema/schema/HTML.XHTML.txt | 11 + .../schema/Output.CommentScriptContents.txt | 10 + .../schema/Output.FixInnerHTML.txt | 15 + .../schema/Output.FlashCompat.txt | 11 + .../ConfigSchema/schema/Output.Newline.txt | 13 + .../ConfigSchema/schema/Output.SortAttr.txt | 14 + .../ConfigSchema/schema/Output.TidyFormat.txt | 25 + .../ConfigSchema/schema/Test.ForceNoIconv.txt | 7 + .../schema/URI.AllowedSchemes.txt | 18 + .../ConfigSchema/schema/URI.Base.txt | 17 + .../ConfigSchema/schema/URI.DefaultScheme.txt | 10 + .../ConfigSchema/schema/URI.DefinitionID.txt | 11 + .../ConfigSchema/schema/URI.DefinitionRev.txt | 11 + .../ConfigSchema/schema/URI.Disable.txt | 14 + .../schema/URI.DisableExternal.txt | 11 + .../schema/URI.DisableExternalResources.txt | 13 + .../schema/URI.DisableResources.txt | 15 + .../ConfigSchema/schema/URI.Host.txt | 19 + .../ConfigSchema/schema/URI.HostBlacklist.txt | 9 + .../ConfigSchema/schema/URI.MakeAbsolute.txt | 13 + .../ConfigSchema/schema/URI.Munge.txt | 83 + .../schema/URI.MungeResources.txt | 17 + .../schema/URI.MungeSecretKey.txt | 30 + .../schema/URI.OverrideAllowedSchemes.txt | 9 + .../schema/URI.SafeIframeRegexp.txt | 22 + .../HTMLPurifier/ConfigSchema/schema/info.ini | 3 + .../HTMLPurifier/EntityLookup/entities.ser | 1 + .../Filter/ExtractStyleBlocks.php | 338 + .../HTMLPurifier/Filter/YouTube.php | 65 + .../Language/classes/en-x-test.php | 9 + .../Language/messages/en-x-test.php | 11 + .../Language/messages/en-x-testmini.php | 12 + .../HTMLPurifier/Language/messages/en.php | 55 + .../standalone/HTMLPurifier/Lexer/PH5P.php | 4787 ++++ .../standalone/HTMLPurifier/Printer.php | 218 + .../HTMLPurifier/Printer/CSSDefinition.php | 44 + .../HTMLPurifier/Printer/ConfigForm.css | 10 + .../HTMLPurifier/Printer/ConfigForm.js | 5 + .../HTMLPurifier/Printer/ConfigForm.php | 451 + .../HTMLPurifier/Printer/HTMLDefinition.php | 324 + AvocadoEdition/plugin/jqplot/MIT-LICENSE.txt | 21 + AvocadoEdition/plugin/jqplot/excanvas.js | 1438 + AvocadoEdition/plugin/jqplot/excanvas.min.js | 3 + .../plugin/jqplot/jqplot.barRenderer.min.js | 3 + .../jqplot/jqplot.categoryAxisRenderer.min.js | 3 + .../plugin/jqplot/jqplot.pointLabels.min.js | 3 + .../plugin/jqplot/jquery.jqplot.css | 261 + AvocadoEdition/plugin/jqplot/jquery.jqplot.js | 11411 ++++++++ .../plugin/jqplot/jquery.jqplot.min.css | 1 + .../plugin/jqplot/jquery.jqplot.min.js | 3 + .../plugins/jqplot.BezierCurveRenderer.js | 314 + .../plugins/jqplot.BezierCurveRenderer.min.js | 3 + .../jqplot/plugins/jqplot.barRenderer.js | 801 + .../jqplot/plugins/jqplot.barRenderer.min.js | 3 + .../jqplot/plugins/jqplot.blockRenderer.js | 235 + .../plugins/jqplot.blockRenderer.min.js | 3 + .../jqplot/plugins/jqplot.bubbleRenderer.js | 759 + .../plugins/jqplot.bubbleRenderer.min.js | 3 + .../plugins/jqplot.canvasAxisLabelRenderer.js | 203 + .../jqplot.canvasAxisLabelRenderer.min.js | 3 + .../plugins/jqplot.canvasAxisTickRenderer.js | 253 + .../jqplot.canvasAxisTickRenderer.min.js | 3 + .../jqplot/plugins/jqplot.canvasOverlay.js | 1021 + .../plugins/jqplot.canvasOverlay.min.js | 3 + .../plugins/jqplot.canvasTextRenderer.js | 449 + .../plugins/jqplot.canvasTextRenderer.min.js | 3 + .../plugins/jqplot.categoryAxisRenderer.js | 679 + .../jqplot.categoryAxisRenderer.min.js | 3 + .../plugin/jqplot/plugins/jqplot.ciParser.js | 116 + .../jqplot/plugins/jqplot.ciParser.min.js | 3 + .../plugin/jqplot/plugins/jqplot.cursor.js | 1108 + .../jqplot/plugins/jqplot.cursor.min.js | 3 + .../jqplot/plugins/jqplot.dateAxisRenderer.js | 741 + .../plugins/jqplot.dateAxisRenderer.min.js | 3 + .../jqplot/plugins/jqplot.donutRenderer.js | 805 + .../plugins/jqplot.donutRenderer.min.js | 3 + .../plugin/jqplot/plugins/jqplot.dragable.js | 225 + .../jqplot/plugins/jqplot.dragable.min.js | 3 + .../plugins/jqplot.enhancedLegendRenderer.js | 305 + .../jqplot.enhancedLegendRenderer.min.js | 3 + .../jqplot/plugins/jqplot.funnelRenderer.js | 943 + .../plugins/jqplot.funnelRenderer.min.js | 3 + .../jqplot/plugins/jqplot.highlighter.js | 465 + .../jqplot/plugins/jqplot.highlighter.min.js | 3 + .../plugin/jqplot/plugins/jqplot.json2.js | 475 + .../plugin/jqplot/plugins/jqplot.json2.min.js | 3 + .../jqplot/plugins/jqplot.logAxisRenderer.js | 534 + .../plugins/jqplot.logAxisRenderer.min.js | 3 + .../plugins/jqplot.mekkoAxisRenderer.js | 611 + .../plugins/jqplot.mekkoAxisRenderer.min.js | 3 + .../jqplot/plugins/jqplot.mekkoRenderer.js | 437 + .../plugins/jqplot.mekkoRenderer.min.js | 3 + .../plugins/jqplot.meterGaugeRenderer.js | 1029 + .../plugins/jqplot.meterGaugeRenderer.min.js | 3 + .../plugin/jqplot/plugins/jqplot.mobile.js | 45 + .../jqplot/plugins/jqplot.mobile.min.js | 3 + .../jqplot/plugins/jqplot.ohlcRenderer.js | 373 + .../jqplot/plugins/jqplot.ohlcRenderer.min.js | 3 + .../jqplot/plugins/jqplot.pieRenderer.js | 904 + .../jqplot/plugins/jqplot.pieRenderer.min.js | 3 + .../jqplot/plugins/jqplot.pointLabels.js | 377 + .../jqplot/plugins/jqplot.pointLabels.min.js | 3 + .../plugins/jqplot.pyramidAxisRenderer.js | 728 + .../plugins/jqplot.pyramidAxisRenderer.min.js | 3 + .../plugins/jqplot.pyramidGridRenderer.js | 429 + .../plugins/jqplot.pyramidGridRenderer.min.js | 3 + .../jqplot/plugins/jqplot.pyramidRenderer.js | 514 + .../plugins/jqplot.pyramidRenderer.min.js | 3 + .../plugin/jqplot/plugins/jqplot.trendline.js | 223 + .../jqplot/plugins/jqplot.trendline.min.js | 3 + .../plugin/jquery-ui/datepicker.php | 30 + AvocadoEdition/plugin/jquery-ui/style.css | 6 + AvocadoEdition/plugin/kcaptcha/_common.php | 3 + .../plugin/kcaptcha/captcha.lib.php | 3 + .../kcaptcha/fonts/palatino_linotype_bold.png | Bin 0 -> 15512 bytes .../plugin/kcaptcha/fonts/perpetua_bold.png | Bin 0 -> 12899 bytes .../plugin/kcaptcha/fonts/times_bold.png | Bin 0 -> 13965 bytes AvocadoEdition/plugin/kcaptcha/img/dot.gif | Bin 0 -> 43 bytes AvocadoEdition/plugin/kcaptcha/img/reload.gif | Bin 0 -> 616 bytes AvocadoEdition/plugin/kcaptcha/img/sound.gif | Bin 0 -> 144 bytes AvocadoEdition/plugin/kcaptcha/kcaptcha.js | 107 + .../plugin/kcaptcha/kcaptcha.lib.php | 285 + .../plugin/kcaptcha/kcaptcha_config.php | 52 + .../plugin/kcaptcha/kcaptcha_image.php | 9 + .../plugin/kcaptcha/kcaptcha_mp3.php | 44 + .../plugin/kcaptcha/kcaptcha_result.php | 13 + .../plugin/kcaptcha/kcaptcha_session.php | 18 + .../plugin/kcaptcha/mp3/basic/0.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/1.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/2.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/3.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/4.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/5.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/6.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/7.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/8.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/basic/9.mp3 | Bin 0 -> 13259 bytes .../plugin/kcaptcha/mp3/jmoon/0.mp3 | Bin 0 -> 10008 bytes .../plugin/kcaptcha/mp3/jmoon/1.mp3 | Bin 0 -> 8340 bytes .../plugin/kcaptcha/mp3/jmoon/2.mp3 | Bin 0 -> 8340 bytes .../plugin/kcaptcha/mp3/jmoon/3.mp3 | Bin 0 -> 9174 bytes .../plugin/kcaptcha/mp3/jmoon/4.mp3 | Bin 0 -> 10425 bytes .../plugin/kcaptcha/mp3/jmoon/5.mp3 | Bin 0 -> 10008 bytes .../plugin/kcaptcha/mp3/jmoon/6.mp3 | Bin 0 -> 10842 bytes .../plugin/kcaptcha/mp3/jmoon/7.mp3 | Bin 0 -> 10008 bytes .../plugin/kcaptcha/mp3/jmoon/8.mp3 | Bin 0 -> 10842 bytes .../plugin/kcaptcha/mp3/jmoon/9.mp3 | Bin 0 -> 10425 bytes AvocadoEdition/plugin/sns/_common.php | 3 + .../plugin/sns/facebook/_common.php | 3 + .../plugin/sns/facebook/callback.php | 62 + .../plugin/sns/facebook/changelog.md | 28 + .../plugin/sns/facebook/composer.json | 22 + AvocadoEdition/plugin/sns/facebook/readme.md | 85 + .../plugin/sns/facebook/src/base_facebook.php | 1441 + .../plugin/sns/facebook/src/facebook.php | 160 + .../sns/facebook/src/fb_ca_chain_bundle.crt | 3920 +++ .../plugin/sns/facebook/tests/bootstrap.php | 5 + .../plugin/sns/facebook/tests/tests.php | 2034 ++ AvocadoEdition/plugin/sns/icon/facebook.png | Bin 0 -> 1052 bytes .../plugin/sns/icon/facebook_cmt.png | Bin 0 -> 1031 bytes .../plugin/sns/icon/facebook_off.png | Bin 0 -> 920 bytes AvocadoEdition/plugin/sns/icon/gplus.png | Bin 0 -> 1669 bytes AvocadoEdition/plugin/sns/icon/gplus_off.png | Bin 0 -> 1113 bytes AvocadoEdition/plugin/sns/icon/kakaotalk.png | Bin 0 -> 1532 bytes .../plugin/sns/icon/kakaotalk_off.png | Bin 0 -> 1173 bytes AvocadoEdition/plugin/sns/icon/twitter.png | Bin 0 -> 1030 bytes .../plugin/sns/icon/twitter_cmt.png | Bin 0 -> 1022 bytes .../plugin/sns/icon/twitter_off.png | Bin 0 -> 969 bytes AvocadoEdition/plugin/sns/twitter/LICENSE | 22 + AvocadoEdition/plugin/sns/twitter/README.md | 114 + AvocadoEdition/plugin/sns/twitter/_common.php | 3 + .../plugin/sns/twitter/callback-sample.php | 40 + .../plugin/sns/twitter/callback.php | 88 + .../plugin/sns/twitter/clearsessions.php | 14 + .../plugin/sns/twitter/config-sample.php | 10 + AvocadoEdition/plugin/sns/twitter/connect.php | 22 + AvocadoEdition/plugin/sns/twitter/html.inc | 39 + .../plugin/sns/twitter/images/darker.png | Bin 0 -> 2370 bytes .../plugin/sns/twitter/images/lighter.png | Bin 0 -> 2490 bytes AvocadoEdition/plugin/sns/twitter/index.php | 35 + .../plugin/sns/twitter/redirect.php | 31 + .../plugin/sns/twitter/twitterconfig.php | 10 + .../plugin/sns/twitter/twitteroauth/OAuth.php | 872 + .../sns/twitter/twitteroauth/twitteroauth.php | 241 + AvocadoEdition/plugin/sns/view.sns.skin.php | 41 + .../plugin/sns/view_comment_list.sns.skin.php | 15 + .../sns/view_comment_write.sns.skin.php | 108 + AvocadoEdition/plugin/syndi/_common.php | 3 + AvocadoEdition/plugin/syndi/ping.php | 65 + AvocadoEdition/shop/_ajax.shop_item.php | 31 + AvocadoEdition/shop/_ajax.shop_update.php | 171 + AvocadoEdition/shop/_common.php | 3 + AvocadoEdition/shop/_head.php | 4 + AvocadoEdition/shop/_head.sub.php | 4 + AvocadoEdition/shop/_tail.php | 4 + AvocadoEdition/shop/_tail.sub.php | 4 + AvocadoEdition/shop/index.php | 160 + AvocadoEdition/shop/skin/shop.item.skin.php | 38 + AvocadoEdition/shop/skin/shop.result.skin.php | 7 + AvocadoEdition/shop/skin/shop.skin.php | 58 + .../skin/banner/basic/banner.skin.php | 98 + AvocadoEdition/skin/banner/basic/style.css | 59 + .../skin/board/basic/img/btn_close.gif | Bin 0 -> 211 bytes .../skin/board/basic/img/icon_file.gif | Bin 0 -> 107 bytes .../skin/board/basic/img/icon_hot.gif | Bin 0 -> 97 bytes .../skin/board/basic/img/icon_img.gif | Bin 0 -> 145 bytes .../skin/board/basic/img/icon_link.gif | Bin 0 -> 104 bytes .../skin/board/basic/img/icon_mobile.gif | Bin 0 -> 62 bytes .../skin/board/basic/img/icon_movie.gif | Bin 0 -> 110 bytes .../skin/board/basic/img/icon_new.gif | Bin 0 -> 71 bytes .../skin/board/basic/img/icon_reply.gif | Bin 0 -> 77 bytes .../skin/board/basic/img/icon_secret.gif | Bin 0 -> 97 bytes .../skin/board/basic/img/icon_sound.gif | Bin 0 -> 113 bytes AvocadoEdition/skin/board/basic/list.skin.php | 217 + AvocadoEdition/skin/board/basic/style.css | 120 + AvocadoEdition/skin/board/basic/view.skin.php | 202 + .../skin/board/basic/view_comment.skin.php | 334 + .../skin/board/basic/write.skin.php | 270 + .../caculate/delete_comment.tail.skin.php | 4 + .../skin/board/caculate/img/btn_close.gif | Bin 0 -> 211 bytes .../skin/board/caculate/img/icon_file.gif | Bin 0 -> 107 bytes .../skin/board/caculate/img/icon_hot.gif | Bin 0 -> 97 bytes .../skin/board/caculate/img/icon_img.gif | Bin 0 -> 145 bytes .../skin/board/caculate/img/icon_link.gif | Bin 0 -> 104 bytes .../skin/board/caculate/img/icon_mobile.gif | Bin 0 -> 62 bytes .../skin/board/caculate/img/icon_movie.gif | Bin 0 -> 110 bytes .../skin/board/caculate/img/icon_new.gif | Bin 0 -> 71 bytes .../skin/board/caculate/img/icon_reply.gif | Bin 0 -> 77 bytes .../skin/board/caculate/img/icon_secret.gif | Bin 0 -> 97 bytes .../skin/board/caculate/img/icon_sound.gif | Bin 0 -> 113 bytes .../skin/board/caculate/list.skin.php | 287 + AvocadoEdition/skin/board/caculate/style.css | 185 + .../skin/board/caculate/view.skin.php | 3 + .../skin/board/caculate/view_comment.php | 116 + .../skin/board/caculate/view_comment.skin.php | 79 + .../skin/board/caculate/write.skin.php | 183 + .../skin/board/caculate/write_comment.php | 69 + .../caculate/write_comment_update.skin.php | 27 + .../skin/board/caculate/write_update.skin.php | 19 + .../skin/board/mmb/_action.data.php | 30 + AvocadoEdition/skin/board/mmb/_common.php | 4 + .../skin/board/mmb/action/log.H.skin.php | 22 + .../skin/board/mmb/action/log.S.skin.php | 22 + .../skin/board/mmb/action/log.item.skin.php | 41 + .../skin/board/mmb/ajax/_common.php | 4 + .../skin/board/mmb/ajax/add_favorite.php | 18 + .../board/mmb/delete_comment.tail.skin.php | 4 + .../skin/board/mmb/emoticon_list.php | 45 + AvocadoEdition/skin/board/mmb/img/d1.png | Bin 0 -> 2841 bytes AvocadoEdition/skin/board/mmb/img/d2.png | Bin 0 -> 2842 bytes AvocadoEdition/skin/board/mmb/img/d3.png | Bin 0 -> 2849 bytes AvocadoEdition/skin/board/mmb/img/d4.png | Bin 0 -> 2844 bytes AvocadoEdition/skin/board/mmb/img/d5.png | Bin 0 -> 2850 bytes AvocadoEdition/skin/board/mmb/img/d6.png | Bin 0 -> 2844 bytes .../skin/board/mmb/img/img_lock.png | Bin 0 -> 7286 bytes .../skin/board/mmb/img/no_image.png | Bin 0 -> 3191 bytes .../skin/board/mmb/js/load.board.js | 103 + .../skin/board/mmb/list.log.skin.php | 180 + AvocadoEdition/skin/board/mmb/list.skin.php | 358 + AvocadoEdition/skin/board/mmb/style.css | 234 + AvocadoEdition/skin/board/mmb/view.skin.php | 3 + .../skin/board/mmb/view_comment.php | 117 + .../skin/board/mmb/view_comment.skin.php | 157 + AvocadoEdition/skin/board/mmb/write.skin.php | 686 + .../skin/board/mmb/write_comment.php | 68 + .../board/mmb/write_comment_update.skin.php | 39 + .../skin/board/mmb/write_update.inc.php | 226 + .../skin/board/mmb/write_update.skin.php | 78 + AvocadoEdition/skin/board/qna/_common.php | 4 + AvocadoEdition/skin/board/qna/ajax.filter.php | 72 + AvocadoEdition/skin/board/qna/img/a_face.gif | Bin 0 -> 241 bytes AvocadoEdition/skin/board/qna/img/best.gif | Bin 0 -> 76 bytes .../skin/board/qna/img/btn_cencel.gif | Bin 0 -> 140 bytes .../skin/board/qna/img/btn_close.gif | Bin 0 -> 223 bytes .../skin/board/qna/img/btn_comment_delete.gif | Bin 0 -> 94 bytes .../skin/board/qna/img/btn_write.gif | Bin 0 -> 144 bytes AvocadoEdition/skin/board/qna/img/comment.gif | Bin 0 -> 185 bytes AvocadoEdition/skin/board/qna/img/e_home.gif | Bin 0 -> 860 bytes AvocadoEdition/skin/board/qna/img/e_list.gif | Bin 0 -> 263 bytes AvocadoEdition/skin/board/qna/img/e_mail.gif | Bin 0 -> 70 bytes AvocadoEdition/skin/board/qna/img/e_name.gif | Bin 0 -> 860 bytes AvocadoEdition/skin/board/qna/img/e_pass.gif | Bin 0 -> 73 bytes .../skin/board/qna/img/e_search.gif | Bin 0 -> 197 bytes AvocadoEdition/skin/board/qna/img/g_face1.gif | Bin 0 -> 315 bytes AvocadoEdition/skin/board/qna/img/g_face2.gif | Bin 0 -> 294 bytes AvocadoEdition/skin/board/qna/img/g_face3.gif | Bin 0 -> 276 bytes AvocadoEdition/skin/board/qna/img/g_face4.gif | Bin 0 -> 221 bytes AvocadoEdition/skin/board/qna/img/g_face5.gif | Bin 0 -> 256 bytes .../skin/board/qna/img/i_notice.gif | Bin 0 -> 270 bytes AvocadoEdition/skin/board/qna/img/i_write.gif | Bin 0 -> 269 bytes .../skin/board/qna/img/icon_file.gif | Bin 0 -> 332 bytes .../skin/board/qna/img/icon_hot.gif | Bin 0 -> 76 bytes .../skin/board/qna/img/icon_new.gif | Bin 0 -> 77 bytes .../skin/board/qna/img/icon_secret.gif | Bin 0 -> 51 bytes .../skin/board/qna/img/icon_secret2.gif | Bin 0 -> 88 bytes AvocadoEdition/skin/board/qna/img/line.gif | Bin 0 -> 51 bytes AvocadoEdition/skin/board/qna/img/line2.gif | Bin 0 -> 59 bytes .../skin/board/qna/img/no_image.jpg | Bin 0 -> 15125 bytes AvocadoEdition/skin/board/qna/img/reply.gif | Bin 0 -> 59 bytes AvocadoEdition/skin/board/qna/img/search.gif | Bin 0 -> 148 bytes .../skin/board/qna/inc.list_main.php | 17 + AvocadoEdition/skin/board/qna/list.skin.php | 247 + AvocadoEdition/skin/board/qna/password.php | 10 + AvocadoEdition/skin/board/qna/style.css | 83 + AvocadoEdition/skin/board/qna/view.skin.php | 7 + .../skin/board/qna/view_comment.php | 119 + .../skin/board/qna/view_comment.skin.php | 84 + .../skin/board/qna/view_skin_js.php | 11 + AvocadoEdition/skin/board/qna/write.php | 420 + AvocadoEdition/skin/board/qna/write.skin.php | 86 + .../skin/board/qna/write_comment_update.php | 342 + .../board/qna/write_comment_update.skin.php | 6 + .../skin/board/qna/write_update.skin.php | 6 + .../skin/connect/basic/connect.skin.php | 9 + .../connect/basic/current_connect.skin.php | 46 + AvocadoEdition/skin/connect/basic/style.css | 1 + .../skin/content/basic/content.skin.php | 6 + AvocadoEdition/skin/content/basic/style.css | 4 + AvocadoEdition/skin/faq/basic/list.skin.php | 136 + AvocadoEdition/skin/faq/basic/style.css | 23 + .../skin/latest/basic/img/icon_file.gif | Bin 0 -> 107 bytes .../skin/latest/basic/img/icon_hot.gif | Bin 0 -> 97 bytes .../skin/latest/basic/img/icon_img.gif | Bin 0 -> 145 bytes .../skin/latest/basic/img/icon_link.gif | Bin 0 -> 104 bytes .../skin/latest/basic/img/icon_mobile.gif | Bin 0 -> 62 bytes .../skin/latest/basic/img/icon_more.gif | Bin 0 -> 169 bytes .../skin/latest/basic/img/icon_movie.gif | Bin 0 -> 110 bytes .../skin/latest/basic/img/icon_new.gif | Bin 0 -> 71 bytes .../skin/latest/basic/img/icon_reply.gif | Bin 0 -> 77 bytes .../skin/latest/basic/img/icon_secret.gif | Bin 0 -> 97 bytes .../skin/latest/basic/img/icon_sound.gif | Bin 0 -> 113 bytes .../skin/latest/basic/latest.skin.php | 44 + AvocadoEdition/skin/latest/basic/style.css | 11 + .../skin/latest/rolling/latest.skin.php | 43 + AvocadoEdition/skin/latest/rolling/style.css | 10 + .../skin/member/basic/formmail.skin.php | 100 + .../basic/img/bak_admin_login_top_pattern.png | Bin 0 -> 942 bytes .../skin/member/basic/img/zip_ico_up.gif | Bin 0 -> 54 bytes .../skin/member/basic/login.admin.skin.php | 83 + .../skin/member/basic/login.skin.php | 56 + .../skin/member/basic/login_check.skin.php | 5 + .../skin/member/basic/member_confirm.skin.php | 54 + .../skin/member/basic/memo.skin.php | 10 + .../skin/member/basic/memo_form.skin.php | 47 + .../skin/member/basic/memo_view.skin.php | 4 + .../skin/member/basic/password.skin.php | 62 + .../skin/member/basic/password_lost.skin.php | 47 + .../skin/member/basic/point.skin.php | 88 + .../skin/member/basic/profile.skin.php | 50 + .../skin/member/basic/register.skin.php | 70 + .../skin/member/basic/register_form.skin.php | 133 + .../member/basic/register_result.skin.php | 39 + .../skin/member/basic/scrap.skin.php | 46 + .../skin/member/basic/scrap_popin.skin.php | 41 + .../skin/member/basic/style.admin.css | 231 + AvocadoEdition/skin/member/basic/style.css | 114 + AvocadoEdition/skin/new/basic/new.skin.php | 144 + AvocadoEdition/skin/new/basic/style.css | 7 + .../skin/outlogin/basic/outlogin.skin.1.php | 34 + .../skin/outlogin/basic/outlogin.skin.2.php | 76 + AvocadoEdition/skin/outlogin/basic/style.css | 158 + AvocadoEdition/skin/poll/basic/poll.skin.php | 65 + .../skin/poll/basic/poll_result.skin.php | 125 + AvocadoEdition/skin/poll/basic/style.css | 87 + .../skin/popular/basic/popular.skin.php | 19 + AvocadoEdition/skin/popular/basic/style.css | 12 + .../skin/qa/basic/img/btn_close.gif | Bin 0 -> 211 bytes .../skin/qa/basic/img/icon_answer.gif | Bin 0 -> 77 bytes .../skin/qa/basic/img/icon_file.gif | Bin 0 -> 107 bytes AvocadoEdition/skin/qa/basic/img/icon_hot.gif | Bin 0 -> 97 bytes AvocadoEdition/skin/qa/basic/img/icon_img.gif | Bin 0 -> 145 bytes .../skin/qa/basic/img/icon_link.gif | Bin 0 -> 104 bytes .../skin/qa/basic/img/icon_mobile.gif | Bin 0 -> 62 bytes .../skin/qa/basic/img/icon_movie.gif | Bin 0 -> 110 bytes AvocadoEdition/skin/qa/basic/img/icon_new.gif | Bin 0 -> 71 bytes .../skin/qa/basic/img/icon_secret.gif | Bin 0 -> 97 bytes .../skin/qa/basic/img/icon_sound.gif | Bin 0 -> 113 bytes AvocadoEdition/skin/qa/basic/list.skin.php | 146 + AvocadoEdition/skin/qa/basic/style.css | 33 + .../skin/qa/basic/view.answer.skin.php | 33 + .../skin/qa/basic/view.answerform.skin.php | 120 + AvocadoEdition/skin/qa/basic/view.skin.php | 128 + AvocadoEdition/skin/qa/basic/write.skin.php | 167 + .../skin/search/basic/search.skin.php | 140 + AvocadoEdition/skin/search/basic/style.css | 29 + AvocadoEdition/skin/visit/basic/style.css | 13 + .../skin/visit/basic/visit.skin.php | 27 + AvocadoEdition/tail.php | 41 + AvocadoEdition/tail.sub.php | 20 + AvocadoEdition/templete/txt.bgm.php | 53 + AvocadoEdition/templete/txt.join.php | 3 + AvocadoEdition/templete/txt.login.php | 3 + AvocadoEdition/templete/txt.logout.php | 3 + AvocadoEdition/templete/txt.mypage.php | 3 + AvocadoEdition/templete/txt.outlogin.php | 1 + AvocadoEdition/templete/txt.twitter.php | 23 + AvocadoEdition/templete/txt.visual.php | 1 + AvocadoEdition/theme/basic/_common.php | 2 + .../theme/basic/couple/list.skin.php | 31 + AvocadoEdition/theme/basic/css/couple.css | 13 + AvocadoEdition/theme/basic/css/default.css | 146 + AvocadoEdition/theme/basic/css/emoticon.css | 45 + AvocadoEdition/theme/basic/css/enter.css | 29 + AvocadoEdition/theme/basic/css/index.css | 31 + AvocadoEdition/theme/basic/css/intro.css | 22 + AvocadoEdition/theme/basic/css/login.css | 25 + AvocadoEdition/theme/basic/css/main.css | 9 + AvocadoEdition/theme/basic/css/member.css | 120 + AvocadoEdition/theme/basic/css/mypage.css | 256 + AvocadoEdition/theme/basic/css/shop.css | 64 + AvocadoEdition/theme/basic/css/style.css | 436 + AvocadoEdition/theme/basic/enter.php | 63 + .../theme/basic/extend/theme.extend.php | 7 + AvocadoEdition/theme/basic/group.php | 49 + AvocadoEdition/theme/basic/head.php | 96 + AvocadoEdition/theme/basic/head.sub.php | 124 + AvocadoEdition/theme/basic/index.php | 34 + .../theme/basic/inventory/item.skin.php | 47 + .../theme/basic/inventory/list.skin.php | 30 + AvocadoEdition/theme/basic/main.php | 16 + .../theme/basic/member/list.skin.php | 52 + .../theme/basic/member/ready_list.skin.php | 94 + .../theme/basic/member/viewer.skin.php | 269 + AvocadoEdition/theme/basic/readme.txt | 8 + AvocadoEdition/theme/basic/screenshot.png | Bin 0 -> 9544 bytes .../theme/basic/shop/shop.item.skin.php | 38 + .../theme/basic/shop/shop.result.skin.php | 7 + AvocadoEdition/theme/basic/shop/shop.skin.php | 57 + .../basic/skin/board/basic/img/btn_cmt.png | Bin 0 -> 2942 bytes .../theme/basic/skin/board/basic/img/chk.png | Bin 0 -> 1070 bytes .../basic/skin/board/basic/img/close_btn.png | Bin 0 -> 1147 bytes .../basic/skin/board/basic/img/icon_lock.png | Bin 0 -> 1225 bytes .../skin/board/basic/img/icon_mobile.gif | Bin 0 -> 339 bytes .../basic/skin/board/basic/img/icon_reply.gif | Bin 0 -> 1187 bytes .../skin/board/basic/img/icon_secret.gif | Bin 0 -> 318 bytes .../basic/skin/board/basic/list.skin.php | 292 + .../theme/basic/skin/board/basic/style.css | 341 + .../basic/skin/board/basic/view.skin.php | 300 + .../skin/board/basic/view_comment.skin.php | 352 + .../basic/skin/board/basic/write.skin.php | 255 + .../basic/skin/content/basic/content.skin.php | 17 + .../theme/basic/skin/content/basic/style.css | 10 + .../basic/skin/outlogin/basic/img/chk.png | Bin 0 -> 1070 bytes .../skin/outlogin/basic/img/info_edit.png | Bin 0 -> 1341 bytes .../skin/outlogin/basic/outlogin.skin.1.php | 69 + .../skin/outlogin/basic/outlogin.skin.2.php | 52 + .../theme/basic/skin/outlogin/basic/style.css | 64 + .../skin/outlogin/shop_basic/img/chk.png | Bin 0 -> 1070 bytes .../outlogin/shop_basic/outlogin.skin.1.php | 55 + .../outlogin/shop_basic/outlogin.skin.2.php | 43 + .../basic/skin/outlogin/shop_basic/style.css | 44 + .../basic/skin/outlogin/shop_side/img/chk.png | Bin 0 -> 1070 bytes .../outlogin/shop_side/outlogin.skin.1.php | 65 + .../outlogin/shop_side/outlogin.skin.2.php | 70 + .../basic/skin/outlogin/shop_side/style.css | 64 + AvocadoEdition/theme/basic/tail.php | 35 + AvocadoEdition/theme/basic/tail.sub.php | 15 + 1537 files changed, 228688 insertions(+) create mode 100644 AvocadoEdition/_common.php create mode 100644 AvocadoEdition/_head.php create mode 100644 AvocadoEdition/_tail.php create mode 100644 AvocadoEdition/adm/_common.php create mode 100644 AvocadoEdition/adm/action_delete.php create mode 100644 AvocadoEdition/adm/action_list.php create mode 100644 AvocadoEdition/adm/action_list_update.php create mode 100644 AvocadoEdition/adm/action_reply.php create mode 100644 AvocadoEdition/adm/admin.ajax.js create mode 100644 AvocadoEdition/adm/admin.head.php create mode 100644 AvocadoEdition/adm/admin.js create mode 100644 AvocadoEdition/adm/admin.lib.php create mode 100644 AvocadoEdition/adm/admin.menu100.php create mode 100644 AvocadoEdition/adm/admin.menu200.php create mode 100644 AvocadoEdition/adm/admin.menu300.php create mode 100644 AvocadoEdition/adm/admin.menu400.php create mode 100644 AvocadoEdition/adm/admin.menu500.php create mode 100644 AvocadoEdition/adm/admin.menu900.php create mode 100644 AvocadoEdition/adm/admin.tail.php create mode 100644 AvocadoEdition/adm/ajax.token.php create mode 100644 AvocadoEdition/adm/ajax/_common.php create mode 100644 AvocadoEdition/adm/auth_list.php create mode 100644 AvocadoEdition/adm/auth_list_delete.php create mode 100644 AvocadoEdition/adm/auth_update.php create mode 100644 AvocadoEdition/adm/banner_form.php create mode 100644 AvocadoEdition/adm/banner_form_update.php create mode 100644 AvocadoEdition/adm/banner_list.php create mode 100644 AvocadoEdition/adm/board_copy.php create mode 100644 AvocadoEdition/adm/board_copy_update.php create mode 100644 AvocadoEdition/adm/board_delete.inc.php create mode 100644 AvocadoEdition/adm/board_form.php create mode 100644 AvocadoEdition/adm/board_form_update.php create mode 100644 AvocadoEdition/adm/board_list.php create mode 100644 AvocadoEdition/adm/board_list_update.php create mode 100644 AvocadoEdition/adm/board_thumbnail_delete.php create mode 100644 AvocadoEdition/adm/boardgroup_form.php create mode 100644 AvocadoEdition/adm/boardgroup_form_update.php create mode 100644 AvocadoEdition/adm/boardgroup_list.php create mode 100644 AvocadoEdition/adm/boardgroup_list_update.php create mode 100644 AvocadoEdition/adm/boardgroupmember_form.php create mode 100644 AvocadoEdition/adm/boardgroupmember_list.php create mode 100644 AvocadoEdition/adm/boardgroupmember_update.php create mode 100644 AvocadoEdition/adm/browscap.php create mode 100644 AvocadoEdition/adm/browscap_convert.php create mode 100644 AvocadoEdition/adm/browscap_converter.php create mode 100644 AvocadoEdition/adm/browscap_update.php create mode 100644 AvocadoEdition/adm/cache_file_delete.php create mode 100644 AvocadoEdition/adm/captcha_file_delete.php create mode 100644 AvocadoEdition/adm/character_article_list.php create mode 100644 AvocadoEdition/adm/character_article_list_update.php create mode 100644 AvocadoEdition/adm/character_article_update.php create mode 100644 AvocadoEdition/adm/character_delete.php create mode 100644 AvocadoEdition/adm/character_form.php create mode 100644 AvocadoEdition/adm/character_form_update.php create mode 100644 AvocadoEdition/adm/character_list.php create mode 100644 AvocadoEdition/adm/character_list_update.php create mode 100644 AvocadoEdition/adm/class_list.php create mode 100644 AvocadoEdition/adm/class_list_delete.php create mode 100644 AvocadoEdition/adm/class_update.php create mode 100644 AvocadoEdition/adm/community_form.php create mode 100644 AvocadoEdition/adm/community_form_update.php create mode 100644 AvocadoEdition/adm/config_form.php create mode 100644 AvocadoEdition/adm/config_form_update.php create mode 100644 AvocadoEdition/adm/contentform.php create mode 100644 AvocadoEdition/adm/contentformupdate.php create mode 100644 AvocadoEdition/adm/contentlist.php create mode 100644 AvocadoEdition/adm/couple_list.php create mode 100644 AvocadoEdition/adm/couple_list_delete.php create mode 100644 AvocadoEdition/adm/couple_update.php create mode 100644 AvocadoEdition/adm/css/admin.css create mode 100644 AvocadoEdition/adm/css/admin.layout.css create mode 100644 AvocadoEdition/adm/css/theme.css create mode 100644 AvocadoEdition/adm/data_backup.php create mode 100644 AvocadoEdition/adm/data_backup_delete.php create mode 100644 AvocadoEdition/adm/data_backup_update.php create mode 100644 AvocadoEdition/adm/data_restore.php create mode 100644 AvocadoEdition/adm/data_restore_update.php create mode 100644 AvocadoEdition/adm/design_form.php create mode 100644 AvocadoEdition/adm/design_form_css.php create mode 100644 AvocadoEdition/adm/design_form_update.php create mode 100644 AvocadoEdition/adm/emoticon_form_update.php create mode 100644 AvocadoEdition/adm/emoticon_list.php create mode 100644 AvocadoEdition/adm/emoticon_list_update.php create mode 100644 AvocadoEdition/adm/exp_list.php create mode 100644 AvocadoEdition/adm/exp_list_delete.php create mode 100644 AvocadoEdition/adm/exp_update.php create mode 100644 AvocadoEdition/adm/explorer_list.php create mode 100644 AvocadoEdition/adm/explorer_list_update.php create mode 100644 AvocadoEdition/adm/explorer_update.php create mode 100644 AvocadoEdition/adm/faqform.php create mode 100644 AvocadoEdition/adm/faqformupdate.php create mode 100644 AvocadoEdition/adm/faqlist.php create mode 100644 AvocadoEdition/adm/faqmasterform.php create mode 100644 AvocadoEdition/adm/faqmasterformupdate.php create mode 100644 AvocadoEdition/adm/faqmasterlist.php create mode 100644 AvocadoEdition/adm/file_list.php create mode 100644 AvocadoEdition/adm/head.sub.php create mode 100644 AvocadoEdition/adm/img/ajax_loader.gif create mode 100644 AvocadoEdition/adm/img/check.png create mode 100644 AvocadoEdition/adm/img/close.gif create mode 100644 AvocadoEdition/adm/img/close.png create mode 100644 AvocadoEdition/adm/img/hd_bg.jpg create mode 100644 AvocadoEdition/adm/img/link_icon.gif create mode 100644 AvocadoEdition/adm/img/logo.jpg create mode 100644 AvocadoEdition/adm/img/logo.png create mode 100644 AvocadoEdition/adm/img/service_img1.jpg create mode 100644 AvocadoEdition/adm/img/service_img2.jpg create mode 100644 AvocadoEdition/adm/img/sub_menu_ico.gif create mode 100644 AvocadoEdition/adm/img/svc_btn_01.jpg create mode 100644 AvocadoEdition/adm/img/svc_btn_02.jpg create mode 100644 AvocadoEdition/adm/img/svc_btn_03.jpg create mode 100644 AvocadoEdition/adm/img/svc_btn_04.jpg create mode 100644 AvocadoEdition/adm/img/svc_btn_05.jpg create mode 100644 AvocadoEdition/adm/img/theme_img.jpg create mode 100644 AvocadoEdition/adm/img/ts01.gif create mode 100644 AvocadoEdition/adm/img/ts02.gif create mode 100644 AvocadoEdition/adm/img/ts03.gif create mode 100644 AvocadoEdition/adm/img_list.php create mode 100644 AvocadoEdition/adm/index.php create mode 100644 AvocadoEdition/adm/intro_form.php create mode 100644 AvocadoEdition/adm/intro_form_update.php create mode 100644 AvocadoEdition/adm/intro_list.php create mode 100644 AvocadoEdition/adm/inventory_list.php create mode 100644 AvocadoEdition/adm/inventory_list_delete.php create mode 100644 AvocadoEdition/adm/inventory_update.php create mode 100644 AvocadoEdition/adm/item_form.php create mode 100644 AvocadoEdition/adm/item_form_update.php create mode 100644 AvocadoEdition/adm/item_list.php create mode 100644 AvocadoEdition/adm/item_list_update.php create mode 100644 AvocadoEdition/adm/level_form_update.php create mode 100644 AvocadoEdition/adm/level_list.php create mode 100644 AvocadoEdition/adm/level_list_update.php create mode 100644 AvocadoEdition/adm/mail_delete.php create mode 100644 AvocadoEdition/adm/mail_form.php create mode 100644 AvocadoEdition/adm/mail_list.php create mode 100644 AvocadoEdition/adm/mail_preview.php create mode 100644 AvocadoEdition/adm/mail_select_form.php create mode 100644 AvocadoEdition/adm/mail_select_list.php create mode 100644 AvocadoEdition/adm/mail_select_update.php create mode 100644 AvocadoEdition/adm/mail_test.php create mode 100644 AvocadoEdition/adm/mail_update.php create mode 100644 AvocadoEdition/adm/member_delete.php create mode 100644 AvocadoEdition/adm/member_form.php create mode 100644 AvocadoEdition/adm/member_form_update.php create mode 100644 AvocadoEdition/adm/member_list.php create mode 100644 AvocadoEdition/adm/member_list_delete.php create mode 100644 AvocadoEdition/adm/member_list_update.php create mode 100644 AvocadoEdition/adm/menu_form.php create mode 100644 AvocadoEdition/adm/menu_form_search.php create mode 100644 AvocadoEdition/adm/menu_list.php create mode 100644 AvocadoEdition/adm/menu_list_update.php create mode 100644 AvocadoEdition/adm/newwinform.php create mode 100644 AvocadoEdition/adm/newwinformupdate.php create mode 100644 AvocadoEdition/adm/newwinlist.php create mode 100644 AvocadoEdition/adm/order_list.php create mode 100644 AvocadoEdition/adm/order_list_delete.php create mode 100644 AvocadoEdition/adm/phpinfo.php create mode 100644 AvocadoEdition/adm/point_list.php create mode 100644 AvocadoEdition/adm/point_list_delete.php create mode 100644 AvocadoEdition/adm/point_update.php create mode 100644 AvocadoEdition/adm/poll_delete.php create mode 100644 AvocadoEdition/adm/poll_form.php create mode 100644 AvocadoEdition/adm/poll_form_update.php create mode 100644 AvocadoEdition/adm/poll_list.php create mode 100644 AvocadoEdition/adm/popular_list.php create mode 100644 AvocadoEdition/adm/popular_rank.php create mode 100644 AvocadoEdition/adm/qa_config.php create mode 100644 AvocadoEdition/adm/qa_config_update.php create mode 100644 AvocadoEdition/adm/quest_form.php create mode 100644 AvocadoEdition/adm/quest_form_update.php create mode 100644 AvocadoEdition/adm/quest_list.php create mode 100644 AvocadoEdition/adm/quest_list_update.php create mode 100644 AvocadoEdition/adm/recipi_list.php create mode 100644 AvocadoEdition/adm/recipi_list_update.php create mode 100644 AvocadoEdition/adm/recipi_update.php create mode 100644 AvocadoEdition/adm/sendmail_test.php create mode 100644 AvocadoEdition/adm/service.php create mode 100644 AvocadoEdition/adm/session_file_delete.php create mode 100644 AvocadoEdition/adm/shop_form.php create mode 100644 AvocadoEdition/adm/shop_form_update.php create mode 100644 AvocadoEdition/adm/shop_list.php create mode 100644 AvocadoEdition/adm/shop_list_update.php create mode 100644 AvocadoEdition/adm/side_list.php create mode 100644 AvocadoEdition/adm/side_list_delete.php create mode 100644 AvocadoEdition/adm/side_update.php create mode 100644 AvocadoEdition/adm/sql_write.sql create mode 100644 AvocadoEdition/adm/status_form_update.php create mode 100644 AvocadoEdition/adm/status_list.php create mode 100644 AvocadoEdition/adm/status_list_update.php create mode 100644 AvocadoEdition/adm/theme.js create mode 100644 AvocadoEdition/adm/theme.php create mode 100644 AvocadoEdition/adm/theme_config_load.php create mode 100644 AvocadoEdition/adm/theme_detail.php create mode 100644 AvocadoEdition/adm/theme_preview.php create mode 100644 AvocadoEdition/adm/theme_update.php create mode 100644 AvocadoEdition/adm/thumbnail_file_delete.php create mode 100644 AvocadoEdition/adm/title_has_list.php create mode 100644 AvocadoEdition/adm/title_has_list_delete.php create mode 100644 AvocadoEdition/adm/title_has_update.php create mode 100644 AvocadoEdition/adm/title_list.php create mode 100644 AvocadoEdition/adm/title_list_update.php create mode 100644 AvocadoEdition/adm/title_update.php create mode 100644 AvocadoEdition/adm/viewer_form.php create mode 100644 AvocadoEdition/adm/viewer_form_update.php create mode 100644 AvocadoEdition/adm/visit.sub.php create mode 100644 AvocadoEdition/adm/visit_browser.php create mode 100644 AvocadoEdition/adm/visit_date.php create mode 100644 AvocadoEdition/adm/visit_delete.php create mode 100644 AvocadoEdition/adm/visit_delete_update.php create mode 100644 AvocadoEdition/adm/visit_device.php create mode 100644 AvocadoEdition/adm/visit_domain.php create mode 100644 AvocadoEdition/adm/visit_hour.php create mode 100644 AvocadoEdition/adm/visit_list.php create mode 100644 AvocadoEdition/adm/visit_month.php create mode 100644 AvocadoEdition/adm/visit_os.php create mode 100644 AvocadoEdition/adm/visit_search.php create mode 100644 AvocadoEdition/adm/visit_week.php create mode 100644 AvocadoEdition/adm/visit_year.php create mode 100644 AvocadoEdition/adm/write_count.php create mode 100644 AvocadoEdition/ajax/_common.php create mode 100644 AvocadoEdition/ajax/_search_character.php create mode 100644 AvocadoEdition/ajax/_search_item.php create mode 100644 AvocadoEdition/ajax/_search_member.php create mode 100644 AvocadoEdition/ajax/_search_title.php create mode 100644 AvocadoEdition/ajax/board_call.php create mode 100644 AvocadoEdition/ajax/close_call.php create mode 100644 AvocadoEdition/ajax/close_memo.php create mode 100644 AvocadoEdition/ajax/inventory_popup.php create mode 100644 AvocadoEdition/ajax/load_board_call.php create mode 100644 AvocadoEdition/ajax/load_memo_call.php create mode 100644 AvocadoEdition/ajax/memo_call.MP3 create mode 100644 AvocadoEdition/ajax/memo_call.php create mode 100644 AvocadoEdition/bbs/_common.php create mode 100644 AvocadoEdition/bbs/_head.php create mode 100644 AvocadoEdition/bbs/_head.sub.php create mode 100644 AvocadoEdition/bbs/_tail.php create mode 100644 AvocadoEdition/bbs/_tail.sub.php create mode 100644 AvocadoEdition/bbs/ajax.autosave.php create mode 100644 AvocadoEdition/bbs/ajax.autosavedel.php create mode 100644 AvocadoEdition/bbs/ajax.autosavelist.php create mode 100644 AvocadoEdition/bbs/ajax.autosaveload.php create mode 100644 AvocadoEdition/bbs/ajax.comment_token.php create mode 100644 AvocadoEdition/bbs/ajax.filter.php create mode 100644 AvocadoEdition/bbs/ajax.mb_email.php create mode 100644 AvocadoEdition/bbs/ajax.mb_hp.php create mode 100644 AvocadoEdition/bbs/ajax.mb_id.php create mode 100644 AvocadoEdition/bbs/ajax.mb_nick.php create mode 100644 AvocadoEdition/bbs/ajax.mb_recommend.php create mode 100644 AvocadoEdition/bbs/alert.php create mode 100644 AvocadoEdition/bbs/alert_close.php create mode 100644 AvocadoEdition/bbs/board.php create mode 100644 AvocadoEdition/bbs/board_head.php create mode 100644 AvocadoEdition/bbs/board_list_update.php create mode 100644 AvocadoEdition/bbs/board_tail.php create mode 100644 AvocadoEdition/bbs/character_list.php create mode 100644 AvocadoEdition/bbs/confirm.php create mode 100644 AvocadoEdition/bbs/content.php create mode 100644 AvocadoEdition/bbs/current_connect.php create mode 100644 AvocadoEdition/bbs/db_table.optimize.php create mode 100644 AvocadoEdition/bbs/delete.php create mode 100644 AvocadoEdition/bbs/delete_all.php create mode 100644 AvocadoEdition/bbs/delete_comment.php create mode 100644 AvocadoEdition/bbs/download.php create mode 100644 AvocadoEdition/bbs/email_certify.php create mode 100644 AvocadoEdition/bbs/email_stop.php create mode 100644 AvocadoEdition/bbs/faq.php create mode 100644 AvocadoEdition/bbs/formmail.php create mode 100644 AvocadoEdition/bbs/formmail_send.php create mode 100644 AvocadoEdition/bbs/good.php create mode 100644 AvocadoEdition/bbs/group.php create mode 100644 AvocadoEdition/bbs/index.php create mode 100644 AvocadoEdition/bbs/link.php create mode 100644 AvocadoEdition/bbs/list.mmb.php create mode 100644 AvocadoEdition/bbs/list.php create mode 100644 AvocadoEdition/bbs/login.php create mode 100644 AvocadoEdition/bbs/login_check.php create mode 100644 AvocadoEdition/bbs/logout.php create mode 100644 AvocadoEdition/bbs/member_confirm.php create mode 100644 AvocadoEdition/bbs/member_leave.php create mode 100644 AvocadoEdition/bbs/memo.php create mode 100644 AvocadoEdition/bbs/memo_delete.php create mode 100644 AvocadoEdition/bbs/memo_form.php create mode 100644 AvocadoEdition/bbs/memo_form_update.php create mode 100644 AvocadoEdition/bbs/memo_view.php create mode 100644 AvocadoEdition/bbs/move.php create mode 100644 AvocadoEdition/bbs/move_update.php create mode 100644 AvocadoEdition/bbs/new.php create mode 100644 AvocadoEdition/bbs/new_delete.php create mode 100644 AvocadoEdition/bbs/newwin.inc.php create mode 100644 AvocadoEdition/bbs/password.php create mode 100644 AvocadoEdition/bbs/password_check.php create mode 100644 AvocadoEdition/bbs/password_lost.php create mode 100644 AvocadoEdition/bbs/password_lost2.php create mode 100644 AvocadoEdition/bbs/password_lost_certify.php create mode 100644 AvocadoEdition/bbs/point.php create mode 100644 AvocadoEdition/bbs/poll.php create mode 100644 AvocadoEdition/bbs/poll_etc_update.php create mode 100644 AvocadoEdition/bbs/poll_etc_update_mail.php create mode 100644 AvocadoEdition/bbs/poll_result.php create mode 100644 AvocadoEdition/bbs/poll_update.php create mode 100644 AvocadoEdition/bbs/profile.php create mode 100644 AvocadoEdition/bbs/qadelete.php create mode 100644 AvocadoEdition/bbs/qadownload.php create mode 100644 AvocadoEdition/bbs/qahead.php create mode 100644 AvocadoEdition/bbs/qalist.php create mode 100644 AvocadoEdition/bbs/qatail.php create mode 100644 AvocadoEdition/bbs/qaview.php create mode 100644 AvocadoEdition/bbs/qawrite.php create mode 100644 AvocadoEdition/bbs/qawrite_update.php create mode 100644 AvocadoEdition/bbs/register.php create mode 100644 AvocadoEdition/bbs/register_email.php create mode 100644 AvocadoEdition/bbs/register_email_update.php create mode 100644 AvocadoEdition/bbs/register_form.php create mode 100644 AvocadoEdition/bbs/register_form_update.php create mode 100644 AvocadoEdition/bbs/register_form_update_mail1.php create mode 100644 AvocadoEdition/bbs/register_form_update_mail2.php create mode 100644 AvocadoEdition/bbs/register_form_update_mail3.php create mode 100644 AvocadoEdition/bbs/register_result.php create mode 100644 AvocadoEdition/bbs/rss.php create mode 100644 AvocadoEdition/bbs/scrap.php create mode 100644 AvocadoEdition/bbs/scrap_delete.php create mode 100644 AvocadoEdition/bbs/scrap_popin.php create mode 100644 AvocadoEdition/bbs/scrap_popin_update.php create mode 100644 AvocadoEdition/bbs/search.php create mode 100644 AvocadoEdition/bbs/sns_send.php create mode 100644 AvocadoEdition/bbs/view.php create mode 100644 AvocadoEdition/bbs/view_comment.php create mode 100644 AvocadoEdition/bbs/view_image.php create mode 100644 AvocadoEdition/bbs/visit_browscap.inc.php create mode 100644 AvocadoEdition/bbs/visit_insert.inc.php create mode 100644 AvocadoEdition/bbs/write.php create mode 100644 AvocadoEdition/bbs/write_comment_update.php create mode 100644 AvocadoEdition/bbs/write_comment_update.sns.php create mode 100644 AvocadoEdition/bbs/write_token.php create mode 100644 AvocadoEdition/bbs/write_update.php create mode 100644 AvocadoEdition/bbs/write_update_file.php create mode 100644 AvocadoEdition/bbs/write_update_mail.php create mode 100644 AvocadoEdition/bgm.php create mode 100644 AvocadoEdition/common.php create mode 100644 AvocadoEdition/config.php create mode 100644 AvocadoEdition/couple/_common.php create mode 100644 AvocadoEdition/couple/_head.php create mode 100644 AvocadoEdition/couple/_head.sub.php create mode 100644 AvocadoEdition/couple/_tail.php create mode 100644 AvocadoEdition/couple/_tail.sub.php create mode 100644 AvocadoEdition/couple/index.php create mode 100644 AvocadoEdition/couple/skin/list.skin.php create mode 100644 AvocadoEdition/css/closet.css create mode 100644 AvocadoEdition/css/couple.css create mode 100644 AvocadoEdition/css/default.css create mode 100644 AvocadoEdition/css/emoticon.css create mode 100644 AvocadoEdition/css/enter.css create mode 100644 AvocadoEdition/css/exp.css create mode 100644 AvocadoEdition/css/fonts/MetalMania-Regular.eot create mode 100644 AvocadoEdition/css/fonts/MetalMania-Regular.ttf create mode 100644 AvocadoEdition/css/fonts/MetalMania-Regular.woff create mode 100644 AvocadoEdition/css/fonts/icomoon.eot create mode 100644 AvocadoEdition/css/fonts/icomoon.svg create mode 100644 AvocadoEdition/css/fonts/icomoon.ttf create mode 100644 AvocadoEdition/css/fonts/icomoon.woff create mode 100644 AvocadoEdition/css/images/ajax-loader.gif create mode 100644 AvocadoEdition/css/images/icons-18-black.png create mode 100644 AvocadoEdition/css/images/icons-18-white.png create mode 100644 AvocadoEdition/css/images/icons-36-black.png create mode 100644 AvocadoEdition/css/images/icons-36-white.png create mode 100644 AvocadoEdition/css/index.css create mode 100644 AvocadoEdition/css/intro.css create mode 100644 AvocadoEdition/css/login.css create mode 100644 AvocadoEdition/css/main.css create mode 100644 AvocadoEdition/css/member.css create mode 100644 AvocadoEdition/css/mypage.css create mode 100644 AvocadoEdition/css/shop.css create mode 100644 AvocadoEdition/css/style.css create mode 100644 AvocadoEdition/css/swiper.css create mode 100644 AvocadoEdition/enter.php create mode 100644 AvocadoEdition/extend/_sample.config.php create mode 100644 AvocadoEdition/extend/banner.lib.php create mode 100644 AvocadoEdition/extend/character.lib.php create mode 100644 AvocadoEdition/extend/community.config.php create mode 100644 AvocadoEdition/extend/exp.lib.php create mode 100644 AvocadoEdition/extend/item.lib.php create mode 100644 AvocadoEdition/extend/menu.lib.php create mode 100644 AvocadoEdition/extend/mmb.lib.php create mode 100644 AvocadoEdition/extend/rank.lib.php create mode 100644 AvocadoEdition/extend/sideclass.lib.php create mode 100644 AvocadoEdition/extend/smarteditor_upload_extend.php create mode 100644 AvocadoEdition/extend/status.lib.php create mode 100644 AvocadoEdition/extend/title.lib.php create mode 100644 AvocadoEdition/extend/user.config.php create mode 100644 AvocadoEdition/extend/version.extend.php create mode 100644 AvocadoEdition/head.php create mode 100644 AvocadoEdition/head.sub.php create mode 100644 AvocadoEdition/img/btn_search.jpg create mode 100644 AvocadoEdition/img/btn_top.png create mode 100644 AvocadoEdition/img/captcha.png create mode 100644 AvocadoEdition/img/ico_memo.png create mode 100644 AvocadoEdition/img/ico_menu_control_pannel.png create mode 100644 AvocadoEdition/img/shop/npc.png create mode 100644 AvocadoEdition/img/temp_main_image.png create mode 100644 AvocadoEdition/img/ts01.gif create mode 100644 AvocadoEdition/img/ts02.gif create mode 100644 AvocadoEdition/img/ts03.gif create mode 100644 AvocadoEdition/img/wrest.gif create mode 100644 AvocadoEdition/index.php create mode 100644 AvocadoEdition/install/AVOCADO.LICENSE.txt create mode 100644 AvocadoEdition/install/LICENSE.txt create mode 100644 AvocadoEdition/install/gnuboard5.sql create mode 100644 AvocadoEdition/install/img/mooning.png create mode 100644 AvocadoEdition/install/img/pat01.png create mode 100644 AvocadoEdition/install/img/ricepaper_v3.png create mode 100644 AvocadoEdition/install/index.php create mode 100644 AvocadoEdition/install/install.css create mode 100644 AvocadoEdition/install/install.inc.php create mode 100644 AvocadoEdition/install/install.inc2.php create mode 100644 AvocadoEdition/install/install_config.php create mode 100644 AvocadoEdition/install/install_db.php create mode 100644 AvocadoEdition/install/library.check.php create mode 100644 AvocadoEdition/intro.php create mode 100644 AvocadoEdition/inventory/_common.php create mode 100644 AvocadoEdition/inventory/_head.php create mode 100644 AvocadoEdition/inventory/_head.sub.php create mode 100644 AvocadoEdition/inventory/_tail.php create mode 100644 AvocadoEdition/inventory/_tail.sub.php create mode 100644 AvocadoEdition/inventory/detail_item.php create mode 100644 AvocadoEdition/inventory/extend/_sample.config.php create mode 100644 AvocadoEdition/inventory/inc/add_item_form.php create mode 100644 AvocadoEdition/inventory/inc/send_item_form.php create mode 100644 AvocadoEdition/inventory/inventory_update.php create mode 100644 AvocadoEdition/inventory/item_form_update.php create mode 100644 AvocadoEdition/inventory/list.inc.php create mode 100644 AvocadoEdition/inventory/sell_item.php create mode 100644 AvocadoEdition/inventory/send_item.php create mode 100644 AvocadoEdition/inventory/skin/item.skin.php create mode 100644 AvocadoEdition/inventory/skin/list.skin.php create mode 100644 AvocadoEdition/inventory/use_item.php create mode 100644 AvocadoEdition/js/_custom.js create mode 100644 AvocadoEdition/js/autosave.js create mode 100644 AvocadoEdition/js/certify.js create mode 100644 AvocadoEdition/js/common.js create mode 100644 AvocadoEdition/js/html5.js create mode 100644 AvocadoEdition/js/jquery-1.12.3.min.js create mode 100644 AvocadoEdition/js/jquery-1.8.3.min.js create mode 100644 AvocadoEdition/js/jquery.cookie.js create mode 100644 AvocadoEdition/js/jquery.fancylist.js create mode 100644 AvocadoEdition/js/jquery.menu.js create mode 100644 AvocadoEdition/js/jquery.register_form.js create mode 100644 AvocadoEdition/js/jquery.rwdImageMaps.js create mode 100644 AvocadoEdition/js/jquery.sms_paging.js create mode 100644 AvocadoEdition/js/kakaolink.js create mode 100644 AvocadoEdition/js/md5.js create mode 100644 AvocadoEdition/js/modernizr.custom.70111.js create mode 100644 AvocadoEdition/js/swiper.js create mode 100644 AvocadoEdition/js/viewimageresize.js create mode 100644 AvocadoEdition/js/wrest.js create mode 100644 AvocadoEdition/lib/Excel/oleread.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_biffwriter.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_format.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_formula.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_olewriter.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_workbook.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_workbookbig.inc.php create mode 100644 AvocadoEdition/lib/Excel/php_writeexcel/class.writeexcel_worksheet.inc.php create mode 100644 AvocadoEdition/lib/Excel/reader.php create mode 100644 AvocadoEdition/lib/common.lib.php create mode 100644 AvocadoEdition/lib/connect.lib.php create mode 100644 AvocadoEdition/lib/editor.lib.php create mode 100644 AvocadoEdition/lib/icode.lms.lib.php create mode 100644 AvocadoEdition/lib/icode.sms.lib.php create mode 100644 AvocadoEdition/lib/json.lib.php create mode 100644 AvocadoEdition/lib/latest.lib.php create mode 100644 AvocadoEdition/lib/mailer.lib.php create mode 100644 AvocadoEdition/lib/naver_syndi.lib.php create mode 100644 AvocadoEdition/lib/outlogin.lib.php create mode 100644 AvocadoEdition/lib/pbkdf2.compat.php create mode 100644 AvocadoEdition/lib/poll.lib.php create mode 100644 AvocadoEdition/lib/popular.lib.php create mode 100644 AvocadoEdition/lib/register.lib.php create mode 100644 AvocadoEdition/lib/thumbnail.lib.php create mode 100644 AvocadoEdition/lib/visit.lib.php create mode 100644 AvocadoEdition/main.php create mode 100644 AvocadoEdition/member/_common.php create mode 100644 AvocadoEdition/member/_head.php create mode 100644 AvocadoEdition/member/_head.sub.php create mode 100644 AvocadoEdition/member/_tail.php create mode 100644 AvocadoEdition/member/_tail.sub.php create mode 100644 AvocadoEdition/member/closet.php create mode 100644 AvocadoEdition/member/exp.php create mode 100644 AvocadoEdition/member/index.php create mode 100644 AvocadoEdition/member/ready.php create mode 100644 AvocadoEdition/member/skin/list.skin.php create mode 100644 AvocadoEdition/member/skin/ready_list.skin.php create mode 100644 AvocadoEdition/member/skin/viewer.skin.php create mode 100644 AvocadoEdition/member/viewer.php create mode 100644 AvocadoEdition/mypage/_common.php create mode 100644 AvocadoEdition/mypage/_head.php create mode 100644 AvocadoEdition/mypage/_head.sub.php create mode 100644 AvocadoEdition/mypage/_tail.php create mode 100644 AvocadoEdition/mypage/_tail.sub.php create mode 100644 AvocadoEdition/mypage/character/_common.php create mode 100644 AvocadoEdition/mypage/character/_head.php create mode 100644 AvocadoEdition/mypage/character/_head.sub.php create mode 100644 AvocadoEdition/mypage/character/_tail.php create mode 100644 AvocadoEdition/mypage/character/_tail.sub.php create mode 100644 AvocadoEdition/mypage/character/character_delete.php create mode 100644 AvocadoEdition/mypage/character/character_form.php create mode 100644 AvocadoEdition/mypage/character/character_form_update.php create mode 100644 AvocadoEdition/mypage/character/cloest.inc.php create mode 100644 AvocadoEdition/mypage/character/cloest_path_update.php create mode 100644 AvocadoEdition/mypage/character/closet_update.php create mode 100644 AvocadoEdition/mypage/character/index.php create mode 100644 AvocadoEdition/mypage/character/maincharacter_update.php create mode 100644 AvocadoEdition/mypage/character/relation_delete.php create mode 100644 AvocadoEdition/mypage/character/relation_list.php create mode 100644 AvocadoEdition/mypage/character/relation_update.php create mode 100644 AvocadoEdition/mypage/character/status.inc.php create mode 100644 AvocadoEdition/mypage/character/status_update.php create mode 100644 AvocadoEdition/mypage/character/title.inc.php create mode 100644 AvocadoEdition/mypage/character/title_update.php create mode 100644 AvocadoEdition/mypage/character/viewer.php create mode 100644 AvocadoEdition/mypage/index.php create mode 100644 AvocadoEdition/mypage/log/_common.php create mode 100644 AvocadoEdition/mypage/log/_head.php create mode 100644 AvocadoEdition/mypage/log/_head.sub.php create mode 100644 AvocadoEdition/mypage/log/_tail.php create mode 100644 AvocadoEdition/mypage/log/_tail.sub.php create mode 100644 AvocadoEdition/mypage/log/index.php create mode 100644 AvocadoEdition/mypage/log/log_favorite.php create mode 100644 AvocadoEdition/mypage/memo/_common.php create mode 100644 AvocadoEdition/mypage/memo/_head.php create mode 100644 AvocadoEdition/mypage/memo/_head.sub.php create mode 100644 AvocadoEdition/mypage/memo/_tail.php create mode 100644 AvocadoEdition/mypage/memo/_tail.sub.php create mode 100644 AvocadoEdition/mypage/memo/ajax/_common.php create mode 100644 AvocadoEdition/mypage/memo/ajax/ajax_latest_talk.php create mode 100644 AvocadoEdition/mypage/memo/ajax/ajax_prev_talk.php create mode 100644 AvocadoEdition/mypage/memo/index.php create mode 100644 AvocadoEdition/mypage/memo/memo_delete.php create mode 100644 AvocadoEdition/mypage/memo/memo_form.php create mode 100644 AvocadoEdition/mypage/memo/memo_update.php create mode 100644 AvocadoEdition/mypage/memo/memo_view.php create mode 100644 AvocadoEdition/mypage/memo/memo_view.skin.php create mode 100644 AvocadoEdition/mypage/money/_common.php create mode 100644 AvocadoEdition/mypage/money/_head.php create mode 100644 AvocadoEdition/mypage/money/_head.sub.php create mode 100644 AvocadoEdition/mypage/money/_tail.php create mode 100644 AvocadoEdition/mypage/money/_tail.sub.php create mode 100644 AvocadoEdition/mypage/money/index.php create mode 100644 AvocadoEdition/mypage/money/money_update.php create mode 100644 AvocadoEdition/perms.sh create mode 100644 AvocadoEdition/plugin/PHPMailer/LICENSE create mode 100644 AvocadoEdition/plugin/PHPMailer/PHPMailerAutoload.php create mode 100644 AvocadoEdition/plugin/PHPMailer/README.md create mode 100644 AvocadoEdition/plugin/PHPMailer/VERSION create mode 100644 AvocadoEdition/plugin/PHPMailer/changelog.md create mode 100644 AvocadoEdition/plugin/PHPMailer/class.phpmailer.php create mode 100644 AvocadoEdition/plugin/PHPMailer/class.phpmaileroauth.php create mode 100644 AvocadoEdition/plugin/PHPMailer/class.phpmaileroauthgoogle.php create mode 100644 AvocadoEdition/plugin/PHPMailer/class.pop3.php create mode 100644 AvocadoEdition/plugin/PHPMailer/class.smtp.php create mode 100644 AvocadoEdition/plugin/PHPMailer/composer.json create mode 100644 AvocadoEdition/plugin/PHPMailer/composer.lock create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/Callback_function_notes.txt create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/DomainKeys_notes.txt create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/Note_for_SMTP_debugging.txt create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/extending.html create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/faq.html create mode 100644 AvocadoEdition/plugin/PHPMailer/docs/pop3_article.txt create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/DKIM.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/code_generator.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/contactform.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/contents.html create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/contentsutf8.html create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/exceptions.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/gmail.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/gmail_xoauth.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/images/phpmailer.png create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/images/phpmailer_mini.png create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/index.html create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/mail.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/mailing_list.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/pop_before_smtp.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/scripts/XRegExp.js create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/scripts/shAutoloader.js create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/scripts/shBrushPhp.js create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/scripts/shCore.js create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/scripts/shLegacy.js create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/send_file_upload.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/send_multiple_file_upload.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/sendmail.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/signed-mail.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/smtp.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/smtp_check.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/smtp_no_auth.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/ssl_options.phps create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCore.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreDefault.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreDjango.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreEclipse.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreEmacs.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreFadeToGrey.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreMDUltra.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreMidnight.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shCoreRDark.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeAppleScript.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeDefault.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeDjango.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeEclipse.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeEmacs.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeFadeToGrey.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeMDUltra.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeMidnight.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeRDark.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/shThemeVisualStudio.css create mode 100644 AvocadoEdition/plugin/PHPMailer/examples/styles/wrapping.png create mode 100644 AvocadoEdition/plugin/PHPMailer/extras/EasyPeasyICS.php create mode 100644 AvocadoEdition/plugin/PHPMailer/extras/README.md create mode 100644 AvocadoEdition/plugin/PHPMailer/extras/htmlfilter.php create mode 100644 AvocadoEdition/plugin/PHPMailer/extras/ntlm_sasl_client.php create mode 100644 AvocadoEdition/plugin/PHPMailer/get_oauth_token.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-am.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ar.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-az.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-be.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-bg.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-br.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ca.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ch.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-cs.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-cz.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-da.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-de.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-dk.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-el.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-eo.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-es.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-et.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-fa.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-fi.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-fo.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-fr.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-gl.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-he.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-hr.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-hu.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-id.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-it.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ja.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ka.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ko.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-lt.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-lv.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ms.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-nb.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-nl.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-no.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-pl.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-pt.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-pt_br.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ro.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-ru.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-se.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-sk.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-sl.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-sr.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-sv.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-tr.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-uk.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-vi.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-zh.php create mode 100644 AvocadoEdition/plugin/PHPMailer/language/phpmailer.lang-zh_cn.php create mode 100644 AvocadoEdition/plugin/browscap/Browscap.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/backup_template.xml create mode 100644 AvocadoEdition/plugin/editor/cheditor5/cheditor.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.eot create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.woff create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/dialog.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/editarea.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/imageupload.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/imageurl.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/lightbox.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/css/ui.css create mode 100644 AvocadoEdition/plugin/editor/cheditor5/editor.lib.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_col_after.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_col_before.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_cols_after.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_cols_before.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_row_after.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_row_before.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_after.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_before.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/cancel.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/color_picker.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/color_picker.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/color_picker_disable.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/delete.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/delete_cross.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_cell.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_image.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/input.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/input_color.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/map_address.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/paste.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/play.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/preview.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/process.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/reset.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/submit.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/button/upload.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/checked.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_arrow.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_cross.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_hs.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_hv.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_reset.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_tick.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/delete_element.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/delete_table.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/dot.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_code_a.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_code_b.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_a.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_b.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_a.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_b.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/1.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/10.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/11.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/12.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/13.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/14.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/15.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/16.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/17.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/18.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/19.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/2.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/20.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/21.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/22.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/23.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/24.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/25.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/26.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/27.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/28.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/29.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/3.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/30.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/31.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/32.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/33.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/34.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/35.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/36.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/37.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/38.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/39.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/4.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/40.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/41.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/42.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/43.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/44.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/45.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/46.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/47.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/48.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/49.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/5.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/50.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/51.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/52.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/53.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/54.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/55.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/56.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/57.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/58.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/59.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/6.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/60.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/61.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/62.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/63.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/64.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/65.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/66.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/67.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/68.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/69.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/7.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/70.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/71.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/72.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/73.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/74.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/75.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/76.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/77.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/78.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/79.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/8.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/80.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/em/9.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/fullscreen.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/fullscreen_actual.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/add.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/cross-small.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/delete.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/dot.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/loader.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/remove_all.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_align_center.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_align_left.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_align_left_wt.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right_wt.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_resize.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/image_wrap_text.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/magnifier-zoom.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/readonlymode.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/remove_col.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/remove_cols.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/remove_row.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/remove_rows.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/splitter.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/statusbar_bgline.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_cell.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_column.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_row.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_cell.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_column.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_row.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_join.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_join_column.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_join_row.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_split_column.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/table_split_row.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/title_bar_bg.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/title_bar_bg2.gif create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-background.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/toolbar.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/viewmode_code.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/viewmode_preview.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/icons/watermark.png create mode 100644 AvocadoEdition/plugin/editor/cheditor5/imageUpload/_common.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/imageUpload/config.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/imageUpload/delete.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/imageUpload/upload.php create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/color_picker.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/flash.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/flash/ImagePreview.swf create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/flash/chximage.swf create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/google_map.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/icon.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/image.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/image.html5.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/image_url.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/AC_OETags.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/color_picker.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/dialog.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/flash.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/google_map.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/icon.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/image.html5.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/image.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/image_upload_flash.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/image_url.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/link.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/media.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/swfobject.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/symbol.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/table.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/js/table_modify.js create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/link.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/media.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/symbol.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/table.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/popup/table_modify.html create mode 100644 AvocadoEdition/plugin/editor/cheditor5/template.xml create mode 100644 AvocadoEdition/plugin/editor/cheditor5/utils/crossdomain.xml create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2Skin.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2_noframe.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/autosave.editor.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/config.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_in.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_items.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_out.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/editor.lib.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_b1.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_button.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_button_left.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_button_right.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_find_h3.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_help.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_icon_tool.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_line1.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_quote2.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_set.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_text_tool.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/bg_tool2.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_698.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_890.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/ico_extend.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/icon_set.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/ko_KR/btn_set.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/ko_KR/bx_set_110302.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/ko_KR/text_tool_set.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/bg_drag_image.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_cancel.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_confirm.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_confirm2.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_del.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_find.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/img/text_tool_set2.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/HuskyEZCreator.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_General.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_Service.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/SE2BasicCreator.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/SE2M_Configuration.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/jindo.min.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/jindo_component.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/lib/jindo2.all.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/lib/jindo_component.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/smarteditor2.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/js/smarteditor2.min.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/license.txt create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/plugin/hp_SE2M_AttachQuickPhoto.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/_common.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/css/jquery.fileupload-noscript.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/css/jquery.fileupload-ui-noscript.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/css/jquery.fileupload-ui.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/css/jquery.fileupload.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/css/style.css create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/img/delete.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/img/loading.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/img/progressbar.gif create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/img/system_delete.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/index.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/basic.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-1.8.3.min.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-ui.min.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-process.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-ui.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.iframe-transport.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.ui.widget.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/JSON.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/_common.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/index.php create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/XPButtonUploadText_61x22.png create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/fileprogress.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/handlers.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/jquery.swfupload.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.queue.js create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.swf create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/readme.txt create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/release_notes.txt create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/shortcut.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea_ie8.html create mode 100644 AvocadoEdition/plugin/editor/smarteditor2/src_include.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/HTMLPurifier.standalone.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/safeiframe.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Exception.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Validator.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema.ser create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/info.ini create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/EntityLookup/entities.ser create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/YouTube.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/classes/en-x-test.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en-x-test.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en-x-testmini.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Lexer/PH5P.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/CSSDefinition.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.css create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.js create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.php create mode 100644 AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/HTMLDefinition.php create mode 100644 AvocadoEdition/plugin/jqplot/MIT-LICENSE.txt create mode 100644 AvocadoEdition/plugin/jqplot/excanvas.js create mode 100644 AvocadoEdition/plugin/jqplot/excanvas.min.js create mode 100644 AvocadoEdition/plugin/jqplot/jqplot.barRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/jqplot.categoryAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/jqplot.pointLabels.min.js create mode 100644 AvocadoEdition/plugin/jqplot/jquery.jqplot.css create mode 100644 AvocadoEdition/plugin/jqplot/jquery.jqplot.js create mode 100644 AvocadoEdition/plugin/jqplot/jquery.jqplot.min.css create mode 100644 AvocadoEdition/plugin/jqplot/jquery.jqplot.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.min.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.js create mode 100644 AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.min.js create mode 100644 AvocadoEdition/plugin/jquery-ui/datepicker.php create mode 100644 AvocadoEdition/plugin/jquery-ui/style.css create mode 100644 AvocadoEdition/plugin/kcaptcha/_common.php create mode 100644 AvocadoEdition/plugin/kcaptcha/captcha.lib.php create mode 100644 AvocadoEdition/plugin/kcaptcha/fonts/palatino_linotype_bold.png create mode 100644 AvocadoEdition/plugin/kcaptcha/fonts/perpetua_bold.png create mode 100644 AvocadoEdition/plugin/kcaptcha/fonts/times_bold.png create mode 100644 AvocadoEdition/plugin/kcaptcha/img/dot.gif create mode 100644 AvocadoEdition/plugin/kcaptcha/img/reload.gif create mode 100644 AvocadoEdition/plugin/kcaptcha/img/sound.gif create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha.js create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha.lib.php create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha_config.php create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha_image.php create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha_mp3.php create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha_result.php create mode 100644 AvocadoEdition/plugin/kcaptcha/kcaptcha_session.php create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/0.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/1.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/2.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/3.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/4.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/5.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/6.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/7.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/8.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/basic/9.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/0.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/1.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/2.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/3.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/4.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/5.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/6.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/7.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/8.mp3 create mode 100644 AvocadoEdition/plugin/kcaptcha/mp3/jmoon/9.mp3 create mode 100644 AvocadoEdition/plugin/sns/_common.php create mode 100644 AvocadoEdition/plugin/sns/facebook/_common.php create mode 100644 AvocadoEdition/plugin/sns/facebook/callback.php create mode 100644 AvocadoEdition/plugin/sns/facebook/changelog.md create mode 100644 AvocadoEdition/plugin/sns/facebook/composer.json create mode 100644 AvocadoEdition/plugin/sns/facebook/readme.md create mode 100644 AvocadoEdition/plugin/sns/facebook/src/base_facebook.php create mode 100644 AvocadoEdition/plugin/sns/facebook/src/facebook.php create mode 100644 AvocadoEdition/plugin/sns/facebook/src/fb_ca_chain_bundle.crt create mode 100644 AvocadoEdition/plugin/sns/facebook/tests/bootstrap.php create mode 100644 AvocadoEdition/plugin/sns/facebook/tests/tests.php create mode 100644 AvocadoEdition/plugin/sns/icon/facebook.png create mode 100644 AvocadoEdition/plugin/sns/icon/facebook_cmt.png create mode 100644 AvocadoEdition/plugin/sns/icon/facebook_off.png create mode 100644 AvocadoEdition/plugin/sns/icon/gplus.png create mode 100644 AvocadoEdition/plugin/sns/icon/gplus_off.png create mode 100644 AvocadoEdition/plugin/sns/icon/kakaotalk.png create mode 100644 AvocadoEdition/plugin/sns/icon/kakaotalk_off.png create mode 100644 AvocadoEdition/plugin/sns/icon/twitter.png create mode 100644 AvocadoEdition/plugin/sns/icon/twitter_cmt.png create mode 100644 AvocadoEdition/plugin/sns/icon/twitter_off.png create mode 100644 AvocadoEdition/plugin/sns/twitter/LICENSE create mode 100644 AvocadoEdition/plugin/sns/twitter/README.md create mode 100644 AvocadoEdition/plugin/sns/twitter/_common.php create mode 100644 AvocadoEdition/plugin/sns/twitter/callback-sample.php create mode 100644 AvocadoEdition/plugin/sns/twitter/callback.php create mode 100644 AvocadoEdition/plugin/sns/twitter/clearsessions.php create mode 100644 AvocadoEdition/plugin/sns/twitter/config-sample.php create mode 100644 AvocadoEdition/plugin/sns/twitter/connect.php create mode 100644 AvocadoEdition/plugin/sns/twitter/html.inc create mode 100644 AvocadoEdition/plugin/sns/twitter/images/darker.png create mode 100644 AvocadoEdition/plugin/sns/twitter/images/lighter.png create mode 100644 AvocadoEdition/plugin/sns/twitter/index.php create mode 100644 AvocadoEdition/plugin/sns/twitter/redirect.php create mode 100644 AvocadoEdition/plugin/sns/twitter/twitterconfig.php create mode 100644 AvocadoEdition/plugin/sns/twitter/twitteroauth/OAuth.php create mode 100644 AvocadoEdition/plugin/sns/twitter/twitteroauth/twitteroauth.php create mode 100644 AvocadoEdition/plugin/sns/view.sns.skin.php create mode 100644 AvocadoEdition/plugin/sns/view_comment_list.sns.skin.php create mode 100644 AvocadoEdition/plugin/sns/view_comment_write.sns.skin.php create mode 100644 AvocadoEdition/plugin/syndi/_common.php create mode 100644 AvocadoEdition/plugin/syndi/ping.php create mode 100644 AvocadoEdition/shop/_ajax.shop_item.php create mode 100644 AvocadoEdition/shop/_ajax.shop_update.php create mode 100644 AvocadoEdition/shop/_common.php create mode 100644 AvocadoEdition/shop/_head.php create mode 100644 AvocadoEdition/shop/_head.sub.php create mode 100644 AvocadoEdition/shop/_tail.php create mode 100644 AvocadoEdition/shop/_tail.sub.php create mode 100644 AvocadoEdition/shop/index.php create mode 100644 AvocadoEdition/shop/skin/shop.item.skin.php create mode 100644 AvocadoEdition/shop/skin/shop.result.skin.php create mode 100644 AvocadoEdition/shop/skin/shop.skin.php create mode 100644 AvocadoEdition/skin/banner/basic/banner.skin.php create mode 100644 AvocadoEdition/skin/banner/basic/style.css create mode 100644 AvocadoEdition/skin/board/basic/img/btn_close.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_file.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_hot.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_img.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_link.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_mobile.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_movie.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_new.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_reply.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_secret.gif create mode 100644 AvocadoEdition/skin/board/basic/img/icon_sound.gif create mode 100644 AvocadoEdition/skin/board/basic/list.skin.php create mode 100644 AvocadoEdition/skin/board/basic/style.css create mode 100644 AvocadoEdition/skin/board/basic/view.skin.php create mode 100644 AvocadoEdition/skin/board/basic/view_comment.skin.php create mode 100644 AvocadoEdition/skin/board/basic/write.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/delete_comment.tail.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/img/btn_close.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_file.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_hot.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_img.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_link.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_mobile.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_movie.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_new.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_reply.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_secret.gif create mode 100644 AvocadoEdition/skin/board/caculate/img/icon_sound.gif create mode 100644 AvocadoEdition/skin/board/caculate/list.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/style.css create mode 100644 AvocadoEdition/skin/board/caculate/view.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/view_comment.php create mode 100644 AvocadoEdition/skin/board/caculate/view_comment.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/write.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/write_comment.php create mode 100644 AvocadoEdition/skin/board/caculate/write_comment_update.skin.php create mode 100644 AvocadoEdition/skin/board/caculate/write_update.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/_action.data.php create mode 100644 AvocadoEdition/skin/board/mmb/_common.php create mode 100644 AvocadoEdition/skin/board/mmb/action/log.H.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/action/log.S.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/action/log.item.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/ajax/_common.php create mode 100644 AvocadoEdition/skin/board/mmb/ajax/add_favorite.php create mode 100644 AvocadoEdition/skin/board/mmb/delete_comment.tail.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/emoticon_list.php create mode 100644 AvocadoEdition/skin/board/mmb/img/d1.png create mode 100644 AvocadoEdition/skin/board/mmb/img/d2.png create mode 100644 AvocadoEdition/skin/board/mmb/img/d3.png create mode 100644 AvocadoEdition/skin/board/mmb/img/d4.png create mode 100644 AvocadoEdition/skin/board/mmb/img/d5.png create mode 100644 AvocadoEdition/skin/board/mmb/img/d6.png create mode 100644 AvocadoEdition/skin/board/mmb/img/img_lock.png create mode 100644 AvocadoEdition/skin/board/mmb/img/no_image.png create mode 100644 AvocadoEdition/skin/board/mmb/js/load.board.js create mode 100644 AvocadoEdition/skin/board/mmb/list.log.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/list.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/style.css create mode 100644 AvocadoEdition/skin/board/mmb/view.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/view_comment.php create mode 100644 AvocadoEdition/skin/board/mmb/view_comment.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/write.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/write_comment.php create mode 100644 AvocadoEdition/skin/board/mmb/write_comment_update.skin.php create mode 100644 AvocadoEdition/skin/board/mmb/write_update.inc.php create mode 100644 AvocadoEdition/skin/board/mmb/write_update.skin.php create mode 100644 AvocadoEdition/skin/board/qna/_common.php create mode 100644 AvocadoEdition/skin/board/qna/ajax.filter.php create mode 100644 AvocadoEdition/skin/board/qna/img/a_face.gif create mode 100644 AvocadoEdition/skin/board/qna/img/best.gif create mode 100644 AvocadoEdition/skin/board/qna/img/btn_cencel.gif create mode 100644 AvocadoEdition/skin/board/qna/img/btn_close.gif create mode 100644 AvocadoEdition/skin/board/qna/img/btn_comment_delete.gif create mode 100644 AvocadoEdition/skin/board/qna/img/btn_write.gif create mode 100644 AvocadoEdition/skin/board/qna/img/comment.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_home.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_list.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_mail.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_name.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_pass.gif create mode 100644 AvocadoEdition/skin/board/qna/img/e_search.gif create mode 100644 AvocadoEdition/skin/board/qna/img/g_face1.gif create mode 100644 AvocadoEdition/skin/board/qna/img/g_face2.gif create mode 100644 AvocadoEdition/skin/board/qna/img/g_face3.gif create mode 100644 AvocadoEdition/skin/board/qna/img/g_face4.gif create mode 100644 AvocadoEdition/skin/board/qna/img/g_face5.gif create mode 100644 AvocadoEdition/skin/board/qna/img/i_notice.gif create mode 100644 AvocadoEdition/skin/board/qna/img/i_write.gif create mode 100644 AvocadoEdition/skin/board/qna/img/icon_file.gif create mode 100644 AvocadoEdition/skin/board/qna/img/icon_hot.gif create mode 100644 AvocadoEdition/skin/board/qna/img/icon_new.gif create mode 100644 AvocadoEdition/skin/board/qna/img/icon_secret.gif create mode 100644 AvocadoEdition/skin/board/qna/img/icon_secret2.gif create mode 100644 AvocadoEdition/skin/board/qna/img/line.gif create mode 100644 AvocadoEdition/skin/board/qna/img/line2.gif create mode 100644 AvocadoEdition/skin/board/qna/img/no_image.jpg create mode 100644 AvocadoEdition/skin/board/qna/img/reply.gif create mode 100644 AvocadoEdition/skin/board/qna/img/search.gif create mode 100644 AvocadoEdition/skin/board/qna/inc.list_main.php create mode 100644 AvocadoEdition/skin/board/qna/list.skin.php create mode 100644 AvocadoEdition/skin/board/qna/password.php create mode 100644 AvocadoEdition/skin/board/qna/style.css create mode 100644 AvocadoEdition/skin/board/qna/view.skin.php create mode 100644 AvocadoEdition/skin/board/qna/view_comment.php create mode 100644 AvocadoEdition/skin/board/qna/view_comment.skin.php create mode 100644 AvocadoEdition/skin/board/qna/view_skin_js.php create mode 100644 AvocadoEdition/skin/board/qna/write.php create mode 100644 AvocadoEdition/skin/board/qna/write.skin.php create mode 100644 AvocadoEdition/skin/board/qna/write_comment_update.php create mode 100644 AvocadoEdition/skin/board/qna/write_comment_update.skin.php create mode 100644 AvocadoEdition/skin/board/qna/write_update.skin.php create mode 100644 AvocadoEdition/skin/connect/basic/connect.skin.php create mode 100644 AvocadoEdition/skin/connect/basic/current_connect.skin.php create mode 100644 AvocadoEdition/skin/connect/basic/style.css create mode 100644 AvocadoEdition/skin/content/basic/content.skin.php create mode 100644 AvocadoEdition/skin/content/basic/style.css create mode 100644 AvocadoEdition/skin/faq/basic/list.skin.php create mode 100644 AvocadoEdition/skin/faq/basic/style.css create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_file.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_hot.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_img.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_link.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_mobile.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_more.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_movie.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_new.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_reply.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_secret.gif create mode 100644 AvocadoEdition/skin/latest/basic/img/icon_sound.gif create mode 100644 AvocadoEdition/skin/latest/basic/latest.skin.php create mode 100644 AvocadoEdition/skin/latest/basic/style.css create mode 100644 AvocadoEdition/skin/latest/rolling/latest.skin.php create mode 100644 AvocadoEdition/skin/latest/rolling/style.css create mode 100644 AvocadoEdition/skin/member/basic/formmail.skin.php create mode 100644 AvocadoEdition/skin/member/basic/img/bak_admin_login_top_pattern.png create mode 100644 AvocadoEdition/skin/member/basic/img/zip_ico_up.gif create mode 100644 AvocadoEdition/skin/member/basic/login.admin.skin.php create mode 100644 AvocadoEdition/skin/member/basic/login.skin.php create mode 100644 AvocadoEdition/skin/member/basic/login_check.skin.php create mode 100644 AvocadoEdition/skin/member/basic/member_confirm.skin.php create mode 100644 AvocadoEdition/skin/member/basic/memo.skin.php create mode 100644 AvocadoEdition/skin/member/basic/memo_form.skin.php create mode 100644 AvocadoEdition/skin/member/basic/memo_view.skin.php create mode 100644 AvocadoEdition/skin/member/basic/password.skin.php create mode 100644 AvocadoEdition/skin/member/basic/password_lost.skin.php create mode 100644 AvocadoEdition/skin/member/basic/point.skin.php create mode 100644 AvocadoEdition/skin/member/basic/profile.skin.php create mode 100644 AvocadoEdition/skin/member/basic/register.skin.php create mode 100644 AvocadoEdition/skin/member/basic/register_form.skin.php create mode 100644 AvocadoEdition/skin/member/basic/register_result.skin.php create mode 100644 AvocadoEdition/skin/member/basic/scrap.skin.php create mode 100644 AvocadoEdition/skin/member/basic/scrap_popin.skin.php create mode 100644 AvocadoEdition/skin/member/basic/style.admin.css create mode 100644 AvocadoEdition/skin/member/basic/style.css create mode 100644 AvocadoEdition/skin/new/basic/new.skin.php create mode 100644 AvocadoEdition/skin/new/basic/style.css create mode 100644 AvocadoEdition/skin/outlogin/basic/outlogin.skin.1.php create mode 100644 AvocadoEdition/skin/outlogin/basic/outlogin.skin.2.php create mode 100644 AvocadoEdition/skin/outlogin/basic/style.css create mode 100644 AvocadoEdition/skin/poll/basic/poll.skin.php create mode 100644 AvocadoEdition/skin/poll/basic/poll_result.skin.php create mode 100644 AvocadoEdition/skin/poll/basic/style.css create mode 100644 AvocadoEdition/skin/popular/basic/popular.skin.php create mode 100644 AvocadoEdition/skin/popular/basic/style.css create mode 100644 AvocadoEdition/skin/qa/basic/img/btn_close.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_answer.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_file.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_hot.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_img.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_link.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_mobile.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_movie.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_new.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_secret.gif create mode 100644 AvocadoEdition/skin/qa/basic/img/icon_sound.gif create mode 100644 AvocadoEdition/skin/qa/basic/list.skin.php create mode 100644 AvocadoEdition/skin/qa/basic/style.css create mode 100644 AvocadoEdition/skin/qa/basic/view.answer.skin.php create mode 100644 AvocadoEdition/skin/qa/basic/view.answerform.skin.php create mode 100644 AvocadoEdition/skin/qa/basic/view.skin.php create mode 100644 AvocadoEdition/skin/qa/basic/write.skin.php create mode 100644 AvocadoEdition/skin/search/basic/search.skin.php create mode 100644 AvocadoEdition/skin/search/basic/style.css create mode 100644 AvocadoEdition/skin/visit/basic/style.css create mode 100644 AvocadoEdition/skin/visit/basic/visit.skin.php create mode 100644 AvocadoEdition/tail.php create mode 100644 AvocadoEdition/tail.sub.php create mode 100644 AvocadoEdition/templete/txt.bgm.php create mode 100644 AvocadoEdition/templete/txt.join.php create mode 100644 AvocadoEdition/templete/txt.login.php create mode 100644 AvocadoEdition/templete/txt.logout.php create mode 100644 AvocadoEdition/templete/txt.mypage.php create mode 100644 AvocadoEdition/templete/txt.outlogin.php create mode 100644 AvocadoEdition/templete/txt.twitter.php create mode 100644 AvocadoEdition/templete/txt.visual.php create mode 100644 AvocadoEdition/theme/basic/_common.php create mode 100644 AvocadoEdition/theme/basic/couple/list.skin.php create mode 100644 AvocadoEdition/theme/basic/css/couple.css create mode 100644 AvocadoEdition/theme/basic/css/default.css create mode 100644 AvocadoEdition/theme/basic/css/emoticon.css create mode 100644 AvocadoEdition/theme/basic/css/enter.css create mode 100644 AvocadoEdition/theme/basic/css/index.css create mode 100644 AvocadoEdition/theme/basic/css/intro.css create mode 100644 AvocadoEdition/theme/basic/css/login.css create mode 100644 AvocadoEdition/theme/basic/css/main.css create mode 100644 AvocadoEdition/theme/basic/css/member.css create mode 100644 AvocadoEdition/theme/basic/css/mypage.css create mode 100644 AvocadoEdition/theme/basic/css/shop.css create mode 100644 AvocadoEdition/theme/basic/css/style.css create mode 100644 AvocadoEdition/theme/basic/enter.php create mode 100644 AvocadoEdition/theme/basic/extend/theme.extend.php create mode 100644 AvocadoEdition/theme/basic/group.php create mode 100644 AvocadoEdition/theme/basic/head.php create mode 100644 AvocadoEdition/theme/basic/head.sub.php create mode 100644 AvocadoEdition/theme/basic/index.php create mode 100644 AvocadoEdition/theme/basic/inventory/item.skin.php create mode 100644 AvocadoEdition/theme/basic/inventory/list.skin.php create mode 100644 AvocadoEdition/theme/basic/main.php create mode 100644 AvocadoEdition/theme/basic/member/list.skin.php create mode 100644 AvocadoEdition/theme/basic/member/ready_list.skin.php create mode 100644 AvocadoEdition/theme/basic/member/viewer.skin.php create mode 100644 AvocadoEdition/theme/basic/readme.txt create mode 100644 AvocadoEdition/theme/basic/screenshot.png create mode 100644 AvocadoEdition/theme/basic/shop/shop.item.skin.php create mode 100644 AvocadoEdition/theme/basic/shop/shop.result.skin.php create mode 100644 AvocadoEdition/theme/basic/shop/shop.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/btn_cmt.png create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/chk.png create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/close_btn.png create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/icon_lock.png create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/icon_mobile.gif create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/icon_reply.gif create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/img/icon_secret.gif create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/list.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/style.css create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/view.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/view_comment.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/board/basic/write.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/content/basic/content.skin.php create mode 100644 AvocadoEdition/theme/basic/skin/content/basic/style.css create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/basic/img/chk.png create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/basic/img/info_edit.png create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/basic/outlogin.skin.1.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/basic/outlogin.skin.2.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/basic/style.css create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_basic/img/chk.png create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_basic/outlogin.skin.1.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_basic/outlogin.skin.2.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_basic/style.css create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_side/img/chk.png create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_side/outlogin.skin.1.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_side/outlogin.skin.2.php create mode 100644 AvocadoEdition/theme/basic/skin/outlogin/shop_side/style.css create mode 100644 AvocadoEdition/theme/basic/tail.php create mode 100644 AvocadoEdition/theme/basic/tail.sub.php diff --git a/AvocadoEdition/_common.php b/AvocadoEdition/_common.php new file mode 100644 index 0000000..2ed94c3 --- /dev/null +++ b/AvocadoEdition/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/_head.php b/AvocadoEdition/_head.php new file mode 100644 index 0000000..79e267f --- /dev/null +++ b/AvocadoEdition/_head.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/AvocadoEdition/_tail.php b/AvocadoEdition/_tail.php new file mode 100644 index 0000000..ae47c3b --- /dev/null +++ b/AvocadoEdition/_tail.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/_common.php b/AvocadoEdition/adm/_common.php new file mode 100644 index 0000000..cd443b1 --- /dev/null +++ b/AvocadoEdition/adm/_common.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/action_delete.php b/AvocadoEdition/adm/action_delete.php new file mode 100644 index 0000000..97d7b91 --- /dev/null +++ b/AvocadoEdition/adm/action_delete.php @@ -0,0 +1,29 @@ += $member['mb_level']) + alert("자신보다 권한이 높거나 같은 회원은 삭제할 수 없습니다."); + +check_token(); + +// 회원자료 삭제 +member_delete($mb['mb_id']); + +if ($url) + goto_url("{$url}?{$qstr}&w=u&mb_id=$mb_id"); +else + goto_url("./action_list.php?{$qstr}"); +?> diff --git a/AvocadoEdition/adm/action_list.php b/AvocadoEdition/adm/action_list.php new file mode 100644 index 0000000..b5c19d1 --- /dev/null +++ b/AvocadoEdition/adm/action_list.php @@ -0,0 +1,202 @@ +['.$row['gr_subject'].'] '.$row['bo_subject'].''; +} + + +$write_table = $g5['write_prefix'] . $s_board; + +$qstr .= "&s_board=".$s_board."&s_date=".$s_date."&e_date=".$e_date; + +if(!$s_date) $s_date = date('Y-m-d', strtotime("last Monday")); +if(!$e_date) $e_date = date('Y-m-d', strtotime("next Sunday")); + +// 일단 짜는 것 부터 시작하자. +// 회원 정렬 부터 시작한다./ + + +$sql_common = " from {$g5['member_table']} mb LEFT JOIN (select *, count(if(wr_id = wr_parent, wr_id, null)) as wr_log, count(if(wr_id != wr_parent, wr_id, null)) as wr_cm from {$g5['board_new_table']} where bo_table = '{$s_board}' and bn_datetime >= '$s_date' and bn_datetime <= '$e_date' group by mb_id ) bo ON mb.mb_id = bo.mb_id "; +$sql_search = " where mb.mb_level > 1 and mb.mb_leave_date = '' and mb.mb_id != '{$config['cf_admin']}' and mb.ch_id != '' and mb.mb_level > 1 "; + +if (!$sst) { + $sst = "mb.mb_datetime"; + $sod = "asc"; +} + +$sql_order = " order by {$sst} {$sod} "; + +$sql = " select count(*) as cnt {$sql_common} {$sql_search}"; + + +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) +$page_rows = 20; + +$total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 +$from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + +$g5['title'] = '활동량 관리'; +include_once('./admin.head.php'); +include_once(G5_PLUGIN_PATH.'/jquery-ui/datepicker.php'); + + +$sql = " select mb.mb_id, mb.mb_name, mb.ch_id, mb.mb_today_login, mb.mb_error_content, bo.wr_log, bo.wr_cm, mb.mb_error_cnt {$sql_common} {$sql_search} {$sql_order} limit {$from_record}, $page_rows"; + + +$result = sql_query($sql); +$colspan = 10; + +?> + +
+ + 총 회원 수 명 +
+ +
+ +
+ 게시판 지정  + + +     + + 기간별검색  + + ~ + +
+ + +
+ +
+ +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "; + ?> + +
목록
아이디닉네임대표캐릭터로그덧글최종 접속누적경고경고내용관리
+ 회 + + + + + +
자료가 없습니다.
+
+ +
+ +
+ +
+ + + + + + diff --git a/AvocadoEdition/adm/action_list_update.php b/AvocadoEdition/adm/action_list_update.php new file mode 100644 index 0000000..63c25f1 --- /dev/null +++ b/AvocadoEdition/adm/action_list_update.php @@ -0,0 +1,30 @@ + diff --git a/AvocadoEdition/adm/action_reply.php b/AvocadoEdition/adm/action_reply.php new file mode 100644 index 0000000..3801854 --- /dev/null +++ b/AvocadoEdition/adm/action_reply.php @@ -0,0 +1,58 @@ + + + + + '{$fr_date}' and mu_datetime < '{$to_date}' and (mu_id > '5599' or mu_id < '5370') and (mu_id > '6576' or mu_id < '6369') and mb_id = '{$mb_id}'"); + + +for ($j=0; $row=sql_fetch_array($log); $j++) { + $log2 = sql_query ("select mu_id from g5_mmb_upload where mu_id < '{$row['mu_id']}' order by mu_id desc limit 0, 3"); + + for ($k=0; $row2=sql_fetch_array($log2); $k++) { + $comment_log = sql_fetch("select mu_id, count(*) as cnt from g5_mmb_comment where mu_id = '{$row2['mu_id']}' and mb_id = '{$mb_id}'"); + + if($comment_log['cnt'] == '0') { + if($reply_count[$reply_index]['mc_no_count'] == "") $reply_count[$reply_index]['mc_no_count'] = 0; + + if($reply_count[$reply_index]['mu_id'] != $row['mu_id']) { + $reply_index++; + $reply_count[$reply_index]['mu_id'] = $row['mu_id']; + } + $reply_count[$reply_index]['mc_no_count']++; + + } + } +} +?> + +

+ + 번 로그 (/3) + +

+ + + diff --git a/AvocadoEdition/adm/admin.ajax.js b/AvocadoEdition/adm/admin.ajax.js new file mode 100644 index 0000000..eae289a --- /dev/null +++ b/AvocadoEdition/adm/admin.ajax.js @@ -0,0 +1,3 @@ +$(function() { + +}); diff --git a/AvocadoEdition/adm/admin.head.php b/AvocadoEdition/adm/admin.head.php new file mode 100644 index 0000000..324efef --- /dev/null +++ b/AvocadoEdition/adm/admin.head.php @@ -0,0 +1,125 @@ +"; + for($i=1; $i'.$menu[$key][$i][1].''; + + $auth_menu[$menu[$key][$i][0]] = $menu[$key][$i][1]; + } + $str .= ""; + + return $str; +} +?> + + + +
+ + + + +
+ + + +
diff --git a/AvocadoEdition/adm/admin.js b/AvocadoEdition/adm/admin.js new file mode 100644 index 0000000..4d971c3 --- /dev/null +++ b/AvocadoEdition/adm/admin.js @@ -0,0 +1,129 @@ +function check_all(f) +{ + var chk = document.getElementsByName("chk[]"); + + for (i=0; i'); + + $f.find("input[name=token]").val(token); + + return true; + }); +}); \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.lib.php b/AvocadoEdition/adm/admin.lib.php new file mode 100644 index 0000000..1e2d210 --- /dev/null +++ b/AvocadoEdition/adm/admin.lib.php @@ -0,0 +1,475 @@ +\n"; + for ($i=0; $i선택"; + if(preg_match('#^theme/(.+)$#', $skins[$i], $match)) + $text = '(테마) '.$match[1]; + else + $text = $skins[$i]; + + $str .= option_selected($skins[$i], $selected, $text); + } + $str .= ""; + return $str; +} + +// 모바일 스킨디렉토리를 SELECT 형식으로 얻음 +function get_mobile_skin_select($skin_gubun, $id, $name, $selected='', $event='') +{ + global $config; + + $skins = array(); + + if(defined('G5_THEME_PATH') && $config['cf_theme']) { + $dirs = get_skin_dir($skin_gubun, G5_THEME_MOBILE_PATH.'/'.G5_SKIN_DIR); + if(!empty($dirs)) { + foreach($dirs as $dir) { + $skins[] = 'theme/'.$dir; + } + } + } + + $skins = array_merge($skins, get_skin_dir($skin_gubun, G5_MOBILE_PATH.'/'.G5_SKIN_DIR)); + + $str = ""; + return $str; +} + + +// 스킨경로를 얻는다 +function get_skin_dir($skin, $skin_path=G5_SKIN_PATH) +{ + global $g5; + + $result_array = array(); + + $dirname = $skin_path.'/'.$skin.'/'; + if(!is_dir($dirname)) + return; + + $handle = opendir($dirname); + while ($file = readdir($handle)) { + if($file == '.'||$file == '..') continue; + + if (is_dir($dirname.$file)) $result_array[] = $file; + } + closedir($handle); + sort($result_array); + + return $result_array; +} + + +// 테마 +function get_theme_dir() +{ + $result_array = array(); + + $dirname = G5_PATH.'/'.G5_THEME_DIR.'/'; + $handle = opendir($dirname); + while ($file = readdir($handle)) { + if($file == '.'||$file == '..') continue; + + if (is_dir($dirname.$file)) { + $theme_path = $dirname.$file; + if(is_file($theme_path.'/index.php') && is_file($theme_path.'/head.php') && is_file($theme_path.'/tail.php')) + $result_array[] = $file; + } + } + closedir($handle); + natsort($result_array); + + return $result_array; +} + +// 테마디렉토리를 SELECT 형식으로 얻음 +function get_theme_select($id, $name, $selected='', $event='') +{ + global $config; + + $theme = array(); + $theme = array_merge($theme, get_theme_dir()); + + $str = ""; + return $str; +} + + +// 테마정보 +function get_theme_info($dir) +{ + $info = array(); + $path = G5_PATH.'/'.G5_THEME_DIR.'/'.$dir; + + if(is_dir($path)) { + $screenshot = $path.'/screenshot.png'; + if(is_file($screenshot)) { + $size = @getimagesize($screenshot); + + if($size[2] == 3) + $screenshot_url = str_replace(G5_PATH, G5_URL, $screenshot); + } + + $info['screenshot'] = $screenshot_url; + + $text = $path.'/readme.txt'; + if(is_file($text)) { + $content = file($text, false); + $content = array_map('trim', $content); + + preg_match('#^Theme Name:(.+)$#i', $content[0], $m0); + preg_match('#^Theme URI:(.+)$#i', $content[1], $m1); + preg_match('#^Maker:(.+)$#i', $content[2], $m2); + preg_match('#^Maker URI:(.+)$#i', $content[3], $m3); + preg_match('#^Version:(.+)$#i', $content[4], $m4); + preg_match('#^Detail:(.+)$#i', $content[5], $m5); + preg_match('#^License:(.+)$#i', $content[6], $m6); + preg_match('#^License URI:(.+)$#i', $content[7], $m7); + + $info['theme_name'] = trim($m0[1]); + $info['theme_uri'] = trim($m1[1]); + $info['maker'] = trim($m2[1]); + $info['maker_uri'] = trim($m3[1]); + $info['version'] = trim($m4[1]); + $info['detail'] = trim($m5[1]); + $info['license'] = trim($m6[1]); + $info['license_uri'] = trim($m7[1]); + } + + if(!$info['theme_name']) + $info['theme_name'] = $dir; + } + + return $info; +} + + +// 테마설정 정보 +function get_theme_config_value($dir, $key='*') +{ + $tconfig = array(); + + $theme_config_file = G5_PATH.'/'.G5_THEME_DIR.'/'.$dir.'/theme.config.php'; + if(is_file($theme_config_file)) { + include($theme_config_file); + + if($key == '*') { + $tconfig = $theme_config; + } else { + $keys = array_map('trim', explode(',', $key)); + foreach($keys as $v) { + $tconfig[$v] = isset($theme_config[$v]) ? trim($theme_config[$v]) : ''; + } + } + } + + return $tconfig; +} + + + +// 회원권한을 SELECT 형식으로 얻음 +function get_member_level_select($name, $start_id=0, $end_id=10, $selected="", $event="") +{ + global $g5; + + $level_name[1] = "방문자"; + $level_name[2] = "일반멤버"; + $level_name[10] = "운영자"; + + $str = "\n'; + return $str; +} + +// 권한 검사 +function auth_check($auth, $attr, $return=false) +{ + global $is_admin; + + if ($is_admin == 'super') return; + + if (!trim($auth)) { + $msg = '이 메뉴에는 접근 권한이 없습니다.\\n\\n접근 권한은 최고관리자만 부여할 수 있습니다.'; + if($return) + return $msg; + else + alert($msg); + } + + $attr = strtolower($attr); + + if (!strstr($auth, $attr)) { + if ($attr == 'r') { + $msg = '읽을 권한이 없습니다.'; + if($return) + return $msg; + else + alert($msg); + } else if ($attr == 'w') { + $msg = '입력, 추가, 생성, 수정 권한이 없습니다.'; + if($return) + return $msg; + else + alert($msg); + } else if ($attr == 'd') { + $msg = '삭제 권한이 없습니다.'; + if($return) + return $msg; + else + alert($msg); + } else { + $msg = '속성이 잘못 되었습니다.'; + if($return) + return $msg; + else + alert($msg); + } + } +} + + +// 작업아이콘 출력 +function icon($act, $link='', $target='_parent') +{ + global $g5; + + $img = array('입력'=>'insert', '추가'=>'insert', '생성'=>'insert', '수정'=>'modify', '삭제'=>'delete', '이동'=>'move', '그룹'=>'move', '보기'=>'view', '미리보기'=>'view', '복사'=>'copy'); + $icon = ''; + if ($link) + $s = ''.$icon.''; + else + $s = $icon; + return $s; +} + + +// rm -rf 옵션 : exec(), system() 함수를 사용할 수 없는 서버 또는 win32용 대체 +// www.php.net 참고 : pal at degerstrom dot com +function rm_rf($file) +{ + if (file_exists($file)) { + if (is_dir($file)) { + $handle = opendir($file); + while($filename = readdir($handle)) { + if ($filename != '.' && $filename != '..') + rm_rf($file.'/'.$filename); + } + closedir($handle); + + @chmod($file, G5_DIR_PERMISSION); + @rmdir($file); + } else { + @chmod($file, G5_FILE_PERMISSION); + @unlink($file); + } + } +} + + + +// 출력순서 +function order_select($fld, $sel='') +{ + $s = ''; + + return $s; +} + +// 불법접근을 막도록 토큰을 생성하면서 토큰값을 리턴 +function get_admin_token() +{ + $token = md5(uniqid(rand(), true)); + set_session('ss_admin_token', $token); + + return $token; +} + + +// POST로 넘어온 토큰과 세션에 저장된 토큰 비교 +function check_admin_token() +{ + $token = get_session('ss_admin_token'); + set_session('ss_admin_token', ''); + + if(!$token || !$_REQUEST['token'] || $token != $_REQUEST['token']) + alert('올바른 방법으로 이용해 주십시오.', G5_URL); + + return true; +} + +// 관리자 페이지 referer 체크 +function admin_referer_check($return=false) +{ + $referer = trim($_SERVER['HTTP_REFERER']); + if(!$referer) { + $msg = '정보가 올바르지 않습니다.'; + + if($return) + return $msg; + else + alert($msg, G5_URL); + } + + $p = @parse_url($referer); + $host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']); + + if($host != $p['host']) { + $msg = '올바른 방법으로 이용해 주십시오.'; + + if($return) + return $msg; + else + alert($msg, G5_URL); + } +} + +// 접근 권한 검사 +if (!$member['mb_id']) +{ + goto_url(G5_BBS_URL.'/login.php?url=' . urlencode(G5_ADMIN_URL)); +} +else if ($is_admin != 'super') +{ + $auth = array(); + $sql = " select au_menu, au_auth from {$g5['auth_table']} where mb_id = '{$member['mb_id']}' "; + $result = sql_query($sql); + for($i=0; $row=sql_fetch_array($result); $i++) + { + $auth[$row['au_menu']] = $row['au_auth']; + } + + if (!$i) + { + goto_url(G5_URL); + } +} + +// 관리자의 아이피, 브라우저와 다르다면 세션을 끊고 관리자에게 메일을 보낸다. +$admin_key = md5($member['mb_datetime'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); +if (get_session('ss_mb_key') !== $admin_key) { + + session_destroy(); + + include_once(G5_LIB_PATH.'/mailer.lib.php'); + // 메일 알림 + mailer($member['mb_nick'], $member['mb_email'], $member['mb_email'], 'XSS 공격 알림', $_SERVER['REMOTE_ADDR'].' 아이피로 XSS 공격이 있었습니다.\n\n관리자 권한을 탈취하려는 접근이므로 주의하시기 바랍니다.\n\n해당 아이피는 차단하시고 의심되는 게시물이 있는지 확인하시기 바랍니다.\n\n'.G5_URL, 0); + + alert_close('정상적으로 로그인하여 접근하시기 바랍니다.'); +} + +@ksort($auth); + +// 가변 메뉴 +unset($auth_menu); +unset($menu); +unset($amenu); +$tmp = dir(G5_ADMIN_PATH); +while ($entry = $tmp->read()) { + if (!preg_match('/^admin.menu([0-9]{3}).*\.php$/', $entry, $m)) + continue; // 파일명이 menu 으로 시작하지 않으면 무시한다. + + $amenu[$m[1]] = $entry; + include_once(G5_ADMIN_PATH.'/'.$entry); +} +@ksort($amenu); + +$arr_query = array(); +if (isset($sst)) $arr_query[] = 'sst='.$sst; +if (isset($sod)) $arr_query[] = 'sod='.$sod; +if (isset($sfl)) $arr_query[] = 'sfl='.$sfl; +if (isset($stx)) $arr_query[] = 'stx='.$stx; +if (isset($page)) $arr_query[] = 'page='.$page; +$qstr = implode("&", $arr_query); + +// 관리자에서는 추가 스크립트는 사용하지 않는다. +//$config['cf_add_script'] = ''; +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu100.php b/AvocadoEdition/adm/admin.menu100.php new file mode 100644 index 0000000..d9098f4 --- /dev/null +++ b/AvocadoEdition/adm/admin.menu100.php @@ -0,0 +1,22 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE) { + $menu['menu100'][] = array('100510', 'Browscap 업데이트', G5_ADMIN_URL.'/browscap.php', 'cf_browscap'); + $menu['menu100'][] = array('100520', '접속로그 변환', G5_ADMIN_URL.'/browscap_convert.php', 'cf_visit_cnvrt'); +} +$menu['menu100'][] = array('100400', '부가서비스', G5_ADMIN_URL.'/service.php', 'cf_service'); +*/ +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu200.php b/AvocadoEdition/adm/admin.menu200.php new file mode 100644 index 0000000..9c36942 --- /dev/null +++ b/AvocadoEdition/adm/admin.menu200.php @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu300.php b/AvocadoEdition/adm/admin.menu300.php new file mode 100644 index 0000000..77cbd7e --- /dev/null +++ b/AvocadoEdition/adm/admin.menu300.php @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu400.php b/AvocadoEdition/adm/admin.menu400.php new file mode 100644 index 0000000..143fb4d --- /dev/null +++ b/AvocadoEdition/adm/admin.menu400.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu500.php b/AvocadoEdition/adm/admin.menu500.php new file mode 100644 index 0000000..8cac513 --- /dev/null +++ b/AvocadoEdition/adm/admin.menu500.php @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.menu900.php b/AvocadoEdition/adm/admin.menu900.php new file mode 100644 index 0000000..52dde44 --- /dev/null +++ b/AvocadoEdition/adm/admin.menu900.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/admin.tail.php b/AvocadoEdition/adm/admin.tail.php new file mode 100644 index 0000000..bd1b624 --- /dev/null +++ b/AvocadoEdition/adm/admin.tail.php @@ -0,0 +1,59 @@ + + +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/ajax.token.php b/AvocadoEdition/adm/ajax.token.php new file mode 100644 index 0000000..f6a100a --- /dev/null +++ b/AvocadoEdition/adm/ajax.token.php @@ -0,0 +1,14 @@ +$error, 'url'=>G5_URL))); + +$token = get_admin_token(); + +die(json_encode(array('error'=>'', 'token'=>$token, 'url'=>''))); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/ajax/_common.php b/AvocadoEdition/adm/ajax/_common.php new file mode 100644 index 0000000..6ca4d1f --- /dev/null +++ b/AvocadoEdition/adm/ajax/_common.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/auth_list.php b/AvocadoEdition/adm/auth_list.php new file mode 100644 index 0000000..4058b8e --- /dev/null +++ b/AvocadoEdition/adm/auth_list.php @@ -0,0 +1,252 @@ +전체목록'; + +$g5['title'] = "관리권한설정"; +include_once('./admin.head.php'); + +$colspan = 5; +?> + +
+ + 설정된 관리권한 건 +
+ +
+ + + + + + +
+ +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + '; + ?> + +
목록
+ + + 회원아이디닉네임메뉴권한
+ + + + + + + +
자료가 없습니다.
+
+ +
+ +
+ +document.fsearch.sfl.value = "'.$sfl.'";'."\n"; + +if (strstr($sfl, 'mb_id')) + $mb_id = $stx; +else + $mb_id = ''; +?> +
+ + + +
+ + + + + + + +
+

관리권한 추가

+ +
+

+ 다음 양식에서 회원에게 관리권한을 부여하실 수 있습니다.
+ 권한 r은 읽기권한, w는 쓰기권한, d는 삭제권한입니다. +

+
+ +
+ + + + + + + + + + + + + + + + + + + +
+ + +
+ +
권한지정 + + + + + + +
+
+ +
+ +
+
+ +
+ + + + diff --git a/AvocadoEdition/adm/auth_list_delete.php b/AvocadoEdition/adm/auth_list_delete.php new file mode 100644 index 0000000..46acecc --- /dev/null +++ b/AvocadoEdition/adm/auth_list_delete.php @@ -0,0 +1,27 @@ + diff --git a/AvocadoEdition/adm/auth_update.php b/AvocadoEdition/adm/auth_update.php new file mode 100644 index 0000000..44a0ff4 --- /dev/null +++ b/AvocadoEdition/adm/auth_update.php @@ -0,0 +1,30 @@ + diff --git a/AvocadoEdition/adm/banner_form.php b/AvocadoEdition/adm/banner_form.php new file mode 100644 index 0000000..5f2b534 --- /dev/null +++ b/AvocadoEdition/adm/banner_form.php @@ -0,0 +1,140 @@ + + +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
배너 이미지 + + + + 이미지 없음 + + + 직접등록   +
+ 외부경로   +
배너 모바일 이미지 + + + + 이미지 없음 + + + 직접등록   +
+ 외부경로   +
대체텍스트 + +
링크 + +
새창 + + +
+ + + " id="bn_begin_chk" onclick="if (this.checked == true) this.form.bn_begin_time.value=this.form.bn_begin_chk.value; else this.form.bn_begin_time.value = this.form.bn_begin_time.defaultValue;"> + +
+ + + " id="bn_end_chk" onclick="if (this.checked == true) this.form.bn_end_time.value=this.form.bn_end_chk.value; else this.form.bn_end_time.value = this.form.bn_end_time.defaultValue;"> + +
+ + +
+ +
+ +
+ + 목록 +
+ +
+ + diff --git a/AvocadoEdition/adm/banner_form_update.php b/AvocadoEdition/adm/banner_form_update.php new file mode 100644 index 0000000..eb8d079 --- /dev/null +++ b/AvocadoEdition/adm/banner_form_update.php @@ -0,0 +1,86 @@ + diff --git a/AvocadoEdition/adm/banner_list.php b/AvocadoEdition/adm/banner_list.php new file mode 100644 index 0000000..ce0d3f6 --- /dev/null +++ b/AvocadoEdition/adm/banner_list.php @@ -0,0 +1,120 @@ + + +
+ 등록된 이미지 개 +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + "; + $bn_img_obj .= ""; + if($link_tag) $bn_img_obj .= ""; + } + + $bn_begin_time = substr($row['bn_begin_time'], 2, 14); + $bn_end_time = substr($row['bn_end_time'], 2, 14); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + '; + } + ?> + +
목록
ID이미지대체텍스트시작일시종료일시출력순서관리
+ 수정 + 삭제 +
자료가 없습니다.
+ +
+ + + + + + diff --git a/AvocadoEdition/adm/board_copy.php b/AvocadoEdition/adm/board_copy.php new file mode 100644 index 0000000..c872363 --- /dev/null +++ b/AvocadoEdition/adm/board_copy.php @@ -0,0 +1,73 @@ + + + + +
+

+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + +
원본 테이블명
영문자, 숫자, _ 만 가능 (공백없이)
복사 유형 + + + + +
+
+ +
+ + +
+ +
+ +
+ + + + + diff --git a/AvocadoEdition/adm/board_copy_update.php b/AvocadoEdition/adm/board_copy_update.php new file mode 100644 index 0000000..a5a8470 --- /dev/null +++ b/AvocadoEdition/adm/board_copy_update.php @@ -0,0 +1,205 @@ +read()) { + if ($entry == '.' || $entry == '..') continue; + + // 김선용 201007 : + if(is_dir(G5_DATA_PATH.'/file/'.$bo_table.'/'.$entry)){ + $dd = dir(G5_DATA_PATH.'/file/'.$bo_table.'/'.$entry); + @mkdir(G5_DATA_PATH.'/file/'.$target_table.'/'.$entry, G5_DIR_PERMISSION); + @chmod(G5_DATA_PATH.'/file/'.$target_table.'/'.$entry, G5_DIR_PERMISSION); + while ($entry2 = $dd->read()) { + if ($entry2 == '.' || $entry2 == '..') continue; + @copy(G5_DATA_PATH.'/file/'.$bo_table.'/'.$entry.'/'.$entry2, G5_DATA_PATH.'/file/'.$target_table.'/'.$entry.'/'.$entry2); + @chmod(G5_DATA_PATH.'/file/'.$target_table.'/'.$entry.'/'.$entry2, G5_DIR_PERMISSION); + $copy_file++; + } + $dd->close(); + } + else { + @copy(G5_DATA_PATH.'/file/'.$bo_table.'/'.$entry, G5_DATA_PATH.'/file/'.$target_table.'/'.$entry); + @chmod(G5_DATA_PATH.'/file/'.$target_table.'/'.$entry, G5_DIR_PERMISSION); + $copy_file++; + } + } + $d->close(); + + // 글복사 + $sql = " insert into {$g5['write_prefix']}$target_table select * from {$g5['write_prefix']}$bo_table "; + sql_query($sql, false); + + // 게시글수 저장 + $sql = " select bo_count_write, bo_count_comment from {$g5['board_table']} where bo_table = '$bo_table' "; + $row = sql_fetch($sql); + $sql = " update {$g5['board_table']} set bo_count_write = '{$row['bo_count_write']}', bo_count_comment = '{$row['bo_count_comment']}' where bo_table = '$target_table' "; + sql_query($sql, false); + + // 4.00.01 + // 위의 코드는 같은 테이블명을 사용하였다는 오류가 발생함. (희한하네 ㅡㅡ;) + $sql = " select * from {$g5['board_file_table']} where bo_table = '$bo_table' "; + $result = sql_query($sql, false); + for ($i=0; $row=sql_fetch_array($result); $i++) + $file_copy[$i] = $row; +} + +if (count($file_copy)) { + for ($i=0; $iopener.document.location.reload();"; + +alert("복사에 성공 했습니다.", './board_copy.php?bo_table='.$bo_table.'&'.$qstr); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/board_delete.inc.php b/AvocadoEdition/adm/board_delete.inc.php new file mode 100644 index 0000000..71a3b35 --- /dev/null +++ b/AvocadoEdition/adm/board_delete.inc.php @@ -0,0 +1,33 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/board_form.php b/AvocadoEdition/adm/board_form.php new file mode 100644 index 0000000..83f50ab --- /dev/null +++ b/AvocadoEdition/adm/board_form.php @@ -0,0 +1,920 @@ +필수'; + + $board['bo_count_delete'] = 1; + $board['bo_count_modify'] = 1; + $board['bo_read_point'] = $config['cf_read_point']; + $board['bo_write_point'] = $config['cf_write_point']; + $board['bo_comment_point'] = $config['cf_comment_point']; + $board['bo_download_point'] = $config['cf_download_point']; + + $board['bo_gallery_height'] = 600; + + $board['bo_page_rows'] = $config['cf_page_rows']; + $board['bo_mobile_page_rows'] = $config['cf_page_rows']; + $board['bo_subject_len'] = 60; + $board['bo_mobile_subject_len'] = 30; + $board['bo_new'] = 24; + $board['bo_hot'] = 100; + $board['bo_image_width'] = 600; + $board['bo_upload_count'] = 1; + $board['bo_upload_size'] = (int)ini_get("upload_max_filesize") * 1048576; + $board['bo_reply_order'] = 1; + $board['bo_use_search'] = 1; + $board['bo_skin'] = 'basic'; + $board['bo_mobile_skin'] = 'basic'; + $board['gr_id'] = $gr_id; + $board['bo_use_secret'] = 0; + $board['bo_include_head'] = '_head.php'; + $board['bo_include_tail'] = '_tail.php'; + +} else if ($w == 'u') { + + $html_title .= ' 수정'; + + if (!$board['bo_table']) + alert('존재하지 않은 게시판 입니다.'); + + if ($is_admin == 'group') { + if ($member['mb_id'] != $group['gr_admin']) + alert('그룹이 틀립니다.'); + } + + $readonly = 'readonly'; + +} + +if ($is_admin != 'super') { + $group = get_group($board['gr_id']); + $is_admin = is_admin($member['mb_id']); +} + +$g5['title'] = $html_title; +include_once ('./admin.head.php'); + +$pg_anchor = ''; + +$frm_submit = '
+ + 목록'.PHP_EOL; +if ($w == 'u') $frm_submit .= '게시판복사 + 게시판 바로가기 + 게시판 썸네일 삭제'.PHP_EOL; +$frm_submit .= '
'; +?> + +
+ + + + + + + + + + + + + + + + + + + + +
+

게시판 기본 설정

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
게시판 기본 설정
+ class="frm_input " maxlength="20"> + + 영문자, 숫자, _ 만 가능 (공백없이 20자 이내) + + 게시판 바로가기 + 목록으로 + +
+ + 동일그룹 게시판목록
+ +
+ +
+ + + > + + + + + + +
+ + +
+
+
+ + + +
+

게시판 권한 설정

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
게시판 권한 설정
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+
+
+ + + +
+

게시판 기능 설정

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
게시판 기능 설정
+ + 댓글 개 이상 달리면 수정불가 + + + + + +
+ 댓글 개 이상 달리면 삭제불가 + + + + + +
+ + + + + + + +
+ id="bo_use_chick"> + 사용 +
+ id="bo_use_noname"> + 사용 +
+ + id="bo_use_dhtml_editor"> + 사용 + + + + + +
+ + > + 사용 (사용시 속도가 느려질 수 있습니다.) + + + + + +
+ + > + 사용 (사용시 속도가 느려질 수 있습니다.) + + + + + +
+ > + 사용 + + + + + +
+ + + + + + + +
+ + 업로드 파일 한개당 bytes 이하 + + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + + + +
+
+
+ + + +
+

게시판 디자인/양식

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
게시판 디자인/양식
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + 픽셀 + + + + + +
+ + 픽셀 + + + + + +
+ + + + + + + +
+ + + + + + +
+ + + + + + + +
+
+
+ + + +
+

게시판 포인트 설정

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
게시판 포인트 설정
+ + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+
+
+ + + +
+

게시판 여분필드 설정

+ + +
+ + + + + + + + + + + + + + + + +
게시판 여분필드 설정
여분필드 + + + + + + + + + +
+
+
+ + + +
+ + + + diff --git a/AvocadoEdition/adm/board_form_update.php b/AvocadoEdition/adm/board_form_update.php new file mode 100644 index 0000000..207289b --- /dev/null +++ b/AvocadoEdition/adm/board_form_update.php @@ -0,0 +1,411 @@ + diff --git a/AvocadoEdition/adm/board_list.php b/AvocadoEdition/adm/board_list.php new file mode 100644 index 0000000..8bc4ce3 --- /dev/null +++ b/AvocadoEdition/adm/board_list.php @@ -0,0 +1,211 @@ +전체목록'; + +$g5['title'] = '게시판관리'; +include_once('./admin.head.php'); + +$colspan = 10; +?> + +
+ + 생성된 게시판수 개 +
+ +
+ + + + + + + +
+ + + + + +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + 수정'; + $one_copy = '복사'; + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + + '; + ?> + +
목록
+ + + 그룹TABLE스킨제목읽기P포인트쓰기P포인트댓글P포인트다운P포인트관리
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
자료가 없습니다.
+
+ +
+ + + + +
+ +
+ + + + + + diff --git a/AvocadoEdition/adm/board_list_update.php b/AvocadoEdition/adm/board_list_update.php new file mode 100644 index 0000000..e3eeff3 --- /dev/null +++ b/AvocadoEdition/adm/board_list_update.php @@ -0,0 +1,67 @@ + diff --git a/AvocadoEdition/adm/board_thumbnail_delete.php b/AvocadoEdition/adm/board_thumbnail_delete.php new file mode 100644 index 0000000..720cad4 --- /dev/null +++ b/AvocadoEdition/adm/board_thumbnail_delete.php @@ -0,0 +1,52 @@ + + +
+

+ 완료 메세지가 나오기 전에 프로그램의 실행을 중지하지 마십시오. +

+
+ +'; + $files = glob($dir.'/thumb-*'); + if (is_array($files)) { + foreach($files as $thumbnail) { + $cnt++; + @unlink($thumbnail); + + echo '
  • '.$thumbnail.'
  • '.PHP_EOL; + + flush(); + + if ($cnt%10==0) + echo PHP_EOL; + } + } + + echo '
  • 완료됨
  • '.PHP_EOL; + echo '

    썸네일 '.$cnt.'건의 삭제 완료됐습니다.

    '.PHP_EOL; +} else { + echo '

    첨부파일 디렉토리가 존재하지 않습니다.

    '; +} +?> + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/boardgroup_form.php b/AvocadoEdition/adm/boardgroup_form.php new file mode 100644 index 0000000..da92d7a --- /dev/null +++ b/AvocadoEdition/adm/boardgroup_form.php @@ -0,0 +1,150 @@ + 필수'; + $gr['gr_use_access'] = 0; + $html_title .= ' 생성'; +} else if ($w == 'u') { + $gr_id_attr = 'readonly'; + $gr = sql_fetch(" select * from {$g5['group_table']} where gr_id = '$gr_id' "); + $html_title .= ' 수정'; +} +else + alert('제대로 된 값이 넘어오지 않았습니다.'); + +if (!isset($group['gr_device'])) { + sql_query(" ALTER TABLE `{$g5['group_table']}` ADD `gr_device` ENUM('both','pc','mobile') NOT NULL DEFAULT 'both' AFTER `gr_subject` ", false); +} + + +$g5['title'] = $html_title; +include_once('./admin.head.php'); +?> + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    class=" alnum_ frm_input" maxlength="10"> + +
    + + 게시판생성'; + ?> +
    + + +
    + '; + else + echo ''.$gr['gr_admin']; + ?> +
    + + > + 사용 +
    접근회원수 + '.$row1['cnt'].''; + ?> +
    여분필드 + + + + +
    +
    + +
    + + 목록 +
    + +
    + +
    +

    + 게시판을 생성하시려면 1개 이상의 게시판그룹이 필요합니다.
    + 게시판그룹을 이용하시면 더 효과적으로 게시판을 관리할 수 있습니다. +

    +
    + + + + diff --git a/AvocadoEdition/adm/boardgroup_form_update.php b/AvocadoEdition/adm/boardgroup_form_update.php new file mode 100644 index 0000000..c29558f --- /dev/null +++ b/AvocadoEdition/adm/boardgroup_form_update.php @@ -0,0 +1,71 @@ + diff --git a/AvocadoEdition/adm/boardgroup_list.php b/AvocadoEdition/adm/boardgroup_list.php new file mode 100644 index 0000000..04f5601 --- /dev/null +++ b/AvocadoEdition/adm/boardgroup_list.php @@ -0,0 +1,215 @@ +처음'; + +$g5['title'] = '게시판그룹설정'; +include_once('./admin.head.php'); + +$colspan = 10; +?> + +
    + + 전체그룹 개 +
    + +
    + + + + + + +
    + + + + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + '; + ?> +
    목록
    + + + 그룹아이디제목그룹관리자게시판출력 순서접속기기관리
    + + + + + + + + + + + + + + +
    자료가 없습니다.
    +
    + + +
    + +
    +

    + 접근사용 옵션을 설정하시면 관리자가 지정한 회원만 해당 그룹에 접근할 수 있습니다.
    + 접근사용 옵션은 해당 그룹에 속한 모든 게시판에 적용됩니다. +

    +
    + + + + + + diff --git a/AvocadoEdition/adm/boardgroup_list_update.php b/AvocadoEdition/adm/boardgroup_list_update.php new file mode 100644 index 0000000..6796c6b --- /dev/null +++ b/AvocadoEdition/adm/boardgroup_list_update.php @@ -0,0 +1,47 @@ + diff --git a/AvocadoEdition/adm/boardgroupmember_form.php b/AvocadoEdition/adm/boardgroupmember_form.php new file mode 100644 index 0000000..4158cad --- /dev/null +++ b/AvocadoEdition/adm/boardgroupmember_form.php @@ -0,0 +1,127 @@ + + +
    + + +
    +

    아이디 , 이름 , 닉네임

    + + + +
    +
    + +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    + + + 그룹아이디그룹처리일시
    + + +
    접근가능한 그룹이 없습니다.
    +
    + +
    + +
    +
    + + + + diff --git a/AvocadoEdition/adm/boardgroupmember_list.php b/AvocadoEdition/adm/boardgroupmember_list.php new file mode 100644 index 0000000..8827df7 --- /dev/null +++ b/AvocadoEdition/adm/boardgroupmember_list.php @@ -0,0 +1,156 @@ + + +
    + + + + + + +
    + +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + '.$row2['cnt'].''; + + $mb_nick = get_sideview($row['mb_id'], $row['mb_nick'], $row['mb_email'], $row['mb_homepage']); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + '; + } + ?> + +
    목록
    + + + 그룹회원아이디이름별명최종접속처리일시
    + + +
    자료가 없습니다.
    +
    + +
    + +
    +
    + + + + + + diff --git a/AvocadoEdition/adm/boardgroupmember_update.php b/AvocadoEdition/adm/boardgroupmember_update.php new file mode 100644 index 0000000..95f8372 --- /dev/null +++ b/AvocadoEdition/adm/boardgroupmember_update.php @@ -0,0 +1,70 @@ + diff --git a/AvocadoEdition/adm/browscap.php b/AvocadoEdition/adm/browscap.php new file mode 100644 index 0000000..25f2f51 --- /dev/null +++ b/AvocadoEdition/adm/browscap.php @@ -0,0 +1,45 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE)) + alert('사용할 수 없는 기능입니다.', G5_ADMIN_URL); + +if ($is_admin != 'super') + alert('최고관리자만 접근 가능합니다.'); + +$g5['title'] = 'Browscap 업데이트'; +include_once('./admin.head.php'); +?> + +
    +

    Browscap 정보를 업데이트하시려면 아래 업데이트 버튼을 클릭해 주세요.

    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/browscap_convert.php b/AvocadoEdition/adm/browscap_convert.php new file mode 100644 index 0000000..edf3b0d --- /dev/null +++ b/AvocadoEdition/adm/browscap_convert.php @@ -0,0 +1,46 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE)) + alert('사용할 수 없는 기능입니다.', G5_ADMIN_URL); + +if ($is_admin != 'super') + alert('최고관리자만 접근 가능합니다.'); + +$rows = preg_replace('#[^0-9]#', '', $_GET['rows']); +if(!$rows) + $rows = 100; + +$g5['title'] = '접속로그 변환'; +include_once('./admin.head.php'); +?> + +
    +

    접속로그 정보를 Browscap 정보로 변환하시려면 아래 업데이트 버튼을 클릭해 주세요.

    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/browscap_converter.php b/AvocadoEdition/adm/browscap_converter.php new file mode 100644 index 0000000..f7572ed --- /dev/null +++ b/AvocadoEdition/adm/browscap_converter.php @@ -0,0 +1,75 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE)) + die('사용할 수 없는 기능입니다.'); + +if($is_admin != 'super') + die('최고관리자로 로그인 후 실행해 주세요.'); + +// browscap cache 파일 체크 +if(!is_file(G5_DATA_PATH.'/cache/browscap_cache.php')) { + echo '

    Browscap 정보가 없습니다. 아래 링크로 이동해 Browscap 정보를 업데이트 하세요.

    '.PHP_EOL; + echo '

    Browscap 업데이트

    '.PHP_EOL; + exit; +} + +include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php'); +$browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache'); +$browscap->doAutoUpdate = false; +$browscap->cacheFilename = 'browscap_cache.php'; + +// 데이터 변환 +$rows = preg_replace('#[^0-9]#', '', $_GET['rows']); +if(!$rows) + $rows = 100; + +$sql_common = " from {$g5['visit_table']} where vi_agent <> '' and ( vi_browser = '' or vi_os = '' or vi_device = '' ) "; +$sql_order = " order by vi_id desc "; +$sql_limit = " limit 0, $rows "; + +$sql = " select count(vi_id) as cnt $sql_common "; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$sql = " select vi_id, vi_agent, vi_browser, vi_os, vi_device + $sql_common + $sql_order + $sql_limit "; +$result = sql_query($sql); + +$cnt = 0; +for($i=0; $row=sql_fetch_array($result); $i++) { + $info = $browscap->getBrowser($row['vi_agent']); + + $brow = $row['vi_browser']; + if(!$brow) + $brow = $info->Comment; + + $os = $row['vi_os']; + if(!$os) + $os = $info->Platform; + + $device = $row['vi_device']; + if(!$device) + $device = $info->Device_Type; + + $sql2 = " update {$g5['visit_table']} + set vi_browser = '$brow', + vi_os = '$os', + vi_device = '$device' + where vi_id = '{$row['vi_id']}' "; + sql_query($sql2); + + $cnt++; +} + +if(($total_count - $cnt) == 0 || $total_count == 0) + echo '

    변환완료

    '; +else + echo '

    총 '.number_format($total_count).'건 중 '.number_format($cnt).'건 변환완료

    접속로그를 추가로 변환하시려면 아래 업데이트 버튼을 클릭해 주세요.

    '; +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/browscap_update.php b/AvocadoEdition/adm/browscap_update.php new file mode 100644 index 0000000..e27a739 --- /dev/null +++ b/AvocadoEdition/adm/browscap_update.php @@ -0,0 +1,24 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE)) + die('사용할 수 없는 기능입니다.'); + +if ($is_admin != 'super') + die('최고관리자만 접근 가능합니다.'); + +include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php'); + +$browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache'); +$browscap->updateMethod = 'cURL'; +$browscap->cacheFilename = 'browscap_cache.php'; +$browscap->updateCache(); + +die(''); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/cache_file_delete.php b/AvocadoEdition/adm/cache_file_delete.php new file mode 100644 index 0000000..271bc37 --- /dev/null +++ b/AvocadoEdition/adm/cache_file_delete.php @@ -0,0 +1,48 @@ + + +
    +

    + 완료 메세지가 나오기 전에 프로그램의 실행을 중지하지 마십시오. +

    +
    + +캐시디렉토리를 열지못했습니다.

    '; +} + +$cnt=0; +echo '
      '.PHP_EOL; + +$files = glob(G5_DATA_PATH.'/cache/latest-*'); +if (is_array($files)) { + foreach ($files as $cache_file) { + $cnt++; + unlink($cache_file); + echo '
    • '.$cache_file.'
    • '.PHP_EOL; + + flush(); + + if ($cnt%10==0) + echo PHP_EOL; + } +} + +echo '
    • 완료됨
    '.PHP_EOL; +echo '

    최신글 캐시파일 '.$cnt.'건 삭제 완료됐습니다.
    프로그램의 실행을 끝마치셔도 좋습니다.

    '.PHP_EOL; +?> + + \ No newline at end of file diff --git a/AvocadoEdition/adm/captcha_file_delete.php b/AvocadoEdition/adm/captcha_file_delete.php new file mode 100644 index 0000000..d8b8055 --- /dev/null +++ b/AvocadoEdition/adm/captcha_file_delete.php @@ -0,0 +1,53 @@ + + +
    +

    + 완료 메세지가 나오기 전에 프로그램의 실행을 중지하지 마십시오. +

    +
    + +캐시디렉토리를 열지못했습니다.

    '; +} + +$cnt=0; +echo '
      '.PHP_EOL; + +$files = glob(G5_DATA_PATH.'/cache/?captcha-*'); +if (is_array($files)) { + $before_time = G5_SERVER_TIME - 3600; // 한시간전 + foreach ($files as $gcaptcha_file) { + $modification_time = filemtime($gcaptcha_file); // 파일접근시간 + + if ($modification_time > $before_time) continue; + + $cnt++; + unlink($gcaptcha_file); + echo '
    • '.$gcaptcha_file.'
    • '.PHP_EOL; + + flush(); + + if ($cnt%10==0) + echo PHP_EOL; + } +} + +echo '
    • 완료됨
    '.PHP_EOL; +echo '

    캡챠파일 '.$cnt.'건의 삭제 완료됐습니다.
    프로그램의 실행을 끝마치셔도 좋습니다.

    '.PHP_EOL; +?> + + \ No newline at end of file diff --git a/AvocadoEdition/adm/character_article_list.php b/AvocadoEdition/adm/character_article_list.php new file mode 100644 index 0000000..f2755e4 --- /dev/null +++ b/AvocadoEdition/adm/character_article_list.php @@ -0,0 +1,327 @@ + +
  • 기본 프로필 양식
  • +
  • 추가 프로필 양식
  • +
  • 프로필 항목 등록
  • +'; + +$frm_submit = '
    + +
    '; + +// 추가 항목에 대한 데이터들 가져오기 +$sql = " select * from {$g5['article_table']} order by ar_theme asc, ar_order asc"; +$result = sql_query($sql); + +$g5['title'] = '프로필 양식 관리'; +include_once ('./admin.head.php'); +?> + +
    + +
    +

    기본 프로필 양식

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    기능사용설정 + /> + +    + /> + +    + /> + +    + /> + +    + /> + +    + /> + +    + /> + +
    사용여부 + /> + +    + /> + +
    도움말 + +
    사용여부 + /> + +    + /> + +
    도움말 + +
    사용여부 + /> + +    + /> + +
    도움말 + +
    도움말 + + +
    +
    + +
    + + + +
    +

    추가 프로필 양식

    + +
    +

    항목을 제거하실 시, 고유코드 항목을 지우고 확인을 누르시면 됩니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    테마고유코드항목명항목타입폼크기단위/항목도움말순서공개영역
    + + + + + + + + + + px + + + + + + + + +
    등록된 항목이 없습니다.
    +
    +
    + +
    + + + +
    + +
    +

    프로필 항목 등록

    + +
    +

    프로필 항목 등록은 하단의 확인을 눌러야만 등록이 됩니다. (기본 프로필 양식 및 추가 프로필 양식의 확인버튼을 클릭 시 내용이 날아갑니다.)

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    테마 + + +
    고유코드 + + +
    항목명 + +
    항목타입 + +
    폼크기 + + px +
    단위/항목 + + + +
    도움말 + + +
    순서 + + +
    공개범위 + +
    +
    +
    + + +
    + + + diff --git a/AvocadoEdition/adm/character_article_list_update.php b/AvocadoEdition/adm/character_article_list_update.php new file mode 100644 index 0000000..e8d971d --- /dev/null +++ b/AvocadoEdition/adm/character_article_list_update.php @@ -0,0 +1,124 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/character_article_update.php b/AvocadoEdition/adm/character_article_update.php new file mode 100644 index 0000000..29559d3 --- /dev/null +++ b/AvocadoEdition/adm/character_article_update.php @@ -0,0 +1,25 @@ + diff --git a/AvocadoEdition/adm/character_delete.php b/AvocadoEdition/adm/character_delete.php new file mode 100644 index 0000000..7d05199 --- /dev/null +++ b/AvocadoEdition/adm/character_delete.php @@ -0,0 +1,36 @@ + diff --git a/AvocadoEdition/adm/character_form.php b/AvocadoEdition/adm/character_form.php new file mode 100644 index 0000000..d22b756 --- /dev/null +++ b/AvocadoEdition/adm/character_form.php @@ -0,0 +1,449 @@ + +
  • 기본 설정
  • +
  • 이미지 설정
  • +'; +if($ad['ad_use_status']) { + $pg_anchor .= '
  • 스탯 설정
  • '; +} +$pg_anchor .= ' +
  • 프로필 설정
  • +'; + + +$frm_submit = '
    + + 목록 +
    '; + +$g5['title'] .= ""; +$g5['title'] .= '캐릭터 '.$html_title; +include_once('./admin.head.php'); +?> + +
    + + + + + + + + + + +
    +

    캐릭터 기본 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    활동 승인 + +
    캐릭터유형 + +
    오너아이디 + +
    + +
    + +
    +
    +
    + + +
    +

    캐릭터 이미지 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + 이미지 미등록 + + + + + + + + + +
    + + + + 이미지 미등록 + + + + + + + + + +
    + + + + 이미지 미등록 + + + + + + + + + +
    +
    +
    + + + + +
    +

    캐릭터 스탯 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    보유 스탯 + + + +
    차감 수치 + +
    + 등록된 스탯 정보가 존재하지 않습니다. +
    스탯포인트전체포인트 + +
    사용포인트 + +
    +
    +
    + + + + +
    +

    캐릭터 프로필 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + 이미지 미등록 + + + + + /> + + + + + + + + /> + + + + + + + + + +
    +
    +
    + + +
    + + + + + + + diff --git a/AvocadoEdition/adm/character_form_update.php b/AvocadoEdition/adm/character_form_update.php new file mode 100644 index 0000000..ff6eaea --- /dev/null +++ b/AvocadoEdition/adm/character_form_update.php @@ -0,0 +1,238 @@ + 0) { + // 저장되는 스탯 정보가 존재할 시 + for($i=0; $i < count($st_id); $i++) { + $temp_st_id = $st_id[$i]; + $old_sc = sql_fetch("select * from {$g5['status_table']} where ch_id = '{$ch_id}' and st_id = '{$temp_st_id}'"); + + if($old_sc['sc_id']) { + // 업데이트 + $sql = " update {$g5['status_table']} + set sc_max = '{$sc_max[$i]}', + sc_value = '{$sc_value[$i]}' + where sc_id = '{$old_sc['sc_id']}' + "; + sql_query($sql); + + } else { + // 등록 + $sql = " insert into {$g5['status_table']} + set st_id = '{$st_id[$i]}', + ch_id = '{$ch_id}', + sc_max = '{$sc_max[$i]}', + sc_value = '{$sc_value[$i]}' + "; + sql_query($sql); + } + } +} + + +goto_url('./character_form.php?'.$qstr.'&w=u&ch_id='.$ch_id, false); +?> diff --git a/AvocadoEdition/adm/character_list.php b/AvocadoEdition/adm/character_list.php new file mode 100644 index 0000000..e1210fd --- /dev/null +++ b/AvocadoEdition/adm/character_list.php @@ -0,0 +1,317 @@ +전체목록'; + +$g5['title'] = '캐릭터 관리'; +include_once('./admin.head.php'); + +$sql = " select * {$sql_common} {$sql_search} {$sql_order} limit {$from_record}, {$rows} "; +$result = sql_query($sql); + +$colspan = 8; + + +/** 세력 정보 **/ +$ch_si = array(); +if($config['cf_side_title']) { + $side_result = sql_query("select si_id, si_name from {$g5['side_table']} where si_auth <= '{$member['mb_level']}' order by si_id asc"); + for($i=0; $row = sql_fetch_array($side_result); $i++) { + $ch_si[$i]['name'] = $row['si_name']; + $ch_si[$i]['id'] = $row['si_id']; + } +} + +/** 종족 정보 **/ +$ch_cl = array(); +if($config['cf_class_title']) { + $class_result = sql_query("select cl_id, cl_name from {$g5['class_table']} where cl_auth <= '{$member['mb_level']}' order by cl_id asc"); + for($i=0; $row = sql_fetch_array($class_result); $i++) { + $ch_cl[$i]['name'] = $row['cl_name']; + $ch_cl[$i]['id'] = $row['cl_id']; + } + +} + +$profile = sql_fetch(" select ad_use_rank from {$g5['article_default_table']} "); +if($profile['ad_use_rank']) { + $colspan++; +} + + +?> + +
    + + 총캐릭터수 명 + + 승인대기 명 | + 수정중 명 | + 삭제 명 + +
    + +
    + + + 0) { +?> + + + 0) { +?> + + + + + + + +
    + + + + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + $s_del = '제거'; + ?> + + + + + + + + + + + + + + + + + + + + + + + + "; + ?> + +
    목록
    + + + 유형이름랭킹상태관리
    + + + + + + + + + + + + + +   
    자료가 없습니다.
    +
    + +
    +

    선택삭제 - 상태를 삭제로 변경, 차후 문제 시 복구가 가능합니다. / 선택제거 - 캐리터 정보 삭제. 복구 불가능. 캐릭터와 관련된 아이템, 포인트 등의 정보 까지 모두 제거 됩니다.

    +
    + +
    + + + + +
    + +
    + + + + + + + + diff --git a/AvocadoEdition/adm/character_list_update.php b/AvocadoEdition/adm/character_list_update.php new file mode 100644 index 0000000..01aba4a --- /dev/null +++ b/AvocadoEdition/adm/character_list_update.php @@ -0,0 +1,108 @@ + diff --git a/AvocadoEdition/adm/class_list.php b/AvocadoEdition/adm/class_list.php new file mode 100644 index 0000000..5740345 --- /dev/null +++ b/AvocadoEdition/adm/class_list.php @@ -0,0 +1,214 @@ +전체목록'; + +$g5['title'] = $config['cf_class_title'].' 관리'; +include_once ('./admin.head.php'); + +$colspan = 7; + + + +$pg_anchor = ''; + +?> + +
    +

    목록

    + + +
    + + 전체 건 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + IDX이미지선택권한보기
    + + + + + + ' alt='' style="max-width: 40px;"> + + + + + + + + + + + 멤버목록보기 + +
    자료가 없습니다.
    +
    + +
    + + +
    + +
    + + +
    + +
    +

    정보 등록

    + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/class_list_delete.php b/AvocadoEdition/adm/class_list_delete.php new file mode 100644 index 0000000..6da5c97 --- /dev/null +++ b/AvocadoEdition/adm/class_list_delete.php @@ -0,0 +1,88 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/class_update.php b/AvocadoEdition/adm/class_update.php new file mode 100644 index 0000000..de5fbba --- /dev/null +++ b/AvocadoEdition/adm/class_update.php @@ -0,0 +1,44 @@ + diff --git a/AvocadoEdition/adm/community_form.php b/AvocadoEdition/adm/community_form.php new file mode 100644 index 0000000..7bd615a --- /dev/null +++ b/AvocadoEdition/adm/community_form.php @@ -0,0 +1,272 @@ + +
  • 기본설정
  • +
  • 기능설정
  • +
  • 기타항목설정
  • +'; + +$frm_submit = '
    + +
    '; +?> + +
    + + +
    +

    커뮤니티 기본환경 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    공개설정 + > + +    + > + +    + > + +    + > + +
    홈페이지 제목
    사이트설명 + +
    파비콘 + + 직접등록   +
    + 외부경로   +
    사이트이미지 + + 직접등록   +
    + 외부경로   +
    + + +
    + + +
    기능설정 + > + +    + > + +    + > + +
    기타설정 + + + > + + +
    +
    +
    + + + + +
    +

    기능 설정

    + + +
    + + + + + + + + + + + + + + + + + + + +
    캐릭터 최대 생성 갯수 + +
    최초 스탯 포인트 + + +
    하루 탐색 횟수 + +
    +
    +
    + + + +
    +

    기타 항목명 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    설정명칭 + +
    단위 + +
    설정명칭 + +
    단위 + +
    설정명칭 + +
    (선택A)설정명칭 + + +
    (선택B)설정명칭 + + +
    상점 카테고리- + + +
    아이템 기능- + + +
    +
    +
    + + + + +
    + + + + diff --git a/AvocadoEdition/adm/community_form_update.php b/AvocadoEdition/adm/community_form_update.php new file mode 100644 index 0000000..57e88db --- /dev/null +++ b/AvocadoEdition/adm/community_form_update.php @@ -0,0 +1,80 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/config_form.php b/AvocadoEdition/adm/config_form.php new file mode 100644 index 0000000..b1dfa88 --- /dev/null +++ b/AvocadoEdition/adm/config_form.php @@ -0,0 +1,1195 @@ + +
  • 기본환경
  • +
  • 게시판기본
  • +
  • 회원가입
  • +
  • 투표메일
  • +
  • 레이아웃 추가설정
  • +'; + +$frm_submit = '
    + +
    '; + +if (!$config['cf_icode_server_ip']) $config['cf_icode_server_ip'] = '211.172.232.124'; +if (!$config['cf_icode_server_port']) $config['cf_icode_server_port'] = '7295'; + +if ($config['cf_sms_use'] && $config['cf_icode_id'] && $config['cf_icode_pw']) { + $userinfo = get_icode_userinfo($config['cf_icode_id'], $config['cf_icode_pw']); +} +?> + +
    + + +
    +

    홈페이지 기본환경 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    관리자 아이콘 + + + 관리자 아이콘 + + + +
    + + +
    + + +
    > 사용
    + + 점 + + + 점 +
    + 자리만 표시 +
    수정하면 일 동안 바꿀 수 없음수정하면 일 동안 바꿀 수 없음
    + + 일 + + + 일 +
    + + 일 + + + 일 +
    + + 분 + + + 라인 +
    + + 라인 + 페이지씩 표시
    + + + +
    + + + +
    + + +
    + + +
    + + > 남김 +
    + + 일 +
    + 123.123.+ 도 입력 가능. (엔터로 구분)') ?> + + + 123.123.+ 도 입력 가능. (엔터로 구분)') ?> + +
    + + +
    + + +
    + 경고) curl이 지원되지 않아 네이버 신디케이션을 사용할수 없습니다.'); ?> + 연동키는 네이버 웹마스터도구 -> 네이버 신디케이션에서 발급할 수 있습니다.') ?> + +
    + 참고로 그룹접근사용 게시판, 글읽기 권한 2 이상 게시판, 비밀글은 신디케이션 수집에서 제외됩니다.') ?> + +
    +
    +
    + + + +
    +

    게시판 기본 설정

    + +
    +

    각 게시판 관리에서 개별적으로 설정 가능합니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    게시판 기본 설정
    초 지난후 가능 + + +
    건 단위로 검색
    + + +
    + + +
    + + +
    + + +
    +
    +
    + + + +
    +

    회원가입 설정

    + +
    +

    회원가입 시 사용할 스킨과 입력 받을 정보 등을 설정할 수 있습니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    회원가입 설정
    + +
    홈페이지 입력 + > + > + 주소 입력 + > + > +
    전화번호 입력 + > + > + 휴대폰번호 입력 + > + > +
    서명 입력 + > + > + 자기소개 입력 + > + > +
    일 후 자동 삭제
    + + + 이상
    바이트 이하회원아이콘 사이즈 + + + + + 픽셀 이하 +
    > 사용 + +
    + + + + + +
    +
    +
    + + + + + + + + + + + + + + + + + + + +
    +

    투표 기타의견 작성 시 메일 설정

    + + +
    + + + + + + + + + + + + +
    투표 기타의견 작성 시 메일 설정
    + + > 사용 +
    +
    +
    + + + + + + + +
    +

    레이아웃 추가설정

    + +
    +

    기본 설정된 파일 경로 및 script, css 를 추가하거나 변경할 수 있습니다.

    +
    + +
    + + + + + + + + + + + + +
    레이아웃 추가설정
    + 관리자 페이지에서는 이 코드를 사용하지 않습니다.') ?> + +
    +
    +
    + + + + + + + + +
    + + + +'.PHP_EOL; + echo 'alert("'.str_replace(G5_PATH.'/', '', G5_LGXPAY_PATH).'/lgdacom 폴더 안에 log 폴더를 생성하신 후 쓰기권한을 부여해 주십시오.\n> mkdir log\n> chmod 707 log");'.PHP_EOL; + echo ''.PHP_EOL; + } else { + if(!is_writable($log_path)) { + echo ''.PHP_EOL; + } + } + } +} + +include_once ('./admin.tail.php'); +?> diff --git a/AvocadoEdition/adm/config_form_update.php b/AvocadoEdition/adm/config_form_update.php new file mode 100644 index 0000000..f092bad --- /dev/null +++ b/AvocadoEdition/adm/config_form_update.php @@ -0,0 +1,159 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/contentform.php b/AvocadoEdition/adm/contentform.php new file mode 100644 index 0000000..2274eae --- /dev/null +++ b/AvocadoEdition/adm/contentform.php @@ -0,0 +1,207 @@ + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    목록
    + + class="required frm_input" size="20" maxlength="20"> + 내용확인 +
    내용
    모바일 내용
    + +
    + + +
    + + +
    + + +
    + + 750) + $width = 750; + else + $width = $size[0]; + + echo ' '; + $himg_str = ''; + } + if ($himg_str) { + echo ''; + } + ?> +
    + + 750) + $width = 750; + else + $width = $size[0]; + + echo ' '; + $timg_str = ''; + } + if ($timg_str) { + echo ''; + } + ?> +
    +
    + +
    + + 목록 +
    + +
    + + + + diff --git a/AvocadoEdition/adm/contentformupdate.php b/AvocadoEdition/adm/contentformupdate.php new file mode 100644 index 0000000..2abf659 --- /dev/null +++ b/AvocadoEdition/adm/contentformupdate.php @@ -0,0 +1,99 @@ + diff --git a/AvocadoEdition/adm/contentlist.php b/AvocadoEdition/adm/contentlist.php new file mode 100644 index 0000000..71c7778 --- /dev/null +++ b/AvocadoEdition/adm/contentlist.php @@ -0,0 +1,98 @@ +/data/dbconfig.php 파일에 $g5[\'content_table\'] = G5_TABLE_PREFIX.\'content\'; 를 추가해 주세요.'); +} +//내용(컨텐츠)정보 테이블이 있는지 검사한다. +if(!sql_query(" DESCRIBE {$g5['content_table']} ", false)) { + if(sql_query(" DESCRIBE {$g5['g5_shop_content_table']} ", false)) { + sql_query(" ALTER TABLE {$g5['g5_shop_content_table']} RENAME TO `{$g5['content_table']}` ;", false); + } else { + $query_cp = sql_query(" CREATE TABLE IF NOT EXISTS `{$g5['content_table']}` ( + `co_id` varchar(20) NOT NULL DEFAULT '', + `co_html` tinyint(4) NOT NULL DEFAULT '0', + `co_subject` varchar(255) NOT NULL DEFAULT '', + `co_content` longtext NOT NULL, + `co_hit` int(11) NOT NULL DEFAULT '0', + `co_include_head` varchar(255) NOT NULL, + `co_include_tail` varchar(255) NOT NULL, + PRIMARY KEY (`co_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ", true); + + // 내용관리 생성 + sql_query(" insert into `{$g5['content_table']}` set co_id = 'company', co_html = '1', co_subject = '회사소개', co_content= '

    회사소개에 대한 내용을 입력하십시오.

    ' ", false ); + sql_query(" insert into `{$g5['content_table']}` set co_id = 'privacy', co_html = '1', co_subject = '개인정보 처리방침', co_content= '

    개인정보 처리방침에 대한 내용을 입력하십시오.

    ' ", false ); + sql_query(" insert into `{$g5['content_table']}` set co_id = 'provision', co_html = '1', co_subject = '서비스 이용약관', co_content= '

    서비스 이용약관에 대한 내용을 입력하십시오.

    ' ", false ); + } +} + +$g5['title'] = '내용관리'; +include_once (G5_ADMIN_PATH.'/admin.head.php'); + +$sql_common = " from {$g5['content_table']} where co_subject != '' "; + +// 테이블의 전체 레코드수만 얻음 +$sql = " select count(*) as cnt " . $sql_common; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$rows = $config['cf_page_rows']; +$total_page = ceil($total_count / $rows); // 전체 페이지 계산 +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $rows; // 시작 열을 구함 + +$sql = "select * $sql_common order by co_id limit $from_record, {$config['cf_page_rows']} "; +$result = sql_query($sql); +?> + +
    + 1) {?>처음으로 + 전체 내용 +
    + + + +
    + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    ID제목관리
    + 수정 + 보기 + 삭제 +
    자료가 한건도 없습니다.
    +
    + + + + diff --git a/AvocadoEdition/adm/couple_list.php b/AvocadoEdition/adm/couple_list.php new file mode 100644 index 0000000..6d102c4 --- /dev/null +++ b/AvocadoEdition/adm/couple_list.php @@ -0,0 +1,231 @@ +전체목록'; + +$mb = array(); + +$g5['title'] = '커플 관리'; +include_once ('./admin.head.php'); + +$pg_anchor = ''; + +$colspan = 5; +?> + + + +
    + + + + + + + +
    +

    커플 목록

    + + +
    + + 전체 커플 +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 왼쪽오른족사귄날짜순서
    + + + + + + + + + + + +
    자료가 없습니다.
    +
    + +
    + +
    + + + +
    + +
    + + + +
    +

    커플 추가

    + + + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    +
    + + +
    +
    +
    + +
    + +
    +
    + +
    + + + + diff --git a/AvocadoEdition/adm/couple_list_delete.php b/AvocadoEdition/adm/couple_list_delete.php new file mode 100644 index 0000000..a55ed6b --- /dev/null +++ b/AvocadoEdition/adm/couple_list_delete.php @@ -0,0 +1,26 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/couple_update.php b/AvocadoEdition/adm/couple_update.php new file mode 100644 index 0000000..13a4901 --- /dev/null +++ b/AvocadoEdition/adm/couple_update.php @@ -0,0 +1,31 @@ + diff --git a/AvocadoEdition/adm/css/admin.css b/AvocadoEdition/adm/css/admin.css new file mode 100644 index 0000000..8a7c6fc --- /dev/null +++ b/AvocadoEdition/adm/css/admin.css @@ -0,0 +1,426 @@ +@charset "utf-8"; +@import url(//fonts.googleapis.com/earlyaccess/notosanskr.css); +@font-face { + font-family: 'icon'; + src: url('../../css/fonts/icomoon.eot?y5isk6'); + src: url('../../css/fonts/icomoon.eot?y5isk6#iefix') format('embedded-opentype'), + url('../../css/fonts/icomoon.ttf?y5isk6') format('truetype'), + url('../../css/fonts/icomoon.woff?y5isk6') format('woff'), + url('../../css/fonts/icomoon.svg?y5isk6#icomoon') format('svg'); + font-weight: normal; + font-style: normal; +} + +/* 초기화 */ +html {overflow-y:scroll} +body {margin:0;padding:0;background:#fff;color:#000;font-size:12px; min-width: 1400px;} +html, h1, h2, h3, h4, h5, h6, form, fieldset, img {margin:0;padding:0;border:0} +h1, h2, h3, h4, h5, h6 {} +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block} +header ul, nav ul, aside ul, footer ul {margin:0;padding:0;list-style:none} +label, input, button, select, img {vertical-align:middle} +textarea, select {} +input {margin:0;padding:0;border-radius:0;} +input[type=text], input[type=password], input[type=submit], input[type=image] {-webkit-appearance:none} +button {border-radius:0;-webkit-appearance:none;cursor:pointer} +p {margin:0;padding:0;word-break:break-all} +hr {display:none} +pre {overflow-x:scroll;} +a {color:#000;text-decoration:none} +a:focus, a:hover, a:active {text-decoration:underline} +caption { display: none; } +.cke_sc, +.sound_only { display: none; } + +input[type="file"] { font-size: 12px; } +input[type="text"], +input[type="password"], +select, +textarea { + border: 1px solid #dde3e0; + box-sizing: border-box; + font-family: 'Dotum'; + font-size: 12px; +} +input[type="text"], +input[type="password"] { padding: 0 8px; } +input[type="text"], +input[type="password"], +select { height: 28px; padding-left: 8px; } +textarea { width: 100%; height: 150px; } + +label {cursor: pointer; } + +label + input { margin-left: 10px; } + + +.txt-center { text-align: center !important; } +.txt-left { text-align: left !important; } +.txt-right { text-align: right !important; } + +.frm_info { + display: block; + margin-bottom: 5px; + font-size: 11px; + font-family: 'Dotum'; + color: #ebb4ab; +} + +.full {width:100% !important;} +.empty_table { line-height: 200px; } + +#container { font-family: 'Noto Sans KR', sans-serif; } +#container section { + position: relative; + padding-bottom: 50px; +} +#container h2 { + font-size: 18px; + font-weight: 300; + margin-bottom: 10px; + line-height: 30px; +} +#container h2:before { + content: "\e90b"; + font-family: 'icon'; + padding-right: 5px; + color: #4b4b47; +} + +.local_ov { + border-bottom: 1px solid #efeff1; + margin-bottom: 10px; + padding-bottom: 10px; + font-size: 13px; + font-weight: 300; +} +.ov_listall{ + display: block; + position: relative; + float: left; + padding: 0 10px 0 0; + margin-right: 10px; + text-decoration: none; + color: #29c7c9; +} +.ov_listall:before { + content: ""; + display: block; + position: absolute; + right: 0; + top: 3px; + bottom: 3px; + width: 1px; + background: #e1e1e1; +} + +.local_desc { + background: #f9f9f9; + padding: 5px 10px; + border: 1px solid #efeff1; + color: #5b5b5a; + margin-bottom: 10px; + line-height: 1.8em; +} +.local_desc .point { + color: #29c7c9; +} +.local_desc.pos-top { + margin-top: 10px; + margin-bottom: 0; +} + +.pg_wrap { display: block; position: relative; text-align: center; padding: 0 0 30px 0; } + +.pg_wrap strong, +.pg_wrap a { + display: inline-block; + padding: 0 10px; + min-width: 10px; + height: 30px; + line-height: 30px; + text-align: center; + border: 1px solid #dadada; + text-decoration: none; +} +.pg_wrap strong { background: #29c7c9; color: #fff; border-color: #22a3a5; } + + + +.btn_list01 { position: relative; padding: 20px 0;} +.local_desc.pos-top + .btn_list01 { padding-top: 10px; } +.btn_list01 * { padding: 10px 15px; vertical-align: middle; } + +.btn_list03 { position: absolute; top: 5px; right: 0; } +.btn_list03 * { padding: 5px 10px; } + +.btn_add01 * { padding: 10px 15px; } + +.btn_list a, +.btn_list button, +.btn_list input { + display: inline-block; + background: #29c7c9; + color: #fff; + font-weight: 400; + text-decoration: none; + border: none; + line-height: 1.0em; + cursor: pointer; +} +.btn_add { + float: right; + clear: both; + margin-bottom: 10px; +} +.btn_add a, +.btn_add button, +.btn_add input { + display: inline-block; + background: #29c7c9; + color: #fff; + font-size: 13px; + font-weight: 400; + text-decoration: none; + border: none; + line-height: 1.0em; + cursor: pointer; +} + +.btn_confirm { + text-align: center; + padding: 50px 0; +} +section + .btn_confirm { padding-top: 0; } + +.btn_confirm a, +.btn_confirm input[type="submit"], +.btn_confirm input[type="button"]{ + display: inline-block; + vertical-align: middle; + box-sizing: border-box; + margin: 2px; + font-size: 13px; + line-height: 1.0em; + padding: 10px 25px; + border: none; + background: #f2f4f3; + color: #494c55; + cursor: pointer; + text-decoration: none; +} +.btn_confirm .btn_submit { background: #29c7c9 !important; color: #fff !important; } + +.sv { display: none !important; } +.anchor { + display: block; + position: relative; + clear: both; + padding: 0; + margin: 0 0 10px 0; + overflow: hidden; +} + +.anchor li { + display: block; + float: left; + list-style: none; + margin: 0; + +} +.anchor li a { + display: block; + position: relative; + padding: 5px 10px; + text-decoration: none; + margin: 0 1px; + color: #62656c; + border-radius: 9.0em; + box-sizing: border-box; + z-index: 1; +} +.anchor li:first-child a { border-left-width: 0; } + +.anchor li.on a, +#anc_001 a[href="#anc_001"], +#anc_002 a[href="#anc_002"], +#anc_003 a[href="#anc_003"], +#anc_004 a[href="#anc_004"], +#anc_005 a[href="#anc_005"], +#anc_006 a[href="#anc_006"], +#anc_007 a[href="#anc_007"], +#anc_008 a[href="#anc_008"], +#anc_009 a[href="#anc_009"], +#anc_010 a[href="#anc_010"], +#anc_011 a[href="#anc_011"], +#anc_012 a[href="#anc_012"], +#anc_013 a[href="#anc_013"], +#anc_014 a[href="#anc_014"], +#anc_015 a[href="#anc_015"], +#anc_016 a[href="#anc_016"]{ + background: #e66149; + color: #fff; +} + +.color-preview { display: inline-block; width: 25px; height: 25px; border: 1px solid #cacaca; vertical-align: middle; } +.admin-icon-box { display: inline-block; min-width: 25px; height: 25px; border: 1px solid #cacaca; vertical-align: middle; } + +table { border-spacing:0px; } + +.tbl_wrap table { width: 100%; border-collapse: collapse;} + +.tbl_head01 thead { } +.tbl_head01 thead th { + background: #f9f9f9; + font-weight: 300; + padding: 8px 10px; + border: 1px solid #efeff1; + font-size: 13px; + color: #5b5b5a; +} + +.tbl_head01 .bo-right { border-right-width: 1px !important; } +.tbl_head01 .bo-left { border-left-width: 1px !important; } +.tbl_head01 .bo-top { border-top-width: 1px !important; } + +.tbl_head01 .bo-no-right { border-right-width: 0px !important; } +.tbl_head01 .bo-no-left { border-left-width: 0px !important; } +.tbl_head01 .bo-no-top { border-top-width: 0px !important; } +.tbl_head01 .bo-no-bottom { border-bottom-width: 0px !important; } + + +.tbl_head01 tbody td { + text-align: center; + padding: 7px 10px; + color: #5b5b5a; + border: 1px solid #efeff1; + border-top-width: 0; + border-left-width: 0; +} +.tbl_head01 tbody td:first-child { border-left-width: 1px; } +.tbl_head01 tbody td a { color: #29c7ca; } + + +.tbl_head01 tfoot th, +.tbl_head01 tfoot td { + background: #f9f9f9; + font-weight: 300; + padding: 8px 10px; + border: 1px solid #efeff1; + border-top-width: 0; + border-left-width: 0; + font-size: 13px; + color: #5b5b5a; +} +.tbl_head01 tfoot td:first-child, +.tbl_head01 tfoot th:first-child { border-left-width: 1px; } + +.tbl_frm01 table { border-top: 1px solid #efeff5; } +.tbl_frm01 tbody th, +.tbl_frm01 tbody td { + color: #5b5b5a; + font-weight: 400; + padding: 10px; + border: 0px solid #efeff5; + border-bottom-width: 1px; +} +.tbl_frm01 tbody th { background: #f9f9f9; border-right-width: 1px; } +.tbl_frm01 tbody th.bo-right, +.tbl_frm01 tbody td.bo-right { border-right-width: 1px; } +.tbl_frm01 tbody th.bo-left, +.tbl_frm01 tbody td.bo-left { border-left-width: 1px; } +.tbl_frm01 tbody th.bo-top, +.tbl_frm01 tbody td.bo-top { border-top-width: 1px; } + +.tbl_frm01 tbody th + td.bo-left { border-left-width: 0px !important; } + + +.index-gnb {display:block; font-size:13px;} +.index-gnb > ul > li {display:table; width:100%; table-layout:fixed; overflow:hidden; border-bottom:1px solid rgba(255,255,255,.2);} +.index-gnb > ul > li > * {display:table-cell;} +.index-gnb > ul > li > a {width:130px; background:#353942; color:#fff; text-align:center; vertical-align:middle; font-size:14px;} +.index-gnb > ul > li > ul {display:block; padding:10px; background:#eaeaea;} +.index-gnb > ul > li > ul > li {display:inline-block; min-width:130px; vertical-align:middle; padding:5px 0;} + + +.prev_thumb { max-width: 100px; max-height: 50px; } +.banner-thumb { max-width: 200px; max-height: 100px; } +.character-thumb { max-width: 200px; max-height: 500px; } + + +.ajax-list-box { + height: 70px; + overflow-y: auto; + border: 1px solid #eaeaea; + margin-top: 10px; + padding: 5px; +} + + +.ajax-list-box ul, +.ajax-list-box li { display: block; margin: 0; padding: 0; position: relative; } +.ajax-list-box li { margin-bottom: 5px; } +.ajax-list-box li a { + display: block; + position: relative; + padding: 10px; + border-radius: 3px; + color: #2a2d2a; + background: #fafafa; + text-decoration: none; + font-size: 12px; +} + +.ajax-list-box li a p.point { color: #29c7c9; } +.ajax-list-box li a:hover { color: #fff; background: #3a3a3a; } +.ajax-list-box li a .ui-thumb { position: absolute; top: 10px; left: 10px; width: 30px; line-height: 30px; overflow: hidden; text-align: center; } +.ajax-list-box li a .ui-thumb img { max-width: 100%; } +.ajax-list-box li a .ui-info {margin-left:40px;} +.ajax-list-box .no-data { line-height: 50px; text-align: center; margin-top: 10px; } + +.visit_bar {position:relative} +.visit_bar span {position:absolute;top:-8px;left:0;height:15px;background:#29c7c9} + + + +/*테마*/ +.theme_p{margin:0 0 10px } +#theme_list{padding:0;margin:0;list-style:none; width: 1000px;position:relative} +#theme_list:after{display:block;visibility:hidden;clear:both;content:""} +#theme_list li{margin:10px 10px 10px 0;float:left} + +#theme_list li:after{display:block;visibility:hidden;clear:both;content:""} +#theme_list li .tmli_if{border: 1px solid #d1dee2;width:302px;} +#theme_list li .tmli_if>img{width:300px;height:225px;} +#theme_list li .tmli_if:hover>img{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";filter: alpha(opacity=50);-moz-opacity:0.5;-khtml-opacity: 0.5;opacity: 0.5;} +#theme_list li .tmli_tit{position:relative; border-top: 1px solid #d1dee2; background: #e5ecef;} +#theme_list li .tmli_tit p{height:40px;line-height:40px;padding:0 10px 0;font-weight:bold;text-overflow: ellipsis; overflow: hidden; white-space: nowrap;} +#theme_list li .tmli_tit button.tmli_dt{position:absolute;top:8px;right:10px;padding:5px;background:#111;color:#fff;display:none;border:none} +#theme_list li .tmli_if:hover button.tmli_dt{display:block} +#theme_list li .theme_sl{float:left;border:none;margin-top:5px;padding:0 5px;height:26px;background:#999;color:#fff} +#theme_list li .theme_sl:hover{background:#ff3061} +#theme_list li .theme_deactive{margin-left:4px} +#theme_list li .theme_sl_use{background:#ff3061;line-height:26px} +#theme_list li .theme_pr{float:right;margin-top:5px;padding:0 5px;height:26px;line-height:24px; border: 1px solid #ccc; background: #fafafa; } +#theme_list li .theme_preview{ float: right; margin-top: 5px; padding:0 5px;height:26px; border: 1px solid #ccc; background: #fafafa; margin-right:3px} + +#theme_detail{position:fixed;top:50%;height:540px;width:900px;margin-top:-271px;background:#fff;background:#f3f3f3;border:1px solid #000; +-webkit-box-shadow: 1px 2px 5px rgba(150,150,150,100.5); +-moz-box-shadow: 1px 2px 5px rgba(150,150,150,0.5); +box-shadow: 1px 2px 5px rgba(150,150,150,0.5);z-index:1000} +#theme_detail:after{display:block;visibility:hidden;clear:both;content:""} +#theme_detail h2{font-size:1.25em;background:#fff;padding:0 15px;line-height:40px;border-bottom:1px solid #d8d8d8;margin:0} +.theme_dt_img{float:left;padding:20px} +.theme_dt_img img{border:1px solid #aaa;} +.theme_dt_if{float:left;width:235px;padding:20px 0} +.theme_dt_if table{width:100%;border-collapse:collapse;margin:15px 0 0 ;font-size:0.92em} +.theme_dt_if table th{padding:5px;background:#fff;border-bottom:1px solid #f3f3f3;vertical-align:top;color:#3f51b5} +.theme_dt_if table td{padding:5px;background:#fff;border-bottom:1px solid #f3f3f3;line-height:1.56em} +.theme_dt_if table td a{text-decoration:underline} +.theme_dt_if p{line-height:1.5em} +.if_p_bg{display:inline-block;width:20px;height:1px ;background:#000;margin:30px 0 10px} +#theme_detail .theme_dt_btn{position:absolute;top:0px;right:0px;background:#fff;} +#theme_detail .theme_dt_btn .close_btn{border:0;border-left:1px solid #d8d8d8;background:url('../img/close.png') 50% 50% no-repeat;width:40px;height:40px;overflow:hidden;text-indent:-99999px} + +#theme_detail .theme_dt_btn .close_btn:hover{background-color:#eceffc} +#theme_detail .theme_dt_btn .btn_03{line-height:28px;display:inline-block;vertical-align:top;margin-top:6px;padding:0 6px;border-radius:5px} diff --git a/AvocadoEdition/adm/css/admin.layout.css b/AvocadoEdition/adm/css/admin.layout.css new file mode 100644 index 0000000..0b970c6 --- /dev/null +++ b/AvocadoEdition/adm/css/admin.layout.css @@ -0,0 +1,280 @@ +@charset "utf-8"; + +html, +body { height: 100%; } +#wrap { + display: table; + width: 100%; + min-height: 100%; +} +#header { + display: table-cell; + position: relative; + width: 200px; + min-height: 100%; + background: #1d1d1f; + vertical-align: top; +} +#header:after { + content: ""; + display: block; + position: absolute; + top: 0; + bottom: 0; + right: 0; + width: 1px; + background: #171b26; + z-index: 0; +} +#admin_prof { + display: block; + position: relative; + width: 200px; + height: 100px; + padding-bottom: 30px; + background: #29c7ca; + border-right: 1px solid #0aa0a5; + box-sizing: border-box; + z-index: 1; +} +#admin_prof h1 { + position: relative; + text-align: center; + line-height: 70px; + +} +#admin_prof h1 img { + position: relative; + z-index: 0; +} +#admin_prof h1 i { + display: block; + position: absolute; + bottom: 5px; + right: 10px; + font-size: 11px; + font-style: normal; + font-weight: 400; + line-height: 1.0em; + color: #1e878a; + z-index: 1; +} +#admin_prof p { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 30px; + margin: 0; + background: #2bacb0; +} + +#admin_prof a:hover { color: #fff !important; } + +#admin_prof .name { + display: block; + position: relative; + padding-right: 30px; + padding-left: 15px; + font-size: 13px; + line-height: 30px; + color: #d6eff1; + text-decoration: none; + + font-family: 'Noto Sans KR', sans-serif; +} + +#admin_prof .logout { + display: block; + position: absolute; + top: 0; + bottom: 0; + right: 0; + width: 30px; + height: 30px; + overflow: hidden; + text-indent: -999px; +} +#admin_prof .logout:before { + content: "\e984"; + font-family:'icon'; + color: #d6eff1; + font-size: 12px; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + line-height: 30px; + text-align: center; + text-indent: 0; +} + +#page_top { + position: relative; + height: 71px; + box-sizing: border-box; + border-bottom: 1px solid #131a24; + background: #1d1d1f; +} +#page_top h2 { + position: absolute; + top: 0; + left: 0; + bottom: 0; + line-height: 70px; + padding-left: 40px; + font-size: 20px; + font-family: 'Noto Sans KR', sans-serif; + color: #c3c8cc; + font-weight: 300; +} + +#page_top a { + display: block; + position: relative; + width: 70px; + height: 70px; + float: right; + border-left: 1px solid #4d515c; + overflow: hidden; + color: #c3c8cc; + text-indent: -999px; +} +#page_top a:before { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + font-family: 'icon'; + line-height: 70px; + font-size: 25px; + text-align: center; + text-indent: 0; +} +#page_top a:hover { + color: #fff; + background: #e7604a; + border-color: #a6240d; +} +#page_top a.ico-home:before { content: "\e900"; } +#page_top a.ico-dev:before { content: "\e995"; } + + + +#wrapper { + display: table-cell; + position: relative; + vertical-align: top; + min-height: 100%; +} + + + +#gnb { + display: block; + position: relative; + padding-top: 20px; + font-family: 'Noto Sans KR', sans-serif; +} +#gnb > ul > li > a { + display: block; + padding: 10px 20px; + color: #9da4b3; + font-size: 15px; + text-decoration: none; +} +#gnb .gnb_2dli { position: relative; } +#gnb .gnb_2dli > a { + display: block; + padding: 10px 20px 10px 25px; + color: #acaeb2; + font-size: 13px; + +} +#gnb .gnb_2dli > a:before { + font-family: 'icon'; + padding-right: 7px; +} +#gnb .gnb_2dli.check:after { + content: "\ea10"; + font-family: 'icon'; + display: block; + position: absolute; + top: 0; + right: 10px; + line-height: 39px; + color: #e76148; +} + +#gnb .gnb_2dli > a:hover { + color: #fff; + background: #484c58; + text-decoration: none; + font-weight: 100; +} + +#gnb .gnb_2dul { + display: none; + background: #262931; +} +#gnb .gnb_2dli.check > a:after { + content: ""; + display: block; + position: absolute; +} + +#gnb .gnb_2dli > a:before { content: "\e994"; } +#gnb .gnb_2dli > a[data-text="기본환경설정"]:before { content: "\e994"; } +#gnb .gnb_2dli > a[data-text="팝업레이어관리"]:before { content: "\e925"; } +#gnb .gnb_2dli > a[data-text="세션파일 일괄삭제"]:before { content: "\e94d"; } +#gnb .gnb_2dli > a[data-text="캐시파일 일괄삭제"]:before { content: "\e94d"; } +#gnb .gnb_2dli > a[data-text="썸네일파일 일괄삭제"]:before { content: "\e90e"; } +#gnb .gnb_2dli > a[data-text="커뮤니티 설정"]:before { content: "\e96f"; } +#gnb .gnb_2dli > a[data-text="화면 설정"]:before { content: "\e956"; } +#gnb .gnb_2dli > a[data-text="디자인 설정"]:before { content: "\e90c"; } +#gnb .gnb_2dli > a[data-text="메인슬라이드 관리"]:before { content: "\e913"; } + +#gnb .gnb_2dli > a[data-text="회원관리"]:before { content: "\e923"; } +#gnb .gnb_2dli > a[data-text="접속자집계"]:before { content: "\e99c"; } +#gnb .gnb_2dli > a[data-text="접속자검색"]:before { content: "\e986"; } +#gnb .gnb_2dli > a[data-text="접속자로그삭제"]:before { content: "\e988"; } +#gnb .gnb_2dli > a[data-text="투표관리"]:before { content: "\e926"; } + +#gnb .gnb_2dli > a[data-text="게시판관리"]:before { content: "\e9ba"; } +#gnb .gnb_2dli > a[data-text="게시판그룹관리"]:before { content: "\e9bc"; } +#gnb .gnb_2dli > a[data-text="내용관리"]:before { content: "\e908"; } +#gnb .gnb_2dli > a[data-text="이모티콘관리"]:before { content: "\e9e1"; } + +#gnb .gnb_2dli > a[data-text="프로필 양식 관리"]:before { content: "\ea72"; } +#gnb .gnb_2dli > a[data-text="캐릭터 관리"]:before { content: "\e9b2"; } +#gnb .gnb_2dli > a[data-text="타이틀 관리"]:before { content: "\e935"; } +#gnb .gnb_2dli > a[data-text="보유타이틀 관리"]:before { content: "\e936"; } +#gnb .gnb_2dli > a[data-text="레벨설정 관리"]:before { content: "\ea4f"; } +#gnb .gnb_2dli > a[data-text="경험치 관리"]:before { content: "\e993"; } +#gnb .gnb_2dli > a[data-text="커플 관리"]:before { content: "\e9da"; } +#gnb .gnb_2dli > a[data-text="스탯 관리"]:before { content: "\e99d"; } + +#gnb .gnb_2dli > a[data-text="상점관리"]:before { content: "\e93a"; } +#gnb .gnb_2dli > a[data-text="아이템관리"]:before { content: "\e99f"; } +#gnb .gnb_2dli > a[data-text="아이템 보유현황"]:before { content: "\e9ae"; } +#gnb .gnb_2dli > a[data-text="아이템 구매기록"]:before { content: "\e9ba"; } +#gnb .gnb_2dli > a[data-text="레시피 관리"]:before { content: "\e996"; } +#gnb .gnb_2dli > a[data-text="소지금관리"]:before { content: "\e93f"; } + + + +#container { padding: 25px; } +#fsearch input { margin: 0; } +#fsearch .btn_submit { + border: none; + background: #29c7c9; + color: #fff; + font-size: 13px; + width: 50px; + height: 28px; + cursor: pointer; + line-height: 1.0em; +} \ No newline at end of file diff --git a/AvocadoEdition/adm/css/theme.css b/AvocadoEdition/adm/css/theme.css new file mode 100644 index 0000000..52bd0c5 --- /dev/null +++ b/AvocadoEdition/adm/css/theme.css @@ -0,0 +1,9 @@ +@charset "utf-8"; +html, body {width:100%; height:100%;} +#preview_item{height:50px} +#preview_item ul{margin:0;padding:0;top:0;width:100%;border-bottom:1px solid #eee; margin:0 auto;text-align:center;background:#333;position:fixed;top:0;z-index:999999;width:100%;} +#preview_item ul li{list-style:none;display:inline-block;height:50px;line-height:50px;padding:0 3px;*display:inline; zoom:1;} +#preview_item ul li a{color:#555;padding:0 8px;height:24px;line-height:24px;background:#f2f2f2;display:inline-block;vertical-align:middle;border:1px solid #dcdcdc;} +#preview_item ul li a:hover{background:#ccc;text-decoration:none;border:1px solid #ccc;} +#preview_item ul li button{color:#fff;padding:0 8px;background:#29c7ca;border-radius:0;height:26px;line-height:24px;vertical-align:middle;border:none} +#preview_item ul li button:hover{background:#046b6d;color:#fff;text-decoration:none;} \ No newline at end of file diff --git a/AvocadoEdition/adm/data_backup.php b/AvocadoEdition/adm/data_backup.php new file mode 100644 index 0000000..2563659 --- /dev/null +++ b/AvocadoEdition/adm/data_backup.php @@ -0,0 +1,275 @@ + +
  • 디자인
  • +
  • 캐릭터 정보
  • +
  • 스탯설정
  • +
  • 경험치/포인트
  • +'; + +function get_bakup_list($cate) { + global $g5; + + $backup_list = ''; + + $result = sql_query("select * from {$g5['backup_table']} where ba_cate = '{$cate}'"); + + for($i=0; $bak = sql_fetch_array($result); $i++) { + if($i == 0) { $border = ""; } else { + $border = "border-top: 1px dashed #e1e1e1;"; + } + $backup_list .= "

    + 백업 - ".$bak['ba_title']."   + 삭제 +

    "; + } + + return $backup_list; +} + +$frm_submit = '
    + +
    '; + + +?> + +
    +

    + 현재 사이트에 적용된 각 DB 데이터를 백업 합니다.
    + 이미지 파일은 백업 되지 않습니다. 이미지는 따로 백업 받아 주세요. +

    +
    + +
    + +
    +

    디자인 설정

    + + +
    + + + + + + + + + + + + + + + + + + + +
    + + 디자인 설정 + + 개별 백업 + + +
    + + 메인/메뉴 화면 + + 개별 백업 + + +
    +
    + +
    + + + +
    +

    캐릭터 정보

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + 캐릭터 기본 정보 + + 개별 백업 + + +
    + + 추가 정보 + + 개별 백업 + + +
    + + 옷장 정보 + + 개별 백업 + + +
    + + 타이틀 정보 + + 개별 백업 + + +
    +
    + +
    + + + +
    +

    스탯 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + 스탯 설정 + + 개별 백업 + + +
    + + 캐릭터 스탯 정보 + + 개별 백업 + + +
    +
    + +
    + + + +
    +

    경험치 / 포인트

    + + +
    + + + + + + + + + + + + + + + + + + + + + +
    + + 경험치 내역 + + 개별 백업 + + +
    + + 포인트(화폐) 내역 + + 개별 백업 + + +
    +
    + +
    + + + +
    + + + + diff --git a/AvocadoEdition/adm/data_backup_delete.php b/AvocadoEdition/adm/data_backup_delete.php new file mode 100644 index 0000000..e1f5d89 --- /dev/null +++ b/AvocadoEdition/adm/data_backup_delete.php @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/data_backup_update.php b/AvocadoEdition/adm/data_backup_update.php new file mode 100644 index 0000000..ba93016 --- /dev/null +++ b/AvocadoEdition/adm/data_backup_update.php @@ -0,0 +1,95 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/data_restore.php b/AvocadoEdition/adm/data_restore.php new file mode 100644 index 0000000..770d683 --- /dev/null +++ b/AvocadoEdition/adm/data_restore.php @@ -0,0 +1,256 @@ + +
  • 디자인
  • +
  • 캐릭터 정보
  • +
  • 스탯설정
  • +
  • 경험치/포인트
  • +'; + +function get_bakup_list($cate) { + global $g5; + + $backup_list = ''; + $result = sql_query("select * from {$g5['backup_table']} where ba_cate = '{$cate}' order by ba_id desc"); + + $backup_list .= ""; + + for($i=0; $bak = sql_fetch_array($result); $i++) { + $backup_list .= ""; + } + + return $backup_list; +} + +$frm_submit = '
    + +
    '; + +?> + +
    +

    + 복원파일을 업로드 하여 디자인 설정을 복원합니다.
    + 이미지 파일은 복원 되지 않습니다. 이미지는 따로 올려주세요. +

    +
    + + +
    + +
    +

    디자인 설정

    + + +
    + + + + + + + + + + + + + + + + +
    + + 디자인 설정 + + +
    + + 메인/메뉴 화면 + + +
    +
    + +
    + + + +
    +

    캐릭터 정보

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    + + 캐릭터 기본 정보 + + +
    + + 추가 정보 + + +
    + + 옷장 정보 + + +
    + + 타이틀 정보 + + +
    +
    + +
    + + + +
    +

    스탯 설정

    + + +
    + + + + + + + + + + + + + + + + + + +
    + + 스탯 설정 + + +
    + + 캐릭터 스탯 정보 + + +
    +
    + +
    + + + +
    +

    경험치 / 포인트

    + + +
    + + + + + + + + + + + + + + + + + + +
    + + 경험치 내역 + + +
    + + 포인트(화폐) 내역 + + +
    +
    + +
    + + + +
    + + + + diff --git a/AvocadoEdition/adm/data_restore_update.php b/AvocadoEdition/adm/data_restore_update.php new file mode 100644 index 0000000..9c218a2 --- /dev/null +++ b/AvocadoEdition/adm/data_restore_update.php @@ -0,0 +1,35 @@ + 0) { + + if($cate == 'content') { + sql_query("delete from {$g5['content_table']} where co_id = 'site_menu' or co_id = 'site_main'"); + } else { + sql_query("delete from ".G5_TABLE_PREFIX.$cate); + } + + for ($i=0; $i diff --git a/AvocadoEdition/adm/design_form.php b/AvocadoEdition/adm/design_form.php new file mode 100644 index 0000000..520aaa4 --- /dev/null +++ b/AvocadoEdition/adm/design_form.php @@ -0,0 +1,1833 @@ + +
  • 화면 디자인
  • +
  • 메뉴 디자인
  • +
  • 버튼 디자인
  • +
  • 테이블(게시판) 디자인
  • +
  • 로드비 디자인
  • +
  • 기타 디자인
  • +'; + +$frm_submit = '
    + +
    '; + + +// 현재 : 번호 42번까지 사용 중 + +?> + +
    + + +
    +

    화면 디자인 설정

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 헤더사용 + + - + + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 로고 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 모바일 로고 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    +
    + 헤더 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    + + 고정   + +
    + 모바일 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    +
    + 모바일 헤더 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    + + 고정   + +
    +
    +
    + + + +
    +

    메뉴 디자인 설정

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 메뉴 위치 + + - + + + + +
    + 가로사이즈 + + - + + + + px +
    + 세로사이즈 + + - + + + + px +
    + 메뉴 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    + + 고정   + +
    + 모바일 메뉴 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    + + 고정   + +
    + 폰트색상 + + 일반상태 + + + + 폰트색상   + +    + 폰트크기   px + +
    + 마우스 오버 + + 폰트색상   + +    + 폰트크기   px +
    +
    +
    + + + +
    +

    테이블(게시판)디자인

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 전체테이블 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 목록-제목 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 목록-항목 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 양식-제목 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 양식-내용 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    +
    +
    + + + +
    +

    버튼 디자인 설정

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 기본버튼 + + 일반상태 + + + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    + 마우스 오버 + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    + 포인트버튼 + + 일반상태 + + + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    + 마우스 오버 + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    + 기타버튼 + + 일반상태 + + + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    + 마우스 오버 + + 텍스트색상   + +    + + 배경색상   + +    + + 라인색상   + +
    +
    +
    + + + +
    +

    로드 게시판 디자인 설정

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 전체 페이지 배경 + + + + + 이미지 미등록 + + + + + 직접등록   +
    + 외부경로   +
    + 색상코드   + +    + + 배경반복   + +    + + 배경위치   + +    + + 배경크기   + +    + + 고정   + +
    + 공지사항 박스 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 접속자 카운터 + + - + + + + +
    + 리스트영역 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 게시물 영역 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +    + 하단여백   px +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 로그 영역 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 코멘트 영역 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + 각 코멘트 영역 + + 배경/폰트/여백 + + + + 배경색상   + +    + 폰트색상   + +    + 하단여백   px +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    + [작성자] 폰트 + + - + + + + 색상코드   + +    + 폰트크기   px +
    + [로그작성자] 폰트 + + - + + + + 색상코드   + +    + 폰트크기   px +    + 접두문자   +    + 접미문자   +
    + [날짜] 폰트 + + - + + + + 색상코드   + +    + 폰트크기   px +
    + [외부링크] 폰트 + + - + + + + 색상코드   + +
    + [멤버호출] 폰트 + + - + + + + 색상코드   + +
    + [로그앵커] 폰트 + + - + + + + 색상코드   + +
    + [해시태그] 폰트 + + - + + + + 색상코드   + +
    +
    +
    + + + +
    +

    기타 디자인 설정

    + + +
    +

    다양한 디자인을 적용하기 위해선 직접 HTML / CSS 파일을 수정해 주시길 바랍니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    홈페이지 기본환경 설정
    + 기본색 + + - + + + + 색상코드   + +
    + 전경색 + + - + + + + 색상코드   + +
    + 강조색 + + - + + + + 색상코드   + +
    + 입력폼 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +    + 라인색상   + +
    + 모서리 라운드 + + 좌측상단 px +    + 우측상단 px +    + 우측하단 px +    + 좌측하단 px +
    + 기본박스 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +    + 라인색상   + +
    + 모서리 라운드 + + 좌측상단 px +    + 우측상단 px +    + 우측하단 px +    + 좌측하단 px +
    + 이퀄라이저 색상 + + - + + + + 막대색상   + +    + 외부광선   + +
    + 서브메뉴 + + 배경/폰트 + + + + 배경색상   + +    + 폰트색상   + +    + 오버색상   + +
    + 라인 + + 라인색상   + +    + + 라인타입   + +    + + 라인굵기   px +      + + /> + + + /> + + + /> + + + /> + +
    +
    +
    + + + + +
    + + + + diff --git a/AvocadoEdition/adm/design_form_css.php b/AvocadoEdition/adm/design_form_css.php new file mode 100644 index 0000000..74d759e --- /dev/null +++ b/AvocadoEdition/adm/design_form_css.php @@ -0,0 +1,777 @@ + +@charset "utf-8"; +/*************************************************************** + Design Manager Setting Style: 자동생성 CSS +--------------------------------------------------------------- + - 최종 수정일 : +***************************************************************/ + + + + +body, +.txt-default { color: ; } + + +a, +.txt-point { color: ; } + + + + +@media all and (min-width: px) { + html.single:before { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } +} + +@media all and (max-width: px) { + html.single:before { + + background-image: url(''); + + background-image: none; + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } +} + + + +@media all and (min-width: px) { + #header { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } + + #gnb { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } + + #gnb_control_box { display: none; } +} + +@media all and (max-width: px) { + + #header { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } + + #gnb { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + + } + + #gnb_control_box { + display: block; + } +} + + + +#header, +#footer { display: none !important; } +#body { margin: 0 !important; } + + + +#body { margin-left: px; } +#header { + position: fixed; + top: 0; + left: 0; + bottom: 0; + overflow-y: auto; + width: px; + +} +#logo { + padding:20px 0; + text-align: center; +} + + + + +#header { + position: relative; + margin: 0; + padding: 0; + clear: both; + height: px; +} +#header .fix-layout { height: 100%; } +#logo { + display: block; + position: absolute; + top: 50%; + left: 0%; + transform: translateY(-50%); +} + + +/*#gnb { float: right; }*/ +#gnb, +#gnb * { + color: ; + font-size: px; +} +#gnb a:hover { + color: ; + font-size: px; +} + + + + + + + +*::-webkit-scrollbar-track { background-color: ; } + +*::-webkit-scrollbar-thumb { background: ; } + + + + +* { outline-color: ; } +::selection { background:; } +::-moz-selection { background:; } +::-webkit-selection { background:; } + + + +::selection { color:; } +::-moz-selection { color:; } +::-webkit-selection { color:; } + + + + + + +.ui-btn { + color: ; + background: ; + border-color: ; +} +.ui-btn:hover { + color: ; + background: ; + border-color: ; +} + +.ui-btn.point { + color: ; + background: ; + border-color: ; +} +.ui-btn.point:hover { + color: ; + background: ; + border-color: ; +} + +.ui-btn.etc { + color: ; + background: ; + border-color: ; +} +.ui-btn.etc:hover { + color: ; + background: ; + border-color: ; +} +.swiper-pagination-bullet-active {background: ;} + + + +.pg_wrap .pg_page { + color: ; + background: ; + border-color: ; +} +.pg_wrap .pg_page:hover { + color: ; + background: ; + border-color: ; +} + +.pg_wrap .pg_current, +.pg_wrap .pg_current:hover { + color: ; + background: ; + border-color: ; +} + + + + + + +.bar-equalizer i { + + background: ; + + -webkit-box-shadow: 0px 0px 3px 0px ; + -moz-box-shadow: 0px 0px 3px 0px ; + box-shadow: 0px 0px 3px 0px ; + +} + + + + +.status-bar dd p { + background: ; +} +.status-bar dd p span { + background: ; + opacity: .5; +} +.status-bar dd p sup { + background: ; +} +.status-bar dd p i { + color: ; +} + + + + +hr.line { + background: ; +} + + + + + +.form-input, +input[type="file"], +input[type="text"], +input[type="number"], +input[type="password"], +textarea, +select { + color: ; + background: ; + border-color: ; + + border-top-left-radius:px; + border-top-right-radius:px; + border-bottom-right-radius:px; + border-bottom-left-radius:px; +} + +::-webkit-input-placeholder { + color: ; +} +:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ + color: ; + opacity: 1; +} +::-moz-placeholder { /* Mozilla Firefox 19+ */ + color: ; + opacity: 1; +} +:-ms-input-placeholder { /* Internet Explorer 10-11 */ + color: ; +} + + +*::-webkit-input-placeholder { color:#000; } +textarea:-moz-placeholder, input:-moz-placeholder { color:#000; } +input:-webkit-autofill, +textarea:-webkit-autofill, +select:-webkit-autofill { + background-color: !important; + color: ; +} + + + + + +.flex-control-paging a { background: ; } +.flex-control-paging a.flex-active { background: ; } + + + + + +.theme-box { + + background-color: ; + + border: 1px solid ; + + color: ; + + border-top-left-radius:px; + border-top-right-radius:px; + border-bottom-right-radius:px; + border-bottom-left-radius:px; +} +.theme-box.no-link a { + + color: ; + +} + + + + +.inven-popup-viewer { + + background-color: ; + + border: 1px solid ; + + color: ; + +} + + + + + +.timeline-Tweet:before { border-top-color: ; } +.TweetAuthor-name { color: ; } + + + + + +#submenu { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} +#submenu a { + color: ; +} +#submenu a:hover { + color: ; +} + + + + + +.theme-list, +.theme-form { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + +/*** Form Area ***/ +.theme-form th { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} +.theme-form td { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + +/*** List Area ***/ +.theme-list th { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} +.theme-list td { + background-color: ; + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + + + + + +#tab_list { border-color: ; } + + + + + +.inventory-list a { + /*border: 1px solid ;*/ + + border: 1px solid ; +} +.inventory-list a i { + /* + background: ; + color: ; + */ + + border: 1px solid ; + background: rgba(0, 0, 0, .7); + color: #fff; +} + + + + + + +#load_log_board { + + background-image: url(''); + + background-color: ; + + background-repeat: ; + + background-position: ; + + background-size: ; + + background-attachment: ; + +} + +.board-notice { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + +#log_list { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + +#log_list .item { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + + + + margin-bottom: px !important; + +} + +#log_list .item .item-inner .ui-pic { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + +} + + + +#log_list .item .item-inner .item-comment { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + + + margin-bottom: px !important; + +} + + +#log_list .item .item-inner .ui-comment { + + background-color: ; + + color: ; + + border--color: ; + border--style: ; + border--width: px; + + + + padding-left: 15px; + padding-right: 15px; + +} + + +#log_list .item .item-inner .co-header p, +#log_list .item .item-inner .co-header p a { + + color: ; + + + font-size: px; + +} + +#log_list .item .item-inner .co-header p.owner, +#log_list .item .item-inner .co-header p.owner a { + + color: ; + + + font-size: px; + +} + +#log_list .item .item-inner .co-footer .date { + + color: ; + + + font-size: px; + +} +#log_list .item .item-inner .co-content .other-site-link { + + color: ; + +} +#log_list .item .item-inner .co-content .link_hash_tag { + + color: ; + +} +#log_list .item .item-inner .co-content .log_link_tag { + + color: ; + +} +#log_list .item .item-inner .co-content .member_call { + + color: ; + +} \ No newline at end of file diff --git a/AvocadoEdition/adm/design_form_update.php b/AvocadoEdition/adm/design_form_update.php new file mode 100644 index 0000000..24e4b58 --- /dev/null +++ b/AvocadoEdition/adm/design_form_update.php @@ -0,0 +1,103 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/emoticon_form_update.php b/AvocadoEdition/adm/emoticon_form_update.php new file mode 100644 index 0000000..fa9cbca --- /dev/null +++ b/AvocadoEdition/adm/emoticon_form_update.php @@ -0,0 +1,28 @@ + diff --git a/AvocadoEdition/adm/emoticon_list.php b/AvocadoEdition/adm/emoticon_list.php new file mode 100644 index 0000000..6b7e9b4 --- /dev/null +++ b/AvocadoEdition/adm/emoticon_list.php @@ -0,0 +1,201 @@ +전체목록'; + +$g5['title'] = '이모티콘 관리'; +include_once ('./admin.head.php'); + +$colspan = 9; + +$po_expire_term = ''; +if($config['cf_point_term'] > 0) { + $po_expire_term = $config['cf_point_term']; +} + +?> + +

    이모티콘 목록

    + +
    + + 전체 건 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; } +?> + + + + + + + '; + + if($i%3) { + for($j = 0; $j < 3-($i%3); $j++) { + echo ""; + } + } + + if($i > 0) { echo ""; } + ?> + +
    목록
    + + + 이미지명령어 이미지명령어 이미지명령어
    + + + "; ?>자료가 없습니다.
    +
    + +
    + +
    + +
    + + + +
    +

    이모티콘 등록

    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/emoticon_list_update.php b/AvocadoEdition/adm/emoticon_list_update.php new file mode 100644 index 0000000..ae0a975 --- /dev/null +++ b/AvocadoEdition/adm/emoticon_list_update.php @@ -0,0 +1,36 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/exp_list.php b/AvocadoEdition/adm/exp_list.php new file mode 100644 index 0000000..4de238f --- /dev/null +++ b/AvocadoEdition/adm/exp_list.php @@ -0,0 +1,263 @@ +전체목록'; + +$mb = array(); +if ($sfl == 'mb_id' && $stx) + $mb = get_member($stx); + +$g5['title'] = $config['cf_exp_name'].' 관리'; +include_once ('./admin.head.php'); + +$colspan = 7; + + +$pg_anchor = ''; + +$frm_submit = '
    + +
    '; +?> + + +
    + + + + + + + +
    +

    지급/회수

    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    지급유형 + + +    + + +
    + + +
    +
    +
    + +
    + +
    + +
    +
    + + +
    +

    내역

    + + +
    + + 전체 건 + +
    + +
    + + + + + +
    +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 오너명캐릭터 이름지급 내용일시 합계
    + + + + +
    자료가 없습니다.
    +
    + +
    + +
    + +
    + + +
    + + + + diff --git a/AvocadoEdition/adm/exp_list_delete.php b/AvocadoEdition/adm/exp_list_delete.php new file mode 100644 index 0000000..beb6276 --- /dev/null +++ b/AvocadoEdition/adm/exp_list_delete.php @@ -0,0 +1,54 @@ + '{$_POST['ex_id'][$k]}' "; + sql_query($sql); + + // 포인트 UPDATE + $sum_point = get_exp_sum($ch_id); + $sql= " update {$g5['character_table']} set ch_exp = '$sum_point' where ch_id = '{$ch_id}' "; + sql_query($sql); + + $rank_info = get_rank_exp($sum_point, $ch_id); + // 기존 랭크에서 변동이 있을 경우에만 실행 + if($ch['ch_rank'] != $rank_info['rank']) { + $state_point = $ch['ch_point'] + $rank_info['add_point']; + // 스텟 포인트 변동 사항 및 랭크 변동사항 저장 + $rank_up_sql = " update {$g5['character_table']} set ch_rank = '{$rank_info['rank']}', ch_point = '{$state_point}' where ch_id = '$ch_id' "; + sql_query($rank_up_sql); + } +} + +goto_url('./exp_list.php?'.$qstr); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/exp_update.php b/AvocadoEdition/adm/exp_update.php new file mode 100644 index 0000000..8ed1905 --- /dev/null +++ b/AvocadoEdition/adm/exp_update.php @@ -0,0 +1,49 @@ + $ch['ch_exp'])) continue; + + insert_exp($ch['ch_id'], $ex_point, $ex_content, $action); + } + +} else { + // 개별지급 + if(!$ch_id && $ch_name) { + $ch = sql_fetch("select ch_id, ch_name, ch_exp from {$g5['character_table']} where ch_name = '{$ch_name}'"); + $ch_id = $ch['ch_id']; + } else { + $ch = sql_fetch("select ch_id, ch_name, ch_exp from {$g5['character_table']} where ch_id = '{$ch_id}'"); + } + + if (!$ch['ch_id']) + alert('존재하는 캐릭터가 아닙니다.'); + + if (($ex_point < 0) && ($ex_point * (-1) > $ch['ch_exp'])) + alert('경험치를 차감하는 경우 현재 경험치보다 작으면 안됩니다.'); + + insert_exp($ch['ch_id'], $ex_point, $ex_content, $action); +} + +goto_url('./exp_list.php?'.$qstr); +?> diff --git a/AvocadoEdition/adm/explorer_list.php b/AvocadoEdition/adm/explorer_list.php new file mode 100644 index 0000000..bf526a7 --- /dev/null +++ b/AvocadoEdition/adm/explorer_list.php @@ -0,0 +1,273 @@ +전체목록'; + +$g5['title'] = '아이템 뽑기 관리'; +include_once('./admin.head.php'); + + +$pg_anchor = ''; + +$frm_submit = '
    + +
    '; + +$colspan = 5; + +if($sch_it_id) { + $sch_it = get_item($sch_it_id); + $sch_it_name = $sch_it['it_name']; + $sch_it_img = $sch_it['it_img']; +} + +?> + +
    + +

    뽑기 설정 목록

    + + +
    + + 등록된 뽑기 설정 수 개 +
    + + +
    + + [ ] 뽑기 설정 +
    + + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 뽑기아이템획득아이템획득구간
    + + + + + + + 이미지 없음 + + + + + + + + 이미지 없음 + + + + + + ~ + 구간 획득 +
    자료가 없습니다.
    +
    + +
    + + +
    +
    + + + + +
    + + +
    +
    + + + + + + + + +

    뽑기 등록

    + + +
    + + + + + + + + + + + + + + + + + + + +
    뽑기 아이템 + + + + + + + + + +
    + +
    획득 아이템 + + +
    +
    획득구간 + ※ 다수의 구간이 겹칠 시,랜덤으로 획득 됩니다.") ?> + + ~ + 구간 획득 +
    +
    + +
    + +
    + +
    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/explorer_list_update.php b/AvocadoEdition/adm/explorer_list_update.php new file mode 100644 index 0000000..25d1fbb --- /dev/null +++ b/AvocadoEdition/adm/explorer_list_update.php @@ -0,0 +1,46 @@ + diff --git a/AvocadoEdition/adm/explorer_update.php b/AvocadoEdition/adm/explorer_update.php new file mode 100644 index 0000000..4eb39b0 --- /dev/null +++ b/AvocadoEdition/adm/explorer_update.php @@ -0,0 +1,40 @@ + diff --git a/AvocadoEdition/adm/faqform.php b/AvocadoEdition/adm/faqform.php new file mode 100644 index 0000000..c09c3b4 --- /dev/null +++ b/AvocadoEdition/adm/faqform.php @@ -0,0 +1,98 @@ + + +
    + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + + + 내용보기 +
    질문
    답변
    +
    + +
    + + 목록 +
    + +
    + + + + diff --git a/AvocadoEdition/adm/faqformupdate.php b/AvocadoEdition/adm/faqformupdate.php new file mode 100644 index 0000000..666400c --- /dev/null +++ b/AvocadoEdition/adm/faqformupdate.php @@ -0,0 +1,45 @@ + diff --git a/AvocadoEdition/adm/faqlist.php b/AvocadoEdition/adm/faqlist.php new file mode 100644 index 0000000..43539db --- /dev/null +++ b/AvocadoEdition/adm/faqlist.php @@ -0,0 +1,95 @@ + + +
    + 등록된 FAQ 상세내용 건 +
    + +
    +
      +
    1. FAQ는 무제한으로 등록할 수 있습니다
    2. +
    3. FAQ 상세내용 추가를 눌러 자주하는 질문과 답변을 입력합니다.
    4. +
    +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    번호제목순서관리
    + 수정 + 삭제 +
    자료가 없습니다.
    + +
    + + + + + diff --git a/AvocadoEdition/adm/faqmasterform.php b/AvocadoEdition/adm/faqmasterform.php new file mode 100644 index 0000000..a7b174f --- /dev/null +++ b/AvocadoEdition/adm/faqmasterform.php @@ -0,0 +1,165 @@ + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + 보기 + 상세보기 + +
    + + 750) + $width = 750; + else + $width = $size[0]; + + echo ' '; + $himg_str = ''; + } + if ($himg_str) { + echo ''; + } + ?> +
    + + 750) + $width = 750; + else + $width = $size[0]; + + echo ''; + $timg_str = ''; + } + if ($timg_str) { + echo ''; + } + ?> +
    상단 내용 + +
    하단 내용 + +
    모바일상단 내용 + +
    모바일하단 내용 + +
    +
    + +
    + + 목록 +
    + +
    + + + + diff --git a/AvocadoEdition/adm/faqmasterformupdate.php b/AvocadoEdition/adm/faqmasterformupdate.php new file mode 100644 index 0000000..001c2b7 --- /dev/null +++ b/AvocadoEdition/adm/faqmasterformupdate.php @@ -0,0 +1,74 @@ + diff --git a/AvocadoEdition/adm/faqmasterlist.php b/AvocadoEdition/adm/faqmasterlist.php new file mode 100644 index 0000000..f5ae0ce --- /dev/null +++ b/AvocadoEdition/adm/faqmasterlist.php @@ -0,0 +1,128 @@ +/data/dbconfig.php 파일에
    $g5[\'faq_table\'] = G5_TABLE_PREFIX.\'faq\';
    $g5[\'faq_master_table\'] = G5_TABLE_PREFIX.\'faq_master\';
    를 추가해 주세요.'); +} + +//자주하시는 질문 마스터 테이블이 있는지 검사한다. +if(!sql_query(" DESCRIBE {$g5['faq_master_table']} ", false)) { + if(sql_query(" DESCRIBE {$g5['g5_shop_faq_master_table']} ", false)) { + sql_query(" ALTER TABLE {$g5['g5_shop_faq_master_table']} RENAME TO `{$g5['faq_master_table']}` ;", false); + } else { + $query_cp = sql_query(" CREATE TABLE IF NOT EXISTS `{$g5['faq_master_table']}` ( + `fm_id` int(11) NOT NULL AUTO_INCREMENT, + `fm_subject` varchar(255) NOT NULL DEFAULT '', + `fm_head_html` text NOT NULL, + `fm_tail_html` text NOT NULL, + `fm_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`fm_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ", true); + } + // FAQ Master + sql_query(" insert into `{$g5['faq_master_table']}` set fm_id = '1', fm_subject = '자주하시는 질문' ", false); +} + +//자주하시는 질문 테이블이 있는지 검사한다. +if(!sql_query(" DESCRIBE {$g5['faq_table']} ", false)) { + if(sql_query(" DESCRIBE {$g5['g5_shop_faq_table']} ", false)) { + sql_query(" ALTER TABLE {$g5['g5_shop_faq_table']} RENAME TO `{$g5['faq_table']}` ;", false); + } else { + $query_cp = sql_query(" CREATE TABLE IF NOT EXISTS `{$g5['faq_table']}` ( + `fa_id` int(11) NOT NULL AUTO_INCREMENT, + `fm_id` int(11) NOT NULL DEFAULT '0', + `fa_subject` text NOT NULL, + `fa_content` text NOT NULL, + `fa_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`fa_id`), + KEY `fm_id` (`fm_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ", true); + } +} + +$g5['title'] = 'FAQ관리'; +include_once (G5_ADMIN_PATH.'/admin.head.php'); + +$sql_common = " from {$g5['faq_master_table']} "; + +// 테이블의 전체 레코드수만 얻음 +$sql = " select count(*) as cnt " . $sql_common; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$rows = $config['cf_page_rows']; +$total_page = ceil($total_count / $rows); // 전체 페이지 계산 +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $rows; // 시작 열을 구함 + +$sql = "select * {$sql_common} order by fm_order, fm_id limit {$from_record}, {$config['cf_page_rows']} "; +$result = sql_query($sql); +?> + +
    + 1) {?>처음으로 + 전체 FAQ +
    + +
    +
      +
    1. FAQ는 무제한으로 등록할 수 있습니다
    2. +
    3. FAQ추가를 눌러 FAQ Master를 생성합니다. (하나의 FAQ 타이틀 생성 : 자주하시는 질문, 이용안내..등 )
    4. +
    5. 생성한 FAQ Master 의 제목을 눌러 세부 내용을 관리할 수 있습니다.
    6. +
    +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    ID제목FAQ수순서관리
    + 수정 + 보기 + 삭제 +
    자료가 한건도 없습니다.
    +
    + + + + diff --git a/AvocadoEdition/adm/file_list.php b/AvocadoEdition/adm/file_list.php new file mode 100644 index 0000000..b16e3d6 --- /dev/null +++ b/AvocadoEdition/adm/file_list.php @@ -0,0 +1,18 @@ + + + + + + diff --git a/AvocadoEdition/adm/head.sub.php b/AvocadoEdition/adm/head.sub.php new file mode 100644 index 0000000..51f2b67 --- /dev/null +++ b/AvocadoEdition/adm/head.sub.php @@ -0,0 +1,62 @@ + + + + + + + + + + + + +<?php echo $g5_head_title; ?> + + + + + + + + + + + + + diff --git a/AvocadoEdition/adm/img/ajax_loader.gif b/AvocadoEdition/adm/img/ajax_loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..5169619bedb26c4f74dc2738b449b0c72c6927ce GIT binary patch literal 45592 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 G1LH$2w0A`)Y@4 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/check.png b/AvocadoEdition/adm/img/check.png new file mode 100644 index 0000000000000000000000000000000000000000..c3c6abd9df806916b5279a72627984e579c2d71d GIT binary patch literal 7401 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/close.gif b/AvocadoEdition/adm/img/close.gif new file mode 100644 index 0000000000000000000000000000000000000000..143c0bd1217e5197fa731996370d013d55b7e21b GIT binary patch literal 200 zcmZ?wbhEHbeWk^E>%=iNJvPCii$EYF#P}jA4nnt z#h)x-t`3L<*~!4_x?mY&QsksZg1*ZlY&$z*B%{M3)TT1$K9=F mwddf=Q;u1Fi-Rs0b#2>o=cBhZ69>1-(uEqVEAo9g7_0%fEk|Ym literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/close.png b/AvocadoEdition/adm/img/close.png new file mode 100644 index 0000000000000000000000000000000000000000..73348e6839bad6986b85448cb216b62c6a59dbe6 GIT binary patch literal 1086 zcmbVLOK8+U7!C++Ew;UQsR)iKqCz*x>?6AyyVhi9V;9|8w=1n8+BBJNLpPb2Oxix(dk@d4rs6huLh;>ly3w7bA?^(|NQyC?|+{i=-=Dc zx~Y}pxVC&BDzdXZlv|qE_tJ;sGwkT3xnVj;#%R^>F{fH&6ob5DlyMOo*3^loxQFA` zjoGDPI$YSVn8Xo`&_<{^9z%0nPjAgL%n3}vC@$M>hF`e&B5u&tU_dx9ecPipaY4vvjFL&3;aQ~1DL7uCutMwx z^+K_di8aF$p&*Hl6XvyK9nd2F8^)^EL21gvVi5;q(l=Q@#=06{R=c$wg@!B|<$!Oq zrWh4O%t;5kG>8hU6VFR0Y18TS?ZuqsC-#S)W6RTu>Y*6Bt2&ptCU|^h35{wfM zWCvxiW5{+bQVn*7?ODziVc$N9E!`&$SgNmLujXGusYDvZVG_w<-szN{(liyuvQSTE zRgJG>t^cW+$bu2W;rM4*8Y(t{p|~>o?6R^v*kv2zv(*TWUAe>7%FQFSRC{;r!u$4l z(2~8mxcI#L)3zt)4sY&gTL1WB3qseMOXVZY9C>taW_J4*`^J{fEpK1kvg5*JW#Pfr zA7tO$=}zRdfm0vB-OJ_tvyE55!Pf)dMrJD;O5UzLuaq;l7k|C^di3Y_u6geFbfF`1 R{?N;Cqw~3bG^dTs{sG$3T}c1{ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/hd_bg.jpg b/AvocadoEdition/adm/img/hd_bg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..345d89cc5aa2857fcfc59172867bf868922f3f1c GIT binary patch literal 8188 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/link_icon.gif b/AvocadoEdition/adm/img/link_icon.gif new file mode 100644 index 0000000000000000000000000000000000000000..7a99c80a1f071a6285ca12c4e76c6e1b6e93c321 GIT binary patch literal 53 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 B6leed literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/logo.png b/AvocadoEdition/adm/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..40c69067e38490cfde57f6e9c720e09715225439 GIT binary patch literal 2252 zcmbVOX;c&E8cqr*LL)`#je?XA3$kUIBm@#!E?JN$LCP9Lk&sLvLNXx>381Lpl2`!& zfr2Qd9<(Z;#!7La1Wa**8*gnvTR=pqA_^C*hzim{#e08vde7;cnfaD^p66Y@_dREH z;bE&#R`ym11OmkgVMV}WAp8K9^We86I{hR(ELF03%1B70RP*H^B1i}&ff$a2pA1HT zd|_t#RnQNCFcXQRcuF2OlrDfIc>XK~uaU@LHUi-nsFCpnsh|>*1SX56{@BqAEm(|L z=#P!{<`TIwCYT})$&!PSSz%FvtW*I_hz$(D_-W{{fCNHATqZ0^fwHmJ`;~{x60ie-nvl=844o2VcU>EbQsq5F|1#_r0)G@h(wt$_N_1i~!(?1c_uet~Y3f zG6MXs8y`d~qB3P5Ap%rDD!BkY57F{DGMu}=HZ%)_y`is_i{V4zr?DV`N&-ri9F{*8 z{(={Zg>)9vC&<^A!Stn(8EhW_U{FW^n*oq~7{S3zlCSri#)r5Rz?V!8rn1P4AQ}L$ zeSC>b7L7`y1d+)MB8|eB<8q`5C0{B4=j@7MyYINnzvR-Ha*(ftW1}F@cLlVrJ{L;lAu+IkmU)*oG!oQO<0_+T7 zwmAN$Smw6i3Y?w3FMW9NzIi|?+%a;vHAb^_M-T|}DGnLyw&YvphS1u` zI=d{)b`dFOZO+<&jdv~t4xKGO6DrU%`X@&czwv%Y1 zMW^QAnq@mM8)O& z7CxYK8I36Rs_sUh8=5y++N|XCs}ffm3xaZ7IntIwd(+Ue)2Ux6fUS>kP^zI65#Bdk z>AZ45zY70&$w)SJSbcATd1c(S{JE9&!73+E8{eFi8CYKaoxS0uskJI$k!kS*SxfMG zS3JY^bnbIS=Jn+xzdT4a#trbNaHHQNGs-7z#}@4eoK|QyG-se<8XPhd)M1PBNd!}-Qt)SV#^*>K$W!mA{%@TW&PfJx9jvdm_1%K*u&0NZX;UlPEO z6y~N~T2NRwq<{V8CmP1)1CyWiw6qDU^~pQc7n9GiHk{b=AbyK;z<8741m$BQ4v~{9 z3YkDoT^sWDtY+`;JJTl!a@?QAL$xy(Q8la_?m` zJRF@{OF!mQE_Kx#jGi?bv+KC|mlyrgiD|i?Ig};bzQuDc9@IHWjus039pzCPyX%LNBM0=M(zLW5v`=1MUdzP9#J>`! z2HM)%yenT_&DbGmy3-c@7>B?2a)nN>8qEHU()eS0@I(3b_D6if?iVMm%9}%t&$#)F z$}6Z5qtQ6u@194#DSB|4Dl}h$99U?E?^dOBdTc$}gce*Z`Ua?R^KqMuUX(!3HKWAM zGc9+&eeEBy9n}^@2aIEMP2IRNc#lo9rIogez1tr)vSx43W7_lL=-s|gqmJThay m*?#HII$7sSF>)q;8xnD_g}t(lt-U<^f5Bmgu^JeOxqkwAq?_{q literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/service_img1.jpg b/AvocadoEdition/adm/img/service_img1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4a603f4fa25c03ef8f06b5271db600e6fa12c619 GIT binary patch literal 6634 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/service_img2.jpg b/AvocadoEdition/adm/img/service_img2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3fc0f5055b920e31b7826183e9eeceb6d27b2ecd GIT binary patch literal 7259 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/svc_btn_04.jpg b/AvocadoEdition/adm/img/svc_btn_04.jpg new file mode 100644 index 0000000000000000000000000000000000000000..29d8649087b2b66122973ae530a35a48720f4b8e GIT binary patch literal 3221 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/svc_btn_05.jpg b/AvocadoEdition/adm/img/svc_btn_05.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7bfcd880c5201280eefd1a59b52fdc68376a5cae GIT binary patch literal 4763 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 byVpeiJi6@s+xcd8``3T>7jJA5WUvMR)k{(I literal 0 HcmV?d00001 diff --git a/AvocadoEdition/adm/img/ts02.gif b/AvocadoEdition/adm/img/ts02.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a48974a39cdb2d2fc2093bd200065e8b36bc87d GIT binary patch literal 188 zcmV;t07L&rNk%w1VHf}y0J8u9|NsBo+}xX+n|F72+uPfKfPlcj!0qkrcifAb=pWoiXggZR4Urqju}8IER6O2=wRZJ;=&stB2d(oIQbK + + + + + diff --git a/AvocadoEdition/adm/index.php b/AvocadoEdition/adm/index.php new file mode 100644 index 0000000..34cfdca --- /dev/null +++ b/AvocadoEdition/adm/index.php @@ -0,0 +1,269 @@ + '' {$sql_order} "; +$row = sql_fetch($sql); +$leave_count = $row['cnt']; + +// 차단회원수 +$sql = " select count(*) as cnt {$sql_common} {$sql_search} and mb_intercept_date <> '' {$sql_order} "; +$row = sql_fetch($sql); +$intercept_count = $row['cnt']; + +$sql = " select * {$sql_common} {$sql_search} {$sql_order} limit {$new_member_rows} "; +$result = sql_query($sql); + +$colspan = 12; +?> + +
    +

    시스템 페이지 링크 안내

    + +
    + + + + + + + + + + + + + + + + + + + + + + +
    멤버목록/member신청자목록/member/ready.php
    커플목록/couple상점/shop
    마이페이지/mypage현재접속자/current_connect.php
    +
    +
    + +
    + + +
    +

    신규가입회원 건 목록

    +
    + 총회원수 명 중 차단 명, 탈퇴 : 명 +
    + +
    + + + + + + + + + + + + + + + + + + '.$row2['cnt'].''; + + if ($is_admin == 'group') + { + $s_mod = ''; + $s_del = ''; + } + else + { + $s_mod = '수정'; + $s_del = '삭제'; + } + $s_grp = '그룹'; + + $leave_date = $row['mb_leave_date'] ? $row['mb_leave_date'] : date("Ymd", G5_SERVER_TIME); + $intercept_date = $row['mb_intercept_date'] ? $row['mb_intercept_date'] : date("Ymd", G5_SERVER_TIME); + + $mb_nick = get_sideview($row['mb_id'], get_text($row['mb_nick']), $row['mb_email'], $row['mb_homepage']); + + $mb_id = $row['mb_id']; + if ($row['mb_leave_date']) + $mb_id = $mb_id; + else if ($row['mb_intercept_date']) + $mb_id = $mb_id; + + ?> + + + + + + + + + + + + + '; + ?> + +
    신규가입회원
    회원아이디이름닉네임권한소지금수신공개인증차단그룹
    자료가 없습니다.
    +
    + + + +
    + + + + +
    +

    최근 소지금 발생내역

    +
    + 전체 건 중 건 목록 +
    + +
    + + + + + + + + + + + + + + + '; + $link2 = ''; + } + ?> + + + + + + + + + + + + '; + ?> + +
    최근 소지금 발생내역
    회원아이디이름닉네임일시소지금 내용소지금소지금합
    자료가 없습니다.
    +
    + + +
    + + diff --git a/AvocadoEdition/adm/intro_form.php b/AvocadoEdition/adm/intro_form.php new file mode 100644 index 0000000..54b1c25 --- /dev/null +++ b/AvocadoEdition/adm/intro_form.php @@ -0,0 +1,121 @@ + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    인트로 이미지 + + + + 이미지 없음 + + + 직접등록   +
    + 외부경로   +
    인트로 모바일 이미지 + + + + 이미지 없음 + + + 직접등록   +
    + 외부경로   +
    대체텍스트 + +
    + + + " id="bn_begin_chk" onclick="if (this.checked == true) this.form.bn_begin_time.value=this.form.bn_begin_chk.value; else this.form.bn_begin_time.value = this.form.bn_begin_time.defaultValue;"> + +
    + + + " id="bn_end_chk" onclick="if (this.checked == true) this.form.bn_end_time.value=this.form.bn_end_chk.value; else this.form.bn_end_time.value = this.form.bn_end_time.defaultValue;"> + +
    + + +
    + +
    + +
    + + 목록 +
    + +
    + + diff --git a/AvocadoEdition/adm/intro_form_update.php b/AvocadoEdition/adm/intro_form_update.php new file mode 100644 index 0000000..f91e228 --- /dev/null +++ b/AvocadoEdition/adm/intro_form_update.php @@ -0,0 +1,88 @@ + diff --git a/AvocadoEdition/adm/intro_list.php b/AvocadoEdition/adm/intro_list.php new file mode 100644 index 0000000..9958460 --- /dev/null +++ b/AvocadoEdition/adm/intro_list.php @@ -0,0 +1,120 @@ + + +
    + 등록된 이미지 개 +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + "; + $bn_img_obj .= ""; + if($link_tag) $bn_img_obj .= ""; + } + + $bn_begin_time = substr($row['bn_begin_time'], 2, 14); + $bn_end_time = substr($row['bn_end_time'], 2, 14); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + '; + } + ?> + +
    목록
    ID이미지대체텍스트시작일시종료일시출력순서관리
    + 수정 + 삭제 +
    자료가 없습니다.
    + +
    + + + + + + diff --git a/AvocadoEdition/adm/inventory_list.php b/AvocadoEdition/adm/inventory_list.php new file mode 100644 index 0000000..7c6d34b --- /dev/null +++ b/AvocadoEdition/adm/inventory_list.php @@ -0,0 +1,254 @@ +전체목록'; + +$ch = array(); +if ($sfl == 'ch_id' && $stx) + $ch = get_member($stx); + +$g5['title'] = '아이템 보유현황 관리'; +include_once ('./admin.head.php'); + +$colspan = 8; + +if (strstr($sfl, "ch_id")) + $ch_id = $stx; +else + $ch_id = ""; + + +$pg_anchor = ''; + +$frm_submit = '
    + +
    '; + +?> + +
    + + + + + + + + +
    +

    캐릭터 아이템 지급

    + + +
    + + + + + + + + + + + + + + + + + + + +
    지급유형 + + +    + + +
    캐릭터 이름 + + + +
    +
    아이템 이름 + + +
    +
    +
    + +
    + + +
    + +
    +

    아이템 보유 현황

    + + +
    + + 전체 건 +
    + +
    + + + + + +
    + +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 소유자아이템 이름보낸사람메모
    + + + + + + + + 이미지 없음 + + + +
    자료가 없습니다.
    +
    + +
    + +
    + +
    + + + +
    + + + + + diff --git a/AvocadoEdition/adm/inventory_list_delete.php b/AvocadoEdition/adm/inventory_list_delete.php new file mode 100644 index 0000000..ce07491 --- /dev/null +++ b/AvocadoEdition/adm/inventory_list_delete.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/inventory_update.php b/AvocadoEdition/adm/inventory_update.php new file mode 100644 index 0000000..f05d208 --- /dev/null +++ b/AvocadoEdition/adm/inventory_update.php @@ -0,0 +1,54 @@ + diff --git a/AvocadoEdition/adm/item_form.php b/AvocadoEdition/adm/item_form.php new file mode 100644 index 0000000..9c086bf --- /dev/null +++ b/AvocadoEdition/adm/item_form.php @@ -0,0 +1,308 @@ +필수'; + $item['it_use'] = 'Y'; + + +} else if ($w == 'u') { + + $html_title .= ' 수정'; + $item = sql_fetch("select * from {$g5['item_table']} where it_id = '{$it_id}'"); + if (!$item['it_id']) + alert('존재하지 않는 아이템 입니다.'); + $readonly = 'readonly'; +} + +$g5['title'] = $html_title; +include_once ('./admin.head.php'); + +$pg_anchor = ''; + + +$frm_submit = '
    + + 목록'.PHP_EOL; +$frm_submit .= '
    '; + +?> + +
    + + + + + + + + +
    +

    아이템 기본 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    아이템 기본 설정
    사용여부 + /> +
    아이템 분류 + +
    아이템 기능 + 기능종류 + + + +    + 뽑기 아이템 설정하러 가기 + +
    + 적용값 + + + ;"> + 스탯 : + + + + + + +
    아이템 이름 + +
    아이템 이미지 + + + + 이미지 없음 + + + 직접등록   +
    + 외부경로   +
    상세이미지 + + + + 이미지 없음 + + + 직접등록   +
    + 외부경로   +
    아이템 설명 + +
    아이템 효과 + +
    되팔기 설정사용여부 + /> + +
    가격 + +
    아이템 속성 + /> + + + /> + + + /> + + + /> + + + /> + + + + + +
    +
    +
    + + + + +
    +

    탐색설정

    + +
    + + + + + + + + + + + + + + + + + + +
    아이템 기본 설정
    탐색획득 + 탐색사용여부 + + /> + +
    + 회득 구간 설정 + + ※ 다수의 구간이 겹칠 시,랜덤으로 획득 됩니다.") ?> + + ~ + 구간 획득 +
    +
    +
    + + + +
    + + + + + diff --git a/AvocadoEdition/adm/item_form_update.php b/AvocadoEdition/adm/item_form_update.php new file mode 100644 index 0000000..872b525 --- /dev/null +++ b/AvocadoEdition/adm/item_form_update.php @@ -0,0 +1,104 @@ + diff --git a/AvocadoEdition/adm/item_list.php b/AvocadoEdition/adm/item_list.php new file mode 100644 index 0000000..3070585 --- /dev/null +++ b/AvocadoEdition/adm/item_list.php @@ -0,0 +1,267 @@ +전체목록'; + +$g5['title'] = '아이템 관리'; +include_once('./admin.head.php'); + +$colspan = 15; +?> + +
    + + 추가된 아이템 수 개 +
    + +
    + + + + + + + + + + + +
    + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 분류기능아이템귀속영구인벤자비레시피되팔기사용관리
    + + + + + + + + + + + + + + 이미지없음 + + + + + > + + > + + > + + > + + > + + > + + + + > + + + +
    자료가 없습니다.
    +
    + +
    + + + + +
    + +
    + + + + + + diff --git a/AvocadoEdition/adm/item_list_update.php b/AvocadoEdition/adm/item_list_update.php new file mode 100644 index 0000000..0487e38 --- /dev/null +++ b/AvocadoEdition/adm/item_list_update.php @@ -0,0 +1,59 @@ + diff --git a/AvocadoEdition/adm/level_form_update.php b/AvocadoEdition/adm/level_form_update.php new file mode 100644 index 0000000..891bebe --- /dev/null +++ b/AvocadoEdition/adm/level_form_update.php @@ -0,0 +1,23 @@ + diff --git a/AvocadoEdition/adm/level_list.php b/AvocadoEdition/adm/level_list.php new file mode 100644 index 0000000..50bf568 --- /dev/null +++ b/AvocadoEdition/adm/level_list.php @@ -0,0 +1,198 @@ +전체목록'; + +$g5['title'] = $config['cf_rank_name'].'설정 관리'; +include_once ('./admin.head.php'); + +$colspan =7; + +$pg_anchor = ''; + +?> + +
    +

    설정 목록

    + + +
    + + 전체 건 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 요구추가 스텟 포인트 
    + + + + + + exp + + +  
    자료가 없습니다.
    +
    + +
    + + +
    + +
    + + + +
    + + +
    +

    설정 등록

    + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/level_list_update.php b/AvocadoEdition/adm/level_list_update.php new file mode 100644 index 0000000..aa8d05f --- /dev/null +++ b/AvocadoEdition/adm/level_list_update.php @@ -0,0 +1,59 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/mail_delete.php b/AvocadoEdition/adm/mail_delete.php new file mode 100644 index 0000000..ad10a77 --- /dev/null +++ b/AvocadoEdition/adm/mail_delete.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/mail_form.php b/AvocadoEdition/adm/mail_form.php new file mode 100644 index 0000000..d2ca36c --- /dev/null +++ b/AvocadoEdition/adm/mail_form.php @@ -0,0 +1,84 @@ + + +

    메일 내용에 {이름} , {닉네임} , {회원아이디} , {이메일} 처럼 내용에 삽입하면 해당 내용에 맞게 변환하여 메일을 발송합니다.

    + +
    + + + + +
    + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    +
    + + + + diff --git a/AvocadoEdition/adm/mail_list.php b/AvocadoEdition/adm/mail_list.php new file mode 100644 index 0000000..681dcc2 --- /dev/null +++ b/AvocadoEdition/adm/mail_list.php @@ -0,0 +1,108 @@ + + +
    +

    + 테스트는 등록된 최고관리자의 이메일로 테스트 메일을 발송합니다.
    + 현재 등록된 메일은 총 건입니다.
    + 주의) 수신자가 동의하지 않은 대량 메일 발송에는 적합하지 않습니다. 수십건 단위로 발송해 주십시오. +

    +
    + + + +
    +
    + + + + + + + + + + + + + + + 미리보기'; + + $num = number_format($total_count - ($page - 1) * $config['cf_page_rows'] - $i); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + "; + ?> + +
    목록
    번호제목작성일시테스트보내기미리보기
    + + + 테스트보내기
    자료가 없습니다.
    +
    + +
    + +
    +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/mail_preview.php b/AvocadoEdition/adm/mail_preview.php new file mode 100644 index 0000000..16abd47 --- /dev/null +++ b/AvocadoEdition/adm/mail_preview.php @@ -0,0 +1,34 @@ +

    ▶ 더 이상 정보 수신을 원치 않으시면 [수신거부] 해 주십시오.

    "; +?> + + + + + +<?php echo G5_VERSION ?> 메일발송 테스트 + + + + +

    + +

    + +

    + +

    + 주의! 이 화면에 보여지는 디자인은 실제 내용이 발송되었을 때 디자인과 다를 수 있습니다. +

    + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/mail_select_form.php b/AvocadoEdition/adm/mail_select_form.php new file mode 100644 index 0000000..e2ffb46 --- /dev/null +++ b/AvocadoEdition/adm/mail_select_form.php @@ -0,0 +1,122 @@ + '' "; +$row = sql_fetch($sql); +$finish_cnt = $row['cnt']; + +$last_option = explode('||', $ma['ma_last_option']); +for ($i=0; $i + +
    + 전체회원 명 , 탈퇴대기회원 명, 정상회원 명 중 메일 발송 대상 선택 +
    + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + +
    대상선택
    회원 ID + > + > + 에서 + 까지 +
    + + +
    + +
    권한 + + 에서 + + 까지 +
    + +
    +
    + +
    + + 목록 +
    +
    + + diff --git a/AvocadoEdition/adm/mail_select_list.php b/AvocadoEdition/adm/mail_select_list.php new file mode 100644 index 0000000..91a9927 --- /dev/null +++ b/AvocadoEdition/adm/mail_select_list.php @@ -0,0 +1,121 @@ + + +
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    목록
    번호회원아이디이름닉네임E-mail
    + +
    + +
    + + 뒤로 +
    + +
    + + diff --git a/AvocadoEdition/adm/mail_select_update.php b/AvocadoEdition/adm/mail_select_update.php new file mode 100644 index 0000000..219e585 --- /dev/null +++ b/AvocadoEdition/adm/mail_select_update.php @@ -0,0 +1,87 @@ +"; +echo "

    메일 발송중 ...

    [끝] 이라는 단어가 나오기 전에는 중간에 중지하지 마세요.

    "; +echo ""; +?> + + + + + +

    ▶ 더 이상 정보 수신을 원치 않으시면 [수신거부] 해 주십시오.

    "; + + mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $to_email, $subject, $content, 1); + + echo "\n"; + //echo "+"; + flush(); + ob_flush(); + ob_end_flush(); + usleep($sleepsec); + if ($cnt % $countgap == 0) + { + echo "\n"; + } + + // 화면을 지운다... 부하를 줄임 + if ($cnt % $maxscreen == 0) + echo "\n"; + } +} +?> + diff --git a/AvocadoEdition/adm/mail_test.php b/AvocadoEdition/adm/mail_test.php new file mode 100644 index 0000000..bc321f5 --- /dev/null +++ b/AvocadoEdition/adm/mail_test.php @@ -0,0 +1,39 @@ +더 이상 정보 수신을 원치 않으시면 [수신거부] 해 주십시오.

    '; + +mailer($config['cf_title'], $member['mb_email'], $member['mb_email'], $subject, $content, 1); + +alert($member['mb_nick'].'('.$member['mb_email'].')님께 테스트 메일을 발송하였습니다. 확인하여 주십시오.'); +?> diff --git a/AvocadoEdition/adm/mail_update.php b/AvocadoEdition/adm/mail_update.php new file mode 100644 index 0000000..ff539cd --- /dev/null +++ b/AvocadoEdition/adm/mail_update.php @@ -0,0 +1,39 @@ + diff --git a/AvocadoEdition/adm/member_delete.php b/AvocadoEdition/adm/member_delete.php new file mode 100644 index 0000000..e536f6c --- /dev/null +++ b/AvocadoEdition/adm/member_delete.php @@ -0,0 +1,29 @@ += $member['mb_level']) + alert("자신보다 권한이 높거나 같은 회원은 삭제할 수 없습니다."); + +check_admin_token(); + +// 회원자료 삭제 +member_delete($mb['mb_id']); + +if ($url) + goto_url("{$url}?$qstr&w=u&mb_id=$mb_id"); +else + goto_url("./member_list.php?$qstr"); +?> diff --git a/AvocadoEdition/adm/member_form.php b/AvocadoEdition/adm/member_form.php new file mode 100644 index 0000000..853121d --- /dev/null +++ b/AvocadoEdition/adm/member_form.php @@ -0,0 +1,280 @@ +필수'; + + $mb['mb_mailling'] = 1; + $mb['mb_open'] = 1; + $mb['mb_level'] = $config['cf_register_level']; + $html_title = '추가'; +} +else if ($w == 'u') +{ + $mb = get_member($mb_id); + if (!$mb['mb_id']) + alert('존재하지 않는 회원자료입니다.'); + + if ($is_admin != 'super' && $mb['mb_level'] >= $member['mb_level']) + alert('자신보다 권한이 높거나 같은 회원은 수정할 수 없습니다.'); + + $required_mb_id = 'readonly'; + $required_mb_password = ''; + $html_title = '수정'; + + $mb['mb_name'] = get_text($mb['mb_name']); + $mb['mb_nick'] = get_text($mb['mb_nick']); + $mb['mb_email'] = get_text($mb['mb_email']); + $mb['mb_homepage'] = get_text($mb['mb_homepage']); + $mb['mb_birth'] = get_text($mb['mb_birth']); + $mb['mb_tel'] = get_text($mb['mb_tel']); + $mb['mb_hp'] = get_text($mb['mb_hp']); + $mb['mb_addr1'] = get_text($mb['mb_addr1']); + $mb['mb_addr2'] = get_text($mb['mb_addr2']); + $mb['mb_addr3'] = get_text($mb['mb_addr3']); + $mb['mb_signature'] = get_text($mb['mb_signature']); + $mb['mb_recommend'] = get_text($mb['mb_recommend']); + $mb['mb_profile'] = get_text($mb['mb_profile']); + $mb['mb_1'] = get_text($mb['mb_1']); + $mb['mb_2'] = get_text($mb['mb_2']); + $mb['mb_3'] = get_text($mb['mb_3']); + $mb['mb_4'] = get_text($mb['mb_4']); + $mb['mb_5'] = get_text($mb['mb_5']); + $mb['mb_6'] = get_text($mb['mb_6']); + $mb['mb_7'] = get_text($mb['mb_7']); + $mb['mb_8'] = get_text($mb['mb_8']); + $mb['mb_9'] = get_text($mb['mb_9']); + $mb['mb_10'] = get_text($mb['mb_10']); +} +else + alert('제대로 된 값이 넘어오지 않았습니다.'); + +// 본인확인방법 +switch($mb['mb_certify']) { + case 'hp': + $mb_certify_case = '휴대폰'; + $mb_certify_val = 'hp'; + break; + case 'ipin': + $mb_certify_case = '아이핀'; + $mb_certify_val = 'ipin'; + break; + case 'admin': + $mb_certify_case = '관리자 수정'; + $mb_certify_val = 'admin'; + break; + default: + $mb_certify_case = ''; + $mb_certify_val = 'admin'; + break; +} + +// 본인확인 +$mb_certify_yes = $mb['mb_certify'] ? 'checked="checked"' : ''; +$mb_certify_no = !$mb['mb_certify'] ? 'checked="checked"' : ''; + +// 성인인증 +$mb_adult_yes = $mb['mb_adult'] ? 'checked="checked"' : ''; +$mb_adult_no = !$mb['mb_adult'] ? 'checked="checked"' : ''; + +//메일수신 +$mb_mailling_yes = $mb['mb_mailling'] ? 'checked="checked"' : ''; +$mb_mailling_no = !$mb['mb_mailling'] ? 'checked="checked"' : ''; + +// SMS 수신 +$mb_sms_yes = $mb['mb_sms'] ? 'checked="checked"' : ''; +$mb_sms_no = !$mb['mb_sms'] ? 'checked="checked"' : ''; + +// 정보 공개 +$mb_open_yes = $mb['mb_open'] ? 'checked="checked"' : ''; +$mb_open_no = !$mb['mb_open'] ? 'checked="checked"' : ''; + +if (isset($mb['mb_certify'])) { + // 날짜시간형이라면 drop 시킴 + if (preg_match("/-/", $mb['mb_certify'])) { + sql_query(" ALTER TABLE `{$g5['member_table']}` DROP `mb_certify` ", false); + } +} else { + sql_query(" ALTER TABLE `{$g5['member_table']}` ADD `mb_certify` TINYINT(4) NOT NULL DEFAULT '0' AFTER `mb_hp` ", false); +} + +if(isset($mb['mb_adult'])) { + sql_query(" ALTER TABLE `{$g5['member_table']}` CHANGE `mb_adult` `mb_adult` TINYINT(4) NOT NULL DEFAULT '0' ", false); +} else { + sql_query(" ALTER TABLE `{$g5['member_table']}` ADD `mb_adult` TINYINT NOT NULL DEFAULT '0' AFTER `mb_certify` ", false); +} + +// 지번주소 필드추가 +if(!isset($mb['mb_addr_jibeon'])) { + sql_query(" ALTER TABLE {$g5['member_table']} ADD `mb_addr_jibeon` varchar(255) NOT NULL DEFAULT '' AFTER `mb_addr2` ", false); +} + +// 건물명필드추가 +if(!isset($mb['mb_addr3'])) { + sql_query(" ALTER TABLE {$g5['member_table']} ADD `mb_addr3` varchar(255) NOT NULL DEFAULT '' AFTER `mb_addr2` ", false); +} + +// 중복가입 확인필드 추가 +if(!isset($mb['mb_dupinfo'])) { + sql_query(" ALTER TABLE {$g5['member_table']} ADD `mb_dupinfo` varchar(255) NOT NULL DEFAULT '' AFTER `mb_adult` ", false); +} + +// 이메일인증 체크 필드추가 +if(!isset($mb['mb_email_certify2'])) { + sql_query(" ALTER TABLE {$g5['member_table']} ADD `mb_email_certify2` varchar(255) NOT NULL DEFAULT '' AFTER `mb_email_certify` ", false); +} + +if ($mb['mb_intercept_date']) $g5['title'] = "차단된 "; +else $g5['title'] .= ""; +$g5['title'] .= '회원 '.$html_title; +include_once('./admin.head.php'); + +// add_javascript('js 구문', 출력순서); 숫자가 작을 수록 먼저 출력됨 +add_javascript(G5_POSTCODE_JS, 0); //다음 주소 js +?> + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + class="frm_input " size="15" minlength="3" maxlength="20"> + 접근가능그룹보기 + class="frm_input " size="15" maxlength="20">
    + > + + > + +
    회원가입일최근접속일
    IP
    인증일시 + + + + + + + +
    추천인
    + + " id="mb_leave_date_set_today" onclick="if (this.form.mb_leave_date.value==this.form.mb_leave_date.defaultValue) { +this.form.mb_leave_date.value=this.value; } else { this.form.mb_leave_date.value=this.form.mb_leave_date.defaultValue; }"> + + 접근차단일자 + + " id="mb_intercept_date_set_today" onclick="if +(this.form.mb_intercept_date.value==this.form.mb_intercept_date.defaultValue) { this.form.mb_intercept_date.value=this.value; } else { +this.form.mb_intercept_date.value=this.form.mb_intercept_date.defaultValue; }"> + +
    +
    + +
    + + 목록 +
    +
    + + + + diff --git a/AvocadoEdition/adm/member_form_update.php b/AvocadoEdition/adm/member_form_update.php new file mode 100644 index 0000000..a12f463 --- /dev/null +++ b/AvocadoEdition/adm/member_form_update.php @@ -0,0 +1,167 @@ += $member['mb_level']) + alert('자신보다 권한이 높거나 같은 회원은 수정할 수 없습니다.'); + + if ($_POST['mb_id'] == $member['mb_id'] && $_POST['mb_level'] != $mb['mb_level']) + alert($mb['mb_id'].' : 로그인 중인 관리자 레벨은 수정 할 수 없습니다.'); + + // 닉네임중복체크 + $sql = " select mb_id, mb_name, mb_nick, mb_email from {$g5['member_table']} where mb_nick = '{$_POST['mb_nick']}' and mb_id <> '{$mb_id}' "; + $row = sql_fetch($sql); + if ($row['mb_id']) + alert('이미 존재하는 닉네임입니다.\\nID : '.$row['mb_id'].'\\n이름 : '.$row['mb_name'].'\\n닉네임 : '.$row['mb_nick'].'\\n메일 : '.$row['mb_email']); + + // 이메일중복체크 + $sql = " select mb_id, mb_name, mb_nick, mb_email from {$g5['member_table']} where mb_email = '{$_POST['mb_email']}' and mb_id <> '$mb_id' "; + $row = sql_fetch($sql); + if ($row['mb_id']) + alert('이미 존재하는 이메일입니다.\\nID : '.$row['mb_id'].'\\n이름 : '.$row['mb_name'].'\\n닉네임 : '.$row['mb_nick'].'\\n메일 : '.$row['mb_email']); + + $mb_dir = substr($mb_id,0,2); + + // 회원 아이콘 삭제 + if ($del_mb_icon) + @unlink(G5_DATA_PATH.'/member/'.$mb_dir.'/'.$mb_id.'.gif'); + + // 아이콘 업로드 + if (is_uploaded_file($_FILES['mb_icon']['tmp_name'])) { + if (!preg_match("/(\.gif)$/i", $_FILES['mb_icon']['name'])) { + alert($_FILES['mb_icon']['name'] . '은(는) gif 파일이 아닙니다.'); + } + + if (preg_match("/(\.gif)$/i", $_FILES['mb_icon']['name'])) { + @mkdir(G5_DATA_PATH.'/member/'.$mb_dir, G5_DIR_PERMISSION); + @chmod(G5_DATA_PATH.'/member/'.$mb_dir, G5_DIR_PERMISSION); + + $dest_path = G5_DATA_PATH.'/member/'.$mb_dir.'/'.$mb_id.'.gif'; + + move_uploaded_file($_FILES['mb_icon']['tmp_name'], $dest_path); + chmod($dest_path, G5_FILE_PERMISSION); + + if (file_exists($dest_path)) { + $size = getimagesize($dest_path); + // 아이콘의 폭 또는 높이가 설정값 보다 크다면 이미 업로드 된 아이콘 삭제 + if ($size[0] > $config['cf_member_icon_width'] || $size[1] > $config['cf_member_icon_height']) { + @unlink($dest_path); + } + } + } + } + + if ($mb_password) + $sql_password = " , mb_password = '".get_encrypt_string($mb_password)."' "; + else + $sql_password = ""; + + if ($passive_certify) + $sql_certify = " , mb_email_certify = '".G5_TIME_YMDHIS."' "; + else + $sql_certify = ""; + + $sql = " update {$g5['member_table']} + set {$sql_common} + {$sql_password} + {$sql_certify} + where mb_id = '{$mb_id}' "; + sql_query($sql); +} +else + alert('제대로 된 값이 넘어오지 않았습니다.'); + +goto_url('./member_form.php?'.$qstr.'&w=u&mb_id='.$mb_id, false); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/member_list.php b/AvocadoEdition/adm/member_list.php new file mode 100644 index 0000000..281411a --- /dev/null +++ b/AvocadoEdition/adm/member_list.php @@ -0,0 +1,248 @@ += '{$stx}') "; + break; + case 'mb_level' : + $sql_search .= " ({$sfl} = '{$stx}') "; + break; + case 'mb_tel' : + case 'mb_hp' : + $sql_search .= " ({$sfl} like '%{$stx}') "; + break; + default : + $sql_search .= " ({$sfl} like '{$stx}%') "; + break; + } + $sql_search .= " ) "; +} + +if ($is_admin != 'super') + $sql_search .= " and mb_level <= '{$member['mb_level']}' "; + +if (!$sst) { + $sst = "mb_datetime"; + $sod = "desc"; +} + +$sql_order = " order by {$sst} {$sod} "; + +$sql = " select count(*) as cnt {$sql_common} {$sql_search} {$sql_order} "; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$rows = $config['cf_page_rows']; +$total_page = ceil($total_count / $rows); // 전체 페이지 계산 +if ($page < 1) $page = 1; // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $rows; // 시작 열을 구함 + +// 탈퇴회원수 +$sql = " select count(*) as cnt {$sql_common} {$sql_search} and mb_leave_date <> '' {$sql_order} "; +$row = sql_fetch($sql); +$leave_count = $row['cnt']; + +// 차단회원수 +$sql = " select count(*) as cnt {$sql_common} {$sql_search} and mb_intercept_date <> '' {$sql_order} "; +$row = sql_fetch($sql); +$intercept_count = $row['cnt']; + +$listall = '전체목록'; + +$g5['title'] = '회원관리'; +include_once('./admin.head.php'); + +$sql = " select * {$sql_common} {$sql_search} {$sql_order} limit {$from_record}, {$rows} "; +$result = sql_query($sql); + +$colspan = 10; +?> + +
    + + 총회원수 명 중, + 차단 명, + 탈퇴 명 +
    + +
    +

    + 회원자료 삭제 시 다른 회원이 기존 회원아이디를 사용하지 못하도록 회원아이디, 이름, 닉네임은 삭제하지 않고 영구 보관합니다. +

    +
    + +
    + + + + + + + +
    + + + + + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + 수정'; + $leave_date = $row['mb_leave_date'] ? $row['mb_leave_date'] : date('Ymd', G5_SERVER_TIME); + $intercept_date = $row['mb_intercept_date'] ? $row['mb_intercept_date'] : date('Ymd', G5_SERVER_TIME); + $mb_nick = get_sideview($row['mb_id'], get_text($row['mb_nick']), $row['mb_email'], $row['mb_homepage']); + $mb_id = $row['mb_id']; + $leave_msg = ''; + $intercept_msg = ''; + $intercept_title = ''; + if ($row['mb_leave_date']) { + $mb_id = $mb_id; + $leave_msg = '탈퇴함'; + } + else if ($row['mb_intercept_date']) { + $mb_id = $mb_id; + $intercept_msg = '차단됨'; + $intercept_title = '차단해제'; + } + if ($intercept_title == '') + $intercept_title = '차단하기'; + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + + + + + "; + ?> + +
    목록
    + + 아이디이름생년보유캐릭터상태권한가입일최종접속관리
    + + + + + + + + + + 보유중인 캐릭터가 없습니다. + + + + + +
    자료가 없습니다.
    +
    + +
    + + + +
    + +
    + + + + + + diff --git a/AvocadoEdition/adm/member_list_delete.php b/AvocadoEdition/adm/member_list_delete.php new file mode 100644 index 0000000..f416a60 --- /dev/null +++ b/AvocadoEdition/adm/member_list_delete.php @@ -0,0 +1,37 @@ += $member['mb_level']) { + $msg .= "{$mb['mb_id']} : 자신보다 권한이 높거나 같은 회원은 삭제할 수 없습니다.\\n"; + } else { + // 회원자료 삭제 + member_delete($mb['mb_id']); + } +} + +if ($msg) + echo ""; + +goto_url("./member_list.php?$qstr"); +?> diff --git a/AvocadoEdition/adm/member_list_update.php b/AvocadoEdition/adm/member_list_update.php new file mode 100644 index 0000000..d4caa4c --- /dev/null +++ b/AvocadoEdition/adm/member_list_update.php @@ -0,0 +1,92 @@ += $member['mb_level']) { + $msg .= $mb['mb_id'].' : 자신보다 권한이 높거나 같은 회원은 수정할 수 없습니다.\\n'; + } else if ($member['mb_id'] == $mb['mb_id']) { + $msg .= $mb['mb_id'].' : 로그인 중인 관리자는 수정 할 수 없습니다.\\n'; + } else { + if($_POST['mb_certify'][$k]) + $mb_adult = $_POST['mb_adult'][$k]; + else + $mb_adult = 0; + + $sql = " update {$g5['member_table']} + set mb_level = '{$_POST['mb_level'][$k]}' + where mb_id = '{$_POST['mb_id'][$k]}' "; + sql_query($sql); + } + } + +} else if ($_POST['act_button'] == "선택삭제") { + + for ($i=0; $i= $member['mb_level']) { + $msg .= $mb['mb_id'].' : 자신보다 권한이 높거나 같은 회원은 삭제할 수 없습니다.\\n'; + } else { + // 회원자료 삭제 + member_delete($mb['mb_id']); + } + } +}else if ($_POST['act_button'] == "완전삭제") { + + for ($i=0; $i= $member['mb_level']) { + $msg .= $mb['mb_id'].' : 자신보다 권한이 높거나 같은 회원은 삭제할 수 없습니다.\\n'; + } else { + // 회원자료 삭제 + sql_query(" delete from {$g5['member_table']} where mb_id = '{$_POST['mb_id'][$k]}' "); + } + } +} + +if ($msg) + //echo ''; + alert($msg); + +goto_url('./member_list.php?'.$qstr); +?> diff --git a/AvocadoEdition/adm/menu_form.php b/AvocadoEdition/adm/menu_form.php new file mode 100644 index 0000000..0db45d5 --- /dev/null +++ b/AvocadoEdition/adm/menu_form.php @@ -0,0 +1,151 @@ + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/menu_form_search.php b/AvocadoEdition/adm/menu_form_search.php new file mode 100644 index 0000000..1d5ff3e --- /dev/null +++ b/AvocadoEdition/adm/menu_form_search.php @@ -0,0 +1,111 @@ + + + + +
    + + + + + + + + + + + + + + + + + + + +
    제목선택
    + "> + + +
    +
    + +
    + +
    + + + +
    + + + + + + + + + + + + + + + +
    + + +
    +
    + +
    + + +
    + \ No newline at end of file diff --git a/AvocadoEdition/adm/menu_list.php b/AvocadoEdition/adm/menu_list.php new file mode 100644 index 0000000..3e0be76 --- /dev/null +++ b/AvocadoEdition/adm/menu_list.php @@ -0,0 +1,206 @@ +dbconfig.php 파일에 $g5[\'menu_table\'] = G5_TABLE_PREFIX.\'menu\'; 를 추가해 주세요.'); +} + +if(!sql_query(" DESCRIBE {$g5['menu_table']} ", false)) { + sql_query(" CREATE TABLE IF NOT EXISTS `{$g5['menu_table']}` ( + `me_id` int(11) NOT NULL AUTO_INCREMENT, + `me_code` varchar(255) NOT NULL DEFAULT '', + `me_name` varchar(255) NOT NULL DEFAULT '', + `me_link` varchar(255) NOT NULL DEFAULT '', + `me_target` varchar(255) NOT NULL DEFAULT '0', + `me_order` int(11) NOT NULL DEFAULT '0', + `me_use` tinyint(4) NOT NULL DEFAULT '0', + `me_mobile_use` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`me_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ", true); +} + +$sql = " select * from {$g5['menu_table']} order by me_id "; +$result = sql_query($sql); + +$g5['title'] = "메뉴설정"; +include_once('./admin.head.php'); + +$colspan = 7; +?> + +
    +

    주의! 메뉴설정 작업 후 반드시 확인을 누르셔야 저장됩니다.

    +
    + +
    + + +
    + +
    + + + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/menu_list_update.php b/AvocadoEdition/adm/menu_list_update.php new file mode 100644 index 0000000..3762821 --- /dev/null +++ b/AvocadoEdition/adm/menu_list_update.php @@ -0,0 +1,70 @@ + diff --git a/AvocadoEdition/adm/newwinform.php b/AvocadoEdition/adm/newwinform.php new file mode 100644 index 0000000..947d844 --- /dev/null +++ b/AvocadoEdition/adm/newwinform.php @@ -0,0 +1,150 @@ + + +
    + + + + +
    +

    초기화면 접속 시 자동으로 뜰 팝업레이어를 설정합니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + 시간 +
    + + " id="nw_begin_chk" onclick="if (this.checked == true) this.form.nw_begin_time.value=this.form.nw_begin_chk.value; else this.form.nw_begin_time.value = this.form.nw_begin_time.defaultValue;"> + +
    + + " id="nw_end_chk" onclick="if (this.checked == true) this.form.nw_end_time.value=this.form.nw_end_chk.value; else this.form.nw_end_time.value = this.form.nw_end_time.defaultValue;"> + +
    + px +
    + px +
    + px +
    + px +
    + +
    +
    + +
    + + 목록 +
    +
    + + + + diff --git a/AvocadoEdition/adm/newwinformupdate.php b/AvocadoEdition/adm/newwinformupdate.php new file mode 100644 index 0000000..2170892 --- /dev/null +++ b/AvocadoEdition/adm/newwinformupdate.php @@ -0,0 +1,53 @@ + diff --git a/AvocadoEdition/adm/newwinlist.php b/AvocadoEdition/adm/newwinlist.php new file mode 100644 index 0000000..b6bee74 --- /dev/null +++ b/AvocadoEdition/adm/newwinlist.php @@ -0,0 +1,118 @@ +/data/dbconfig.php 파일에 $g5[\'new_win_table\'] = G5_TABLE_PREFIX.\'new_win\'; 를 추가해 주세요.'); +} +//내용(컨텐츠)정보 테이블이 있는지 검사한다. +if(!sql_query(" DESCRIBE {$g5['new_win_table']} ", false)) { + if(sql_query(" DESCRIBE {$g5['g5_shop_new_win_table']} ", false)) { + sql_query(" ALTER TABLE {$g5['g5_shop_new_win_table']} RENAME TO `{$g5['new_win_table']}` ;", false); + } else { + $query_cp = sql_query(" CREATE TABLE IF NOT EXISTS `{$g5['new_win_table']}` ( + `nw_id` int(11) NOT NULL AUTO_INCREMENT, + `nw_device` varchar(10) NOT NULL DEFAULT 'both', + `nw_begin_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `nw_end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `nw_disable_hours` int(11) NOT NULL DEFAULT '0', + `nw_left` int(11) NOT NULL DEFAULT '0', + `nw_top` int(11) NOT NULL DEFAULT '0', + `nw_height` int(11) NOT NULL DEFAULT '0', + `nw_width` int(11) NOT NULL DEFAULT '0', + `nw_subject` text NOT NULL, + `nw_content` text NOT NULL, + `nw_content_html` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`nw_id`) + ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ", true); + } +} + +$g5['title'] = '팝업레이어 관리'; +include_once (G5_ADMIN_PATH.'/admin.head.php'); + +$sql_common = " from {$g5['new_win_table']} "; + +// 테이블의 전체 레코드수만 얻음 +$sql = " select count(*) as cnt " . $sql_common; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$sql = "select * {$sql_common} order by nw_id desc "; +$result = sql_query($sql); +?> + +
    전체
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    번호제목접속기기시작일시종료일시시간LeftTopWidthHeight관리
    시간pxpxpxpx + 수정 + 삭제 +
    자료가 한건도 없습니다.
    +
    + + + diff --git a/AvocadoEdition/adm/order_list.php b/AvocadoEdition/adm/order_list.php new file mode 100644 index 0000000..17443b2 --- /dev/null +++ b/AvocadoEdition/adm/order_list.php @@ -0,0 +1,170 @@ +전체목록'; + +$ch = array(); +if ($sfl == 'ch_id' && $stx) + $ch = get_member($stx); + +$g5['title'] = '아이템 구매 기록'; +include_once ('./admin.head.php'); + +$colspan = 5; + +?> + +
    + + 전체 건 +
    + +
    + + + + + +
    +
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 구매캐릭터구매회원아이템구매일
    + + + + + +
    자료가 없습니다.
    +
    + +
    + +
    + +
    + + + + + + + + diff --git a/AvocadoEdition/adm/order_list_delete.php b/AvocadoEdition/adm/order_list_delete.php new file mode 100644 index 0000000..61131b8 --- /dev/null +++ b/AvocadoEdition/adm/order_list_delete.php @@ -0,0 +1,21 @@ + diff --git a/AvocadoEdition/adm/phpinfo.php b/AvocadoEdition/adm/phpinfo.php new file mode 100644 index 0000000..a7f01a1 --- /dev/null +++ b/AvocadoEdition/adm/phpinfo.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/point_list.php b/AvocadoEdition/adm/point_list.php new file mode 100644 index 0000000..5ca8759 --- /dev/null +++ b/AvocadoEdition/adm/point_list.php @@ -0,0 +1,252 @@ +전체목록'; + +$mb = array(); +if ($sfl == 'mb_id' && $stx) + $mb = get_member($stx); + +$g5['title'] = $config['cf_money'].' 관리'; +include_once ('./admin.head.php'); + +$colspan = 9; + +$po_expire_term = ''; +if($config['cf_point_term'] > 0) { + $po_expire_term = $config['cf_point_term']; +} + +?> + +
    + + 전체 건 + +
    + +
    + + + + + +
    +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + '; + $link2 = ''; + } + + $expr = ''; + if($row['po_expired'] == 1) + $expr = ' txt_expired'; + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 회원아이디이름닉네임내용일시
    + + + + +
    자료가 없습니다.
    +
    + +
    + +
    + +
    + + + +
    +

    개별회원 증감 설정

    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    지급유형 + + +    + + +
    멤버 닉네임 + + + +
    +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/point_list_delete.php b/AvocadoEdition/adm/point_list_delete.php new file mode 100644 index 0000000..e47a510 --- /dev/null +++ b/AvocadoEdition/adm/point_list_delete.php @@ -0,0 +1,59 @@ + 0) { + insert_use_point($row['mb_id'], $row['po_use_point'], $row['po_id']); + } + } + + // 소지금 내역삭제 + $sql = " delete from {$g5['point_table']} where po_id = '{$_POST['po_id'][$k]}' "; + sql_query($sql); + + // po_mb_point에 반영 + $sql = " update {$g5['point_table']} + set po_mb_point = po_mb_point - '{$row['po_point']}' + where mb_id = '{$_POST['mb_id'][$k]}' + and po_id > '{$_POST['po_id'][$k]}' "; + sql_query($sql); + + // 소지금 UPDATE + $sum_point = get_point_sum($_POST['mb_id'][$k]); + $sql= " update {$g5['member_table']} set mb_point = '{$sum_point}' where mb_id = '{$_POST['mb_id'][$k]}' "; + sql_query($sql); +} + +goto_url('./point_list.php?'.$qstr); +?> \ No newline at end of file diff --git a/AvocadoEdition/adm/point_update.php b/AvocadoEdition/adm/point_update.php new file mode 100644 index 0000000..be5a365 --- /dev/null +++ b/AvocadoEdition/adm/point_update.php @@ -0,0 +1,49 @@ + 1 "; + $sql = " select * {$sql_common} {$sql_search} "; + $result = sql_query($sql); + + for($i=0; $mb = sql_fetch_array($result); $i++) { + if (($po_point < 0) && ($po_point * (-1) > $mb['mb_point'])) + alert('소지금를 깎는 경우 현재 소지금보다 작으면 안됩니다.', './point_list.php?'.$qstr); + + insert_point($mb['mb_id'], $po_point, $po_content, '@passive', $mb['mb_id'], $member['mb_id'].'-'.uniqid(''), $expire); + } +} else { + // 개별지급 + if(!$mb_id && $mb_name) { + $mb = sql_fetch("select * from {$g5['member_table']} where mb_name = '{$mb_name}'"); + $mb_id = $mb['mb_id']; + } else { + $mb = get_member($mb_id); + } + + if (!$mb['mb_id']) + alert('존재하는 회원이 아닙니다.'); + + if (($po_point < 0) && ($po_point * (-1) > $mb['mb_point'])) + alert('소지금를 깎는 경우 현재 소지금보다 작으면 안됩니다.', './point_list.php?'.$qstr); + + insert_point($mb['mb_id'], $po_point, $po_content, '@passive', $mb['mb_id'], $member['mb_id'].'-'.uniqid(''), $expire); +} + + + +goto_url('./point_list.php?'.$qstr); +?> diff --git a/AvocadoEdition/adm/poll_delete.php b/AvocadoEdition/adm/poll_delete.php new file mode 100644 index 0000000..3cae4f3 --- /dev/null +++ b/AvocadoEdition/adm/poll_delete.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/poll_form.php b/AvocadoEdition/adm/poll_form.php new file mode 100644 index 0000000..c009d60 --- /dev/null +++ b/AvocadoEdition/adm/poll_form.php @@ -0,0 +1,123 @@ + + +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + 필수'; + } + + $po_poll = get_text($po['po_poll'.$i]); + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + class="frm_input " maxlength="125"> + + + + +
    + + +
    + + 이상 투표할 수 있음 +
    + + 점 +
    투표등록일
    + +
    + +
    + + 목록 +
    + +
    + + diff --git a/AvocadoEdition/adm/poll_form_update.php b/AvocadoEdition/adm/poll_form_update.php new file mode 100644 index 0000000..a3cba14 --- /dev/null +++ b/AvocadoEdition/adm/poll_form_update.php @@ -0,0 +1,69 @@ + diff --git a/AvocadoEdition/adm/poll_list.php b/AvocadoEdition/adm/poll_list.php new file mode 100644 index 0000000..b3a75c3 --- /dev/null +++ b/AvocadoEdition/adm/poll_list.php @@ -0,0 +1,163 @@ +전체목록'; + +$g5['title'] = '투표관리'; +include_once('./admin.head.php'); + +$colspan = 7; +?> + +
    + + 투표수 개 +
    + +
    +
    + + + + + +
    +
    + + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + 수정'; + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 번호제목투표권한투표수기타의견관리
    + + + + 보기 + +
    자료가 없습니다.
    +
    + +
    + +
    +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/popular_list.php b/AvocadoEdition/adm/popular_list.php new file mode 100644 index 0000000..fe49ec8 --- /dev/null +++ b/AvocadoEdition/adm/popular_list.php @@ -0,0 +1,171 @@ +전체목록'; + +$g5['title'] = '인기검색어관리'; +include_once('./admin.head.php'); + +$colspan = 4; +?> + + + +
    + + 건수 : 개 +
    + +
    +
    + + + + + +
    +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 검색어등록일등록IP
    + + +
    자료가 없습니다.
    + +
    + + +
    + +
    + + +
    + + + + + + diff --git a/AvocadoEdition/adm/popular_rank.php b/AvocadoEdition/adm/popular_rank.php new file mode 100644 index 0000000..7290287 --- /dev/null +++ b/AvocadoEdition/adm/popular_rank.php @@ -0,0 +1,112 @@ + '' and pp_date between '{$fr_date}' and '{$to_date}' "; +$sql_group = " group by pp_word "; +$sql_order = " order by cnt desc "; + +$sql = " select pp_word {$sql_common} {$sql_search} {$sql_group} "; +$result = sql_query($sql); +$total_count = sql_num_rows($result); + +$rows = $config['cf_page_rows']; +$total_page = ceil($total_count / $rows); // 전체 페이지 계산 +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $rows; // 시작 열을 구함 + +$sql = " select pp_word, count(*) as cnt {$sql_common} {$sql_search} {$sql_group} {$sql_order} limit {$from_record}, {$rows} "; +$result = sql_query($sql); + +$listall = '전체목록'; + +$g5['title'] = '인기검색어순위'; +include_once('./admin.head.php'); +include_once(G5_PLUGIN_PATH.'/jquery-ui/datepicker.php'); + +$colspan = 3; +?> + + + +
    + + 건수 개 +
    + +
    +
    + 기간별검색 + + + ~ + + + +
    +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    순위검색어검색회수
    자료가 없습니다.
    +
    + +
    + + + + diff --git a/AvocadoEdition/adm/qa_config.php b/AvocadoEdition/adm/qa_config.php new file mode 100644 index 0000000..e1d6ad8 --- /dev/null +++ b/AvocadoEdition/adm/qa_config.php @@ -0,0 +1,263 @@ + + +
    + + +
    +

    1:1문의 설정

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    1:1문의 설정
    + + 1:1문의 바로가기 +
    + + +
    + +
    이메일 입력 + > + > +
    + + +
    + + +
    + + +
    + +
    + + 픽셀 +
    + + 업로드 파일 한개당 bytes 이하 +
    + +
    + +
    + +
    + +
    여분필드 + + + + +
    +
    +
    + +
    + +
    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/qa_config_update.php b/AvocadoEdition/adm/qa_config_update.php new file mode 100644 index 0000000..6ebcbed --- /dev/null +++ b/AvocadoEdition/adm/qa_config_update.php @@ -0,0 +1,67 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/quest_form.php b/AvocadoEdition/adm/quest_form.php new file mode 100644 index 0000000..ac1e165 --- /dev/null +++ b/AvocadoEdition/adm/quest_form.php @@ -0,0 +1,178 @@ +필수'; + + +} else if ($w == 'u') { + + $html_title .= ' 수정'; + $quest = sql_fetch("select * from {$g5['quest_table']} where qu_id = '{$qu_id}'"); + if (!$quest['qu_id']) + alert('존재하지 않는 퀘스트 입니다.'); + $readonly = 'readonly'; +} + +$g5['title'] = $html_title; +include_once ('./admin.head.php'); + + +$frm_submit = '
    + + 목록'.PHP_EOL; +$frm_submit .= '
    '; + +?> + + + + +
    + + + + + + + + +
    +

    퀘스트 기본 설정

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    퀘스트 기본 설정
    퀘스트 분류 + +
    수행가능 + +
    퀘스트 이름 + +
    + 퀘스트 기간 + + 시작일 + + +
    + 종료일 + + +
    퀘스트 이미지 + + +

    + ex)
    + /img/img_01.png
    + /img/img_02.png
    + /img/img_03.png
    + ... +

    +
    +
    +
    + + + +
    + + + + + diff --git a/AvocadoEdition/adm/quest_form_update.php b/AvocadoEdition/adm/quest_form_update.php new file mode 100644 index 0000000..1e655aa --- /dev/null +++ b/AvocadoEdition/adm/quest_form_update.php @@ -0,0 +1,35 @@ + diff --git a/AvocadoEdition/adm/quest_list.php b/AvocadoEdition/adm/quest_list.php new file mode 100644 index 0000000..e15a062 --- /dev/null +++ b/AvocadoEdition/adm/quest_list.php @@ -0,0 +1,242 @@ +전체목록'; + +$g5['title'] = '퀘스트 관리'; +include_once('./admin.head.php'); + +$colspan = 8; +?> + +
    + + 추가된 퀘스트 수 개 +
    + +
    + + + + + + + + + + + +
    + + + + + +
    + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 분류세력퀘스트 이름이미지시작일종료일관리
    + + + + + + + + + + + + + ", $quest['qu_image']); + for($k = 0; $k < count($img_data); $k++) { + $q_img = $img_data[$k]; + if(!$q_img) continue; + ?> + + + + + + + + + + 보기 + + +
    자료가 없습니다.
    +
    + +
    + + + + +
    + +
    + + + + + + diff --git a/AvocadoEdition/adm/quest_list_update.php b/AvocadoEdition/adm/quest_list_update.php new file mode 100644 index 0000000..b14d313 --- /dev/null +++ b/AvocadoEdition/adm/quest_list_update.php @@ -0,0 +1,45 @@ + diff --git a/AvocadoEdition/adm/recipi_list.php b/AvocadoEdition/adm/recipi_list.php new file mode 100644 index 0000000..1f5ddf7 --- /dev/null +++ b/AvocadoEdition/adm/recipi_list.php @@ -0,0 +1,291 @@ +전체목록'; + + +$g5['title'] = '레시피 관리'; +include_once ('./admin.head.php'); + +$colspan = 11; + + +$pg_anchor = ''; + + +$frm_submit = '
    + +
    '; + +?> + + +
    + + + + + + + +
    +

    레시피 목록

    + + +
    + + 전체 건 +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 재료01재료02재료03조합결과사용
    + + + + "; + } + ?> + + + + "; + } + ?> + + + + "; + } + ?> + + + + "; + } + ?> + + + + > +
    자료가 없습니다.
    +
    + +
    + + +
    + + + +
    +
    + + + +
    + + + + + + + +
    +

    레시피 정보 입력

    + + +
    +

    재료 선택 시, [ 아이템 속성 > 레시피 재료 ] 설정이 되어 있는 아이템만 검색됩니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    재료 01 + + +
    +
    재료 02 + + +
    +
    재료 03 + + +
    +
    결과 + + +
    +
    +
    +
    + + +
    + + + + + diff --git a/AvocadoEdition/adm/recipi_list_update.php b/AvocadoEdition/adm/recipi_list_update.php new file mode 100644 index 0000000..e449135 --- /dev/null +++ b/AvocadoEdition/adm/recipi_list_update.php @@ -0,0 +1,36 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/recipi_update.php b/AvocadoEdition/adm/recipi_update.php new file mode 100644 index 0000000..9013ea6 --- /dev/null +++ b/AvocadoEdition/adm/recipi_update.php @@ -0,0 +1,61 @@ + 0) + alert('이미 등록된 레시피 조합 입니다.', './recipi_list.php?'.$qstr); + +sql_query ("insert into {$g5['recepi_table']} + set re_item_order ='{$re_item_order}', + it_id = '{$it_id}', + re_use = '{$re_use}' + "); + +goto_url('./recipi_list.php?'.$qstr); + +?> diff --git a/AvocadoEdition/adm/sendmail_test.php b/AvocadoEdition/adm/sendmail_test.php new file mode 100644 index 0000000..a0facf1 --- /dev/null +++ b/AvocadoEdition/adm/sendmail_test.php @@ -0,0 +1,65 @@ +[메일검사] 내용

    이 내용이 제대로 보인다면 보내는 메일 서버에는 이상이 없는것입니다.

    '.G5_TIME_YMDHIS.'

    이 메일 주소로는 회신되지 않습니다.', 1); + + echo '

    '; + echo '

    결과메세지

    '; + echo '

    '; + echo '다음 '.count($email).'개의 메일 주소로 테스트 메일 발송이 완료되었습니다.'; + echo '

    '; + echo '
      '; + for ($i=0;$i'.$email[$i].''; + } + echo '
    '; + echo '

    '; + echo '해당 주소로 테스트 메일이 도착했는지 확인해 주십시오.
    '; + echo '만약, 테스트 메일이 오지 않는다면 더 다양한 계정의 메일 주소로 메일을 보내 보십시오.
    '; + echo '그래도 메일이 하나도 도착하지 않는다면 메일 서버(sendmail server)의 오류일 가능성이 높으니, 웹 서버관리자에게 문의하여 주십시오.
    '; + echo '

    '; + echo '
    '; +} +?> + +
    +

    테스트 메일 발송

    +
    +

    + 메일서버가 정상적으로 동작 중인지 확인할 수 있습니다.
    + 아래 입력칸에 테스트 메일을 발송하실 메일 주소를 입력하시면, [메일검사] 라는 제목으로 테스트 메일을 발송합니다.
    +

    +
    +
    +
    + 테스트메일 발송 + + + +
    +
    +
    +

    + 만약 [메일검사] 라는 내용으로 테스트 메일이 도착하지 않는다면 보내는 메일서버 혹은 받는 메일서버 중 문제가 발생했을 가능성이 있습니다.
    + 따라서 보다 정확한 테스트를 원하신다면 여러 곳으로 테스트 메일을 발송하시기 바랍니다.
    +

    +
    +
    + + diff --git a/AvocadoEdition/adm/service.php b/AvocadoEdition/adm/service.php new file mode 100644 index 0000000..c677bea --- /dev/null +++ b/AvocadoEdition/adm/service.php @@ -0,0 +1,49 @@ + + +
    +

    아래의 서비스들은 그누보드에서 이미 지원하는 기능으로 별도의 개발이 필요 없으며 서비스 신청후 바로 사용 할수 있습니다.

    +
    + +
    +
    + 휴대폰 본인확인 서비스 +

    휴대폰 본인확인 서비스

    +

    정보통신망법 23조 2항(주민등록번호의 사용제한)에 따라 기존 주민등록번호 기반의 인증서비스 이용이 불가합니다. 주민등록번호 대체수단으로 최소한의 정보(생년월일, 휴대폰번호, 성별)를 입력받아 본인임을 확인하는 인증수단 입니다

    + +
      +
    • KCP 휴대폰 본인확인 신청하기
    • +
    • LG유플러스 휴대폰대체인증 신청하기
    • +
    • OKname 휴대폰 본인확인 신청하기
    • +
    +
    +
    + 아이핀 본인확인 서비스 +

    아이핀 본인확인 서비스

    +

    정부가 주관하는 주민등록번호 대체 수단으로 본인의 개인정보를 아이핀 사이트에 한번만 발급해 놓고, 이후부터는 아이디와 패스워드 만으로 + 본인임을 확인하는 인증수단 입니다.

    + +

    OKname 아이핀 본인확인 신청하기

    +
    +
    +
    +
    +

    SMS 문자 서비스

    +

    사이트 관리자 또는 회원이 다른 회원의
    휴대폰으로 단문메세지(최대 한글 40자, 영문 80자)를 발송할 수 있습니다.

    +
    +
    아이코드 SMS 서비스 신청하기
    +
    + +
    +
    + + diff --git a/AvocadoEdition/adm/session_file_delete.php b/AvocadoEdition/adm/session_file_delete.php new file mode 100644 index 0000000..abc2c2b --- /dev/null +++ b/AvocadoEdition/adm/session_file_delete.php @@ -0,0 +1,61 @@ + + +
    +

    + 완료 메세지가 나오기 전에 프로그램의 실행을 중지하지 마십시오. +

    +
    + + 세션 디렉토리를 열지못했습니다.

    "; + } else { + $list_tag_st = "
      \n
    • 완료됨
    • \n"; + $list_tag_end = "
    \n"; + } + + $cnt=0; + echo $list_tag_st; + while($file=readdir($dir)) { + + if (!strstr($file,'sess_')) continue; + if (strpos($file,'sess_')!=0) continue; + + $session_file = G5_DATA_PATH.'/session/'.$file; + + if (!$atime=@fileatime($session_file)) { + continue; + } + if (time() > $atime + (3600 * 6)) { // 지난시간을 초로 계산해서 적어주시면 됩니다. default : 6시간전 + $cnt++; + $return = unlink($session_file); + //echo "\n"; + echo "
  • {$session_file}
  • \n"; + + flush(); + + if ($cnt%10==0) + //echo "\n"; + echo "\n"; + } + } + echo $list_tag_end; + echo '

    세션데이터 '.$cnt.'건 삭제 완료됐습니다.
    프로그램의 실행을 끝마치셔도 좋습니다.

    '.PHP_EOL; +?> + + diff --git a/AvocadoEdition/adm/shop_form.php b/AvocadoEdition/adm/shop_form.php new file mode 100644 index 0000000..9c03ca0 --- /dev/null +++ b/AvocadoEdition/adm/shop_form.php @@ -0,0 +1,374 @@ +필수'; + $shop['sh_use'] = '1'; + $shop['sh_use_money'] = '1'; + + +} else if ($w == 'u') { + + $html_title .= ' 수정'; + $shop = sql_fetch("select * from {$g5['shop_table']} where sh_id = '{$sh_id}'"); + if (!$shop['sh_id']) + alert('존재하지 않는 진열정보 입니다.'); + $readonly = 'readonly'; +} + +$g5['title'] = $html_title; +include_once ('./admin.head.php'); + +$pg_anchor = ''; + + +$frm_submit = '
    + + 목록'.PHP_EOL; +$frm_submit .= '
    '; + + +/** 세력 정보 **/ +if($config['cf_side_title']) { + $ch_si = array(); + $side_result = sql_query("select si_id, si_name from {$g5['side_table']} where si_auth <= '{$member['mb_level']}' order by si_id asc"); + for($i=0; $row = sql_fetch_array($side_result); $i++) { + $ch_si[$i]['name'] = $row['si_name']; + $ch_si[$i]['id'] = $row['si_id']; + } +} + +/** 종족 정보 **/ +if($config['cf_class_title']) { + $ch_cl = array(); + $class_result = sql_query("select cl_id, cl_name from {$g5['class_table']} where cl_auth <= '{$member['mb_level']}' order by cl_id asc"); + for($i=0; $row = sql_fetch_array($class_result); $i++) { + $ch_cl[$i]['name'] = $row['cl_name']; + $ch_cl[$i]['id'] = $row['cl_id']; + } + +} + +?> + + + +
    + + + + + + + + +
    +

    진열 기본 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    아이템 기본 설정
    판매여부 + /> +
    상점 분류 +
    진열 아이템 + + +
    +
    아이템 설명 + +
    진열기간날짜 + + + ~ + +
    시간 + + 시 + ~ + 시 +
    요일 + + + + > + + + +
    진열순서 + +
    +
    +
    + + +
    +

    가격 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    아이템 기본 설정
    설정 + 필요 + + +
    소모여부 + /> + +
    설정 + 필요 + + +
    소모여부 + /> + +
    교환아이템 설정 + 필요 아이템 + + + +
    + +
    소모여부 + /> + +
    교환타이틀 설정 + 필요 타이틀 + + + +
    +
    소모여부 + /> + +
    +
    +
    + + +
    +

    구매제한 설정

    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    아이템 기본 설정
    구매갯수 + + +
    재고설정 + + +
    제한 설정 + 구매가능 + + + + > + + + +
    사용여부 + /> + +
    제한 설정 + 구매가능 + + + + > + + + +
    사용여부 + /> + +
    랭킹 제한 설정 + 구매가능 + + + + > + + + +
    사용여부 + /> + +
    +
    +
    + + + +
    + + + + diff --git a/AvocadoEdition/adm/shop_form_update.php b/AvocadoEdition/adm/shop_form_update.php new file mode 100644 index 0000000..e976db7 --- /dev/null +++ b/AvocadoEdition/adm/shop_form_update.php @@ -0,0 +1,109 @@ + 0) { + $sh_week = implode("||", $sh_week); + $sh_week = "||".$sh_week."||"; +} + +// 소속 제한 설정 저장 +if(count($sh_side) > 0) { + $sh_side = implode("||", $sh_side); + $sh_side = "||".$sh_side."||"; +} +// 종족 제한 설정 저장 +if(count($sh_class) > 0) { + $sh_class = implode("||", $sh_class); + $sh_class = "||".$sh_class."||"; +} +// 랭킹 제한 설정 저장 +if(count($sh_rank) > 0) { + $sh_rank = implode("||", $sh_rank); + $sh_rank = "||".$sh_rank."||"; +} + +// 진열 아이템 유효성 여부 체크 +if(!$it_id && $it_name) { + $it = sql_fetch("select it_id from {$g5['item_table']} where it_name = '{$it_name}'"); + $it_id = $it['it_id']; + if(!$it['it_id']) { + alert("진열 아이템으로 등록되는 아이템의 정보가 없습니다."); + } +} + +// 교환 아이템 유효성 여부 체크 +if(!$sh_has_item && $sh_has_item_name) { + $has_item = sql_fetch("select it_id from {$g5['item_table']} where it_name = '{$sh_has_item_name}'"); + $sh_has_item = $has_item['it_id']; + if(!$has_item['it_id']) { + alert("교환 아이템으로 등록되는 아이템의 정보가 없습니다."); + } +} +if(!$sh_has_item_name) { $sh_has_item = 0; } + + +// 교환 타이틀 유효성 여부 체크 +if(!$sh_has_title && $sh_has_title_name) { + $has_title = sql_fetch("select ti_id from {$g5['item_table']} where ti_title = '{$sh_has_title_name}'"); + $sh_has_title = $has_title['ti_id']; + if(!$has_title['ti_id']) { + alert("교환 타이틀로 등록되는 타이틀의 정보가 없습니다."); + } +} +if(!$sh_has_title_name) { $sh_has_title = 0; } + +$sql_common = " + it_id = '{$it_id}', + ca_name = '{$ca_name}', + sh_limit = '{$sh_limit}', + sh_qty = '{$sh_qty}', + sh_money = '{$sh_money}', + sh_use_money = '{$sh_use_money}', + sh_exp = '{$sh_exp}', + sh_use_exp = '{$sh_use_exp}', + sh_content = '{$sh_content}', + sh_side = '{$sh_side}', + sh_use_side = '{$sh_use_side}', + sh_class = '{$sh_class}', + sh_use_class = '{$sh_use_class}', + sh_rank = '{$sh_rank}', + sh_use_rank = '{$sh_use_rank}', + sh_has_item = '{$sh_has_item}', + sh_use_has_item = '{$sh_use_has_item}', + sh_has_title = '{$sh_has_title}', + sh_use_has_title = '{$sh_use_has_title}', + sh_use = '{$sh_use}', + sh_date_s = '{$sh_date_s}', + sh_date_e = '{$sh_date_e}', + sh_time_s = '{$sh_time_s}', + sh_time_e = '{$sh_time_e}', + sh_week = '{$sh_week}', + sh_order = '{$sh_order}' +"; + + +if($w == '') { + $sql = " insert into {$g5['shop_table']} + set {$sql_common}"; + sql_query($sql); +} else { + $sh = sql_fetch("select sh_id from {$g5['shop_table']} where sh_id = '{$sh_id}'"); + + if(!$sh['sh_id']) { + alert("상품 진열 정보가 존재하지 않습니다."); + } + + $sql = " update {$g5['shop_table']} + set {$sql_common} + where sh_id = '{$sh_id}'"; + sql_query($sql); +} + +goto_url('./shop_list.php?'.$qstr, false); +?> diff --git a/AvocadoEdition/adm/shop_list.php b/AvocadoEdition/adm/shop_list.php new file mode 100644 index 0000000..e7c1778 --- /dev/null +++ b/AvocadoEdition/adm/shop_list.php @@ -0,0 +1,275 @@ +전체목록'; + +$g5['title'] = '상점 관리'; +include_once('./admin.head.php'); + +$colspan = 13; +?> + +
    + + 진열된 아이템 수 개 +
    + +
    + + + + + + + + + + +
    + + + + + +
    + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 분류아이템진열기간구매금액구매경험치교환아이템교환타이틀구매갯수순서관리
    소모성소모성소모성소모성재고갯수
    + + + + + + + + + + + +

    ~

    + + +

    시 ~

    + + "; + $str_week = explode("||", $shop['sh_week']); + $add_str = ""; + for($k=0; $k < count($str_week); $k++) { + if($str_week[$k] == '') continue; + ?> + + "; } ?> +
    + + + + + + + + + - + + + + + + - + + + + + + + + +
    + > + + > + + > + + > + + +
    자료가 없습니다.
    +
    + +
    + + + + +
    + +
    + + + + + + + diff --git a/AvocadoEdition/adm/shop_list_update.php b/AvocadoEdition/adm/shop_list_update.php new file mode 100644 index 0000000..1fd81b6 --- /dev/null +++ b/AvocadoEdition/adm/shop_list_update.php @@ -0,0 +1,52 @@ + diff --git a/AvocadoEdition/adm/side_list.php b/AvocadoEdition/adm/side_list.php new file mode 100644 index 0000000..4dec518 --- /dev/null +++ b/AvocadoEdition/adm/side_list.php @@ -0,0 +1,214 @@ +전체목록'; + +$g5['title'] = $config['cf_side_title'].' 관리'; +include_once ('./admin.head.php'); + +$colspan = 7; + + + +$pg_anchor = ''; + +?> + +
    +

    목록

    + + +
    + + 전체 건 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + IDX이미지선택권한보기
    + + + + + + ' alt=''> + + + + + + + + + + + 멤버목록보기 + +
    자료가 없습니다.
    +
    + +
    + + +
    + +
    + + +
    + +
    +

    정보 등록

    + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/side_list_delete.php b/AvocadoEdition/adm/side_list_delete.php new file mode 100644 index 0000000..9799d5f --- /dev/null +++ b/AvocadoEdition/adm/side_list_delete.php @@ -0,0 +1,88 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/side_update.php b/AvocadoEdition/adm/side_update.php new file mode 100644 index 0000000..851715c --- /dev/null +++ b/AvocadoEdition/adm/side_update.php @@ -0,0 +1,44 @@ + diff --git a/AvocadoEdition/adm/sql_write.sql b/AvocadoEdition/adm/sql_write.sql new file mode 100644 index 0000000..e3becb8 --- /dev/null +++ b/AvocadoEdition/adm/sql_write.sql @@ -0,0 +1,71 @@ +CREATE TABLE `__TABLE_NAME__` ( + `wr_id` int(11) NOT NULL AUTO_INCREMENT, + `wr_num` int(11) NOT NULL DEFAULT '0', + `wr_reply` varchar(10) NOT NULL, + `wr_parent` int(11) NOT NULL DEFAULT '0', + `wr_is_comment` tinyint(4) NOT NULL DEFAULT '0', + `wr_comment` int(11) NOT NULL DEFAULT '0', + `wr_comment_reply` varchar(5) NOT NULL, + `ca_name` varchar(255) NOT NULL, + `wr_option` set('html1','html2','secret','mail') NOT NULL, + `wr_subject` varchar(255) NOT NULL, + `wr_content` text NOT NULL, + `wr_link1` text NOT NULL, + `wr_link2` text NOT NULL, + `wr_link1_hit` int(11) NOT NULL DEFAULT '0', + `wr_link2_hit` int(11) NOT NULL DEFAULT '0', + `wr_hit` int(11) NOT NULL DEFAULT '0', + `wr_good` int(11) NOT NULL DEFAULT '0', + `wr_nogood` int(11) NOT NULL DEFAULT '0', + `mb_id` varchar(20) NOT NULL, + `wr_password` varchar(255) NOT NULL, + `wr_name` varchar(255) NOT NULL, + `wr_email` varchar(255) NOT NULL, + `wr_homepage` varchar(255) NOT NULL, + `wr_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `wr_file` tinyint(4) NOT NULL DEFAULT '0', + `wr_last` varchar(19) NOT NULL, + `wr_ip` varchar(255) NOT NULL, + `wr_facebook_user` varchar(255) NOT NULL, + `wr_twitter_user` varchar(255) NOT NULL, + + `wr_dice1` int(11) NOT NULL DEFAULT '0', + `wr_dice2` int(11) NOT NULL DEFAULT '0', + `wr_log` text NOT NULL, + `wr_item` int(11) NOT NULL DEFAULT '0', + `wr_item_log` varchar(255) NOT NULL DEFAULT '', + `wr_action` varchar(255) NOT NULL DEFAULT '', + + `wr_secret` int(11) NOT NULL DEFAULT '0', + `wr_adult` int(11) NOT NULL DEFAULT '0', + `wr_wide` int(11) NOT NULL DEFAULT '0', + `wr_plip` int(11) NOT NULL DEFAULT '0', + `wr_noname` int(11) NOT NULL DEFAULT '0', + `wr_ing` int(11) NOT NULL DEFAULT '0', + + `ch_id` int(11) NOT NULL DEFAULT '0', + `ch_side` int(11) NOT NULL DEFAULT '0', + `ch_class` int(11) NOT NULL DEFAULT '0', + `ti_id` int(11) NOT NULL DEFAULT '0', + `ma_id` int(11) NOT NULL DEFAULT '0', + `wr_width` int(11) NOT NULL DEFAULT '0', + `wr_height` int(11) NOT NULL DEFAULT '0', + `wr_url` varchar(255) NOT NULL DEFAULT '', + `wr_type` varchar(255) NOT NULL DEFAULT '', + + + + `wr_1` varchar(255) NOT NULL DEFAULT '', + `wr_2` varchar(255) NOT NULL DEFAULT '', + `wr_3` varchar(255) NOT NULL DEFAULT '', + `wr_4` varchar(255) NOT NULL DEFAULT '', + `wr_5` varchar(255) NOT NULL DEFAULT '', + `wr_6` varchar(255) NOT NULL DEFAULT '', + `wr_7` varchar(255) NOT NULL DEFAULT '', + `wr_8` varchar(255) NOT NULL DEFAULT '', + `wr_9` varchar(255) NOT NULL DEFAULT '', + `wr_10` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`wr_id`), + KEY `wr_num_reply_parent` (`wr_num`,`wr_reply`,`wr_parent`), + KEY `wr_is_comment` (`wr_is_comment`,`wr_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/AvocadoEdition/adm/status_form_update.php b/AvocadoEdition/adm/status_form_update.php new file mode 100644 index 0000000..59fdb1b --- /dev/null +++ b/AvocadoEdition/adm/status_form_update.php @@ -0,0 +1,22 @@ + diff --git a/AvocadoEdition/adm/status_list.php b/AvocadoEdition/adm/status_list.php new file mode 100644 index 0000000..54f3920 --- /dev/null +++ b/AvocadoEdition/adm/status_list.php @@ -0,0 +1,231 @@ +전체목록'; + +$g5['title'] = '스탯설정 관리'; +include_once ('./admin.head.php'); + +$colspan =7; + +$pg_anchor = ''; + +?> + +
    +

    캐릭터 생성 시 지급되는 전체 스탯포인트 설정은 [ 환경설정 > 커뮤니티 설정 ] 에서 설정해 주시길 바랍니다.

    +
    + +
    +

    스탯 설정 목록

    + + +
    + + 전체 건 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 스탯명최대값최소값순서도움말기준
    + + + + + + + + + + + + + + /> + +
    자료가 없습니다.
    +
    + +
    + + +
    + +
    + + + +
    + + +
    +

    스탯 설정 등록

    + + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + + + +
    +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/status_list_update.php b/AvocadoEdition/adm/status_list_update.php new file mode 100644 index 0000000..b7b36b8 --- /dev/null +++ b/AvocadoEdition/adm/status_list_update.php @@ -0,0 +1,61 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/theme.js b/AvocadoEdition/adm/theme.js new file mode 100644 index 0000000..c0d4f0f --- /dev/null +++ b/AvocadoEdition/adm/theme.js @@ -0,0 +1,80 @@ +$(function() { + $(".theme_active").on("click", function() { + var theme = $(this).data("theme"); + var name = $(this).data("name"); + + if(!confirm(name+" 테마를 적용하시겠습니까?")) + return false; + + var set_default_skin = 0; + if($(this).data("set_default_skin") == true) { + if(confirm("기본환경설정, 1:1문의, 쇼핑몰 스킨을 테마에서 설정된 스킨으로 변경하시겠습니까?\n\n변경을 선택하시면 테마에서 지정된 스킨으로 회원스킨 등이 변경됩니다.")) + set_default_skin = 1; + } + + $.ajax({ + type: "POST", + url: "./theme_update.php", + data: { + "theme": theme, + "set_default_skin": set_default_skin + }, + cache: false, + async: false, + success: function(data) { + if(data) { + alert(data); + return false; + } + + document.location.reload(); + } + }); + }); + + $(".theme_deactive").on("click", function() { + var theme = $(this).data("theme"); + var name = $(this).data("name"); + + if(!confirm(name+" 테마 사용설정을 해제하시겠습니까?\n\n테마 설정을 해제하셔도 게시판 등의 스킨은 변경되지 않으므로 개별 변경작업이 필요합니다.")) + return false; + + $.ajax({ + type: "POST", + url: "./theme_update.php", + data: { + "theme": theme, + "type": "reset" + }, + cache: false, + async: false, + success: function(data) { + if(data) { + alert(data); + return false; + } + + document.location.reload(); + } + }); + }); + + $(".theme_preview").on("click", function() { + var theme = $(this).data("theme"); + + $("#theme_detail").remove(); + + $.ajax({ + type: "POST", + url: "./theme_detail.php", + data: { + "theme": theme + }, + cache: false, + async: false, + success: function(data) { + $("#theme_list").after(data); + } + }); + }); +}); \ No newline at end of file diff --git a/AvocadoEdition/adm/theme.php b/AvocadoEdition/adm/theme.php new file mode 100644 index 0000000..4962733 --- /dev/null +++ b/AvocadoEdition/adm/theme.php @@ -0,0 +1,78 @@ + + + +
    + 설치된 테마 + +
    + + 0) { ?> +
      + '; + else + $screenshot = ''; + + if($config['cf_theme'] == $theme[$i]) { + $btn_active = '사용중'; + } else { + $tconfig = get_theme_config_value($theme[$i], 'set_default_skin'); + if($tconfig['set_default_skin']) + $set_default_skin = 'true'; + else + $set_default_skin = 'false'; + + $btn_active = ''; + } + ?> +
    • +
      + +
      +

      +
      +
      + + + +
    • + +
    + +

    설치된 테마가 없습니다.

    + + +'; +else + $screenshot = ''; + +if($info['theme_uri']) { + $name = ''.$name.''; +} + +$maker = get_text($info['maker']); +if($info['maker_uri']) { + $maker = ''.$maker.''; +} + +$license = get_text($info['license']); +if($info['license_uri']) { + $license = ''.$license.''; +} +?> + +
    +

    +
    +
    +

    + + + + + + + + + + + + + +
    Version
    Maker
    License
    +
    + 미리보기 + +
    +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/adm/theme_preview.php b/AvocadoEdition/adm/theme_preview.php new file mode 100644 index 0000000..73a002c --- /dev/null +++ b/AvocadoEdition/adm/theme_preview.php @@ -0,0 +1,72 @@ +'; +} else { + $btn_active = ''; +} + +$g5['title'] = get_text($info['theme_name']).' 테마 미리보기'; +require_once(G5_PATH.'/head.sub.php'); +?> + + + + +
    + +
    + +
    + +
    + + $val) { + if(preg_match('#^qa_.+$#', $key)) { + if($val) { + if(!preg_match('#^theme/.+$#', $val)) + $val = 'theme/'.$val; + + $qa_sql_common[] = " $key = '$val' "; + } + + continue; + } + + if(preg_match('#^de_.+$#', $key)) { + if(!isset($default[$key])) + continue; + + if($val) { + if(!preg_match('#^theme/.+$#', $val)) + $val = 'theme/'.$val; + + $de_sql_common[] = " $key = '$val' "; + } + + continue; + } + + if(!isset($config[$key])) + continue; + + if($val) { + if(!preg_match('#^theme/.+$#', $val)) + $val = 'theme/'.$val; + + $sql_common[] = " $key = '$val' "; + } + } + + if(!empty($sql_common)) { + $sql = " update {$g5['config_table']} set " . implode(', ', $sql_common); + sql_query($sql); + } + + if(!empty($qa_sql_common)) { + $sql = " update {$g5['qa_config_table']} set " . implode(', ', $qa_sql_common); + sql_query($sql); + } + + if(!empty($de_sql_common)) { + $sql = " update {$g5['g5_shop_default_table']} set " . implode(', ', $de_sql_common); + sql_query($sql); + } + } +} + +die(''); \ No newline at end of file diff --git a/AvocadoEdition/adm/thumbnail_file_delete.php b/AvocadoEdition/adm/thumbnail_file_delete.php new file mode 100644 index 0000000..3b5ea0b --- /dev/null +++ b/AvocadoEdition/adm/thumbnail_file_delete.php @@ -0,0 +1,68 @@ + + +
    +

    + 완료 메세지가 나오기 전에 프로그램의 실행을 중지하지 마십시오. +

    +
    + +썸네일디렉토리를 열지못했습니다.

    '; +} + +$cnt=0; +echo '
      '.PHP_EOL; + +foreach($directory as $dir) { + $files = glob($dir.'/thumb-*'); + if (is_array($files)) { + foreach($files as $thumbnail) { + $cnt++; + @unlink($thumbnail); + + echo '
    • '.$thumbnail.'
    • '.PHP_EOL; + + flush(); + + if ($cnt%10==0) + echo PHP_EOL; + } + } +} + +echo '
    • 완료됨
    '.PHP_EOL; +echo '

    썸네일 '.$cnt.'건의 삭제 완료됐습니다.
    프로그램의 실행을 끝마치셔도 좋습니다.

    '.PHP_EOL; +?> + + \ No newline at end of file diff --git a/AvocadoEdition/adm/title_has_list.php b/AvocadoEdition/adm/title_has_list.php new file mode 100644 index 0000000..081fd8c --- /dev/null +++ b/AvocadoEdition/adm/title_has_list.php @@ -0,0 +1,262 @@ +전체목록'; + + +$g5['title'] = '타이틀 보유현황 관리'; +include_once ('./admin.head.php'); + +$colspan = 6; + +if (strstr($sfl, "ch_id")) + $ch_id = $stx; +else + $ch_id = ""; + + + +$pg_anchor = ''; + +$frm_submit = '
    + +
    '; + + +?> + +
    + + + + + + + +
    +

    타이틀 지급

    + +
    + + + + + + + + + + + + + + + + + + + +
    지급유형 + + +    + + +
    캐릭터 이름 + + + +
    +
    타이틀 이름 + + +
    +
    +
    +
    + +
    + +
    +
    + + +
    +

    타이틀 보유 현황

    + + +
    + + 전체 건 +
    + +
    + + + + + +
    +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + +  소유자타이틀 이름상태사용여부
    + + + + + + + + + + 미착용"?> + + +
    자료가 없습니다.
    +
    + +
    + +
    + +
    + + + +
    + + + + + diff --git a/AvocadoEdition/adm/title_has_list_delete.php b/AvocadoEdition/adm/title_has_list_delete.php new file mode 100644 index 0000000..09901bc --- /dev/null +++ b/AvocadoEdition/adm/title_has_list_delete.php @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/title_has_update.php b/AvocadoEdition/adm/title_has_update.php new file mode 100644 index 0000000..ec80000 --- /dev/null +++ b/AvocadoEdition/adm/title_has_update.php @@ -0,0 +1,72 @@ + diff --git a/AvocadoEdition/adm/title_list.php b/AvocadoEdition/adm/title_list.php new file mode 100644 index 0000000..e8b6e50 --- /dev/null +++ b/AvocadoEdition/adm/title_list.php @@ -0,0 +1,230 @@ +전체목록'; + +$g5['title'] = '타이틀 관리'; +include_once('./admin.head.php'); + + +$pg_anchor = ''; + +$frm_submit = '
    + +
    '; + +$colspan = 5; +?> + +
    + +

    타이틀 목록

    + + +
    + + 타이틀 수 개 +
    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    목록
    + + + 이미지이미지 수정타이틀명사용유무
    + + + + + + + + + + + + + +
    자료가 없습니다.
    +
    + +
    + + +
    +
    + + + + +
    + +
    +
    + + + + + + + + + +

    타이틀 신규 등록

    + + +
    + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/adm/title_list_update.php b/AvocadoEdition/adm/title_list_update.php new file mode 100644 index 0000000..3f401c5 --- /dev/null +++ b/AvocadoEdition/adm/title_list_update.php @@ -0,0 +1,80 @@ + diff --git a/AvocadoEdition/adm/title_update.php b/AvocadoEdition/adm/title_update.php new file mode 100644 index 0000000..654e089 --- /dev/null +++ b/AvocadoEdition/adm/title_update.php @@ -0,0 +1,43 @@ + diff --git a/AvocadoEdition/adm/viewer_form.php b/AvocadoEdition/adm/viewer_form.php new file mode 100644 index 0000000..98ea02f --- /dev/null +++ b/AvocadoEdition/adm/viewer_form.php @@ -0,0 +1,256 @@ + +
  • 메뉴 화면 구성
  • +
  • 메인 화면 구성
  • +
  • 도움말
  • +'; + +$frm_submit = '
    + +
    '; + +?> + + +
    + + +
    +

    커뮤니티 메뉴 화면

    + + +
    + + + + + + + + + + + + + + + + +
    메뉴영역 태그 + + +
    모바일 메뉴영역 태그 + + +
    +
    +
    + + + +
    +

    메인화면 구성

    + + +
    + + + + + + + + + + + + + + + + +
    메인화면 태그 + + +
    모바일 메인화면 태그 + + +
    +
    +
    + + + + + +
    + +
    +

    도움말

    + + +
    +

    ※ 특수 기능 삽입 코드 : 내용 작성 시, 아래의 글자를 입력하면 화면에 해당 기능을 가진 폼이 출력됩니다.

    +

    ※ 출력폼 수정을 원할 시, 파일 위치로 가셔서 해당 파일에 작성되어 있는 텍스트 혹은 기능을 수정하셔야 합니다.

    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    기능명코드문자파일위치설명
    로그인 링크 + + + templete/txt.login.php + + 로그인 링크를 출력할 때 사용합니다. 비회원인 상태에서만 출력 되며, 로그인 후에는 출력되지 않습니다. +
    로그아웃 링크 + + + templete/txt.logout.php + + 로그아웃 링크를 출력할 때 사용합니다. 회원인 상태에서만 출력 되며, 로그아웃 후에는 출력되지 않습니다. +
    회원가입 링크 + + + templete/txt.join.php + + 회원가입 링크를 출력할 때 사용합니다. 비회원인 상태에서만 출력 되며, 로그인 후에는 출력되지 않습니다. +
    마이페이지 링크 + + + templete/txt.mypage.php + + 마이페이지 링크를 출력할 때 사용합니다. 회원인 상태에서만 출력됩니다. +
    외부로그인 + + + skin/outlogin/basic/outlogin.skin.1.php (로그인 전)
    + skin/outlogin/basic/outlogin.skin.2.php (로그인 후) +
    + 로그인창을 출력할 때 사용합니다. 로그인/로그인 이후 폼이 다르게 출력됩니다. +
    트위터 타임라인 + + + templete/txt.twitter.php + + 관리자 환경설정에서 설정한 트위터의 타임라인을 출력합니다. +
    메인 슬라이드 + + + templete/txt.visual.php + + 메인 슬라이드에 등록한 배너 슬라이드를 출력합니다. +
    배경음악 컨트롤 + + + templete/txt.bgm.php + + 배경음악을 컨트롤 하는 버튼을 출력합니다. 접속기기가 모바일일 경우, 출력되지 않습니다. +
    +
    + +
    + + + + + diff --git a/AvocadoEdition/adm/viewer_form_update.php b/AvocadoEdition/adm/viewer_form_update.php new file mode 100644 index 0000000..ed6e49c --- /dev/null +++ b/AvocadoEdition/adm/viewer_form_update.php @@ -0,0 +1,62 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/visit.sub.php b/AvocadoEdition/adm/visit.sub.php new file mode 100644 index 0000000..ae4a4f7 --- /dev/null +++ b/AvocadoEdition/adm/visit.sub.php @@ -0,0 +1,57 @@ + + + + +
    +
    + 기간별검색   + + + ~ + + + +
    +
    +
    + + + diff --git a/AvocadoEdition/adm/visit_browser.php b/AvocadoEdition/adm/visit_browser.php new file mode 100644 index 0000000..aca6850 --- /dev/null +++ b/AvocadoEdition/adm/visit_browser.php @@ -0,0 +1,97 @@ + $max) $max = $arr[$s]; + + $sum_count++; +} +?> + +
    + + + + + + + + + + + + + + + + + + + + $value) { + $count = $arr[$key]; + if ($save_count != $count) { + $i++; + $no = $i; + $save_count = $count; + } else { + $no = ""; + } + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + '; + } + ?> + +
    목록
    순위브라우저그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_date.php b/AvocadoEdition/adm/visit_date.php new file mode 100644 index 0000000..29aab17 --- /dev/null +++ b/AvocadoEdition/adm/visit_date.php @@ -0,0 +1,86 @@ + $max) $max = $row['cnt']; + + $sum_count += $row['cnt']; +} +?> + +
    + + + + + + + + + + + + + + + + + + + $value) { + $count = $value; + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + '; + } + ?> + +
    목록
    년-월-일그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_delete.php b/AvocadoEdition/adm/visit_delete.php new file mode 100644 index 0000000..690da29 --- /dev/null +++ b/AvocadoEdition/adm/visit_delete.php @@ -0,0 +1,121 @@ + + +
    + 접속자 로그를 삭제할 년도와 방법을 선택해주십시오. +
    + +
    + +
    + + + + + + + + + + + + + + + + + + + + +
    일자선택 + 년 +     + 월 + + +
    삭제방법선택 + +
    관리자 비밀번호 + +
    +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/adm/visit_delete_update.php b/AvocadoEdition/adm/visit_delete_update.php new file mode 100644 index 0000000..70ad6ca --- /dev/null +++ b/AvocadoEdition/adm/visit_delete_update.php @@ -0,0 +1,60 @@ + \ No newline at end of file diff --git a/AvocadoEdition/adm/visit_device.php b/AvocadoEdition/adm/visit_device.php new file mode 100644 index 0000000..ec35059 --- /dev/null +++ b/AvocadoEdition/adm/visit_device.php @@ -0,0 +1,101 @@ + $max) $max = $arr[$s]; + + $sum_count++; +} +?> + +
    + + + + + + + + + + + + + + + + + + + + $value) { + $count = $arr[$key]; + if ($save_count != $count) { + $i++; + $no = $i; + $save_count = $count; + } else { + $no = ''; + } + + if (!$key) { + $key = '기타'; + } + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + '; + } + ?> + +
    목록
    순위접속기기그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_domain.php b/AvocadoEdition/adm/visit_domain.php new file mode 100644 index 0000000..da7d2db --- /dev/null +++ b/AvocadoEdition/adm/visit_domain.php @@ -0,0 +1,104 @@ + $max) $max = $arr[$s]; + + $sum_count++; +} +?> + +
    + + + + + + + + + + + + + + + + + + + + $value) { + $count = $arr[$key]; + if ($save_count != $count) { + $i++; + $no = $i; + $save_count = $count; + } else { + $no = ''; + } + + if (!$key) { + $link = ''; + $link2 = ''; + $key = '직접'; + } else { + $link = ''; + $link2 = ''; + } + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + '; + } + ?> + +
    목록
    순위접속 도메인그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_hour.php b/AvocadoEdition/adm/visit_hour.php new file mode 100644 index 0000000..2e0a692 --- /dev/null +++ b/AvocadoEdition/adm/visit_hour.php @@ -0,0 +1,82 @@ + $max) $max = $row['cnt']; + + $sum_count += $row['cnt']; +} +?> + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    시간그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_list.php b/AvocadoEdition/adm/visit_list.php new file mode 100644 index 0000000..02ce73f --- /dev/null +++ b/AvocadoEdition/adm/visit_list.php @@ -0,0 +1,118 @@ + + +
    + + + + + + + + + + + + + + ', '&'), array("<", ">", "&"), $referer); + $link = ''; + $link = str_replace('&', "&", $link); + $link2 = ''; + } + + if ($is_admin == 'super') + $ip = $row['vi_ip']; + else + $ip = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $row['vi_ip']); + + if ($brow == '기타') { $brow = ''.$brow.''; } + if ($os == '기타') { $os = ''.$os.''; } + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + '; + ?> + +
    목록
    IP접속 경로브라우저OS접속기기일시
    자료가 없거나 관리자에 의해 삭제되었습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_month.php b/AvocadoEdition/adm/visit_month.php new file mode 100644 index 0000000..911e569 --- /dev/null +++ b/AvocadoEdition/adm/visit_month.php @@ -0,0 +1,90 @@ + $max) $max = $row['cnt']; + + $sum_count += $row['cnt']; +} +?> + +
    + + + + + + + + + + + + + + + + + + + $value) { + $count = $value; + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + '; + } + ?> + + +
    목록
    년-월그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_os.php b/AvocadoEdition/adm/visit_os.php new file mode 100644 index 0000000..32e6892 --- /dev/null +++ b/AvocadoEdition/adm/visit_os.php @@ -0,0 +1,101 @@ + $max) $max = $arr[$s]; + + $sum_count++; +} +?> + +
    + + + + + + + + + + + + + + + + + + + + $value) { + $count = $arr[$key]; + if ($save_count != $count) { + $i++; + $no = $i; + $save_count = $count; + } else { + $no = ''; + } + + if (!$key) { + $key = 'Unknown'; + } + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + + '; + } + ?> + +
    목록
    순위OS그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_search.php b/AvocadoEdition/adm/visit_search.php new file mode 100644 index 0000000..47b87fd --- /dev/null +++ b/AvocadoEdition/adm/visit_search.php @@ -0,0 +1,149 @@ +처음'; //페이지 처음으로 (초기화용도) +?> + +
    +
    + + + + + + +
    +
    + + + + + + + + diff --git a/AvocadoEdition/adm/visit_week.php b/AvocadoEdition/adm/visit_week.php new file mode 100644 index 0000000..1842fee --- /dev/null +++ b/AvocadoEdition/adm/visit_week.php @@ -0,0 +1,81 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + } + ?> + +
    목록
    요일그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/visit_year.php b/AvocadoEdition/adm/visit_year.php new file mode 100644 index 0000000..4bd0f0d --- /dev/null +++ b/AvocadoEdition/adm/visit_year.php @@ -0,0 +1,86 @@ + $max) $max = $row['cnt']; + + $sum_count += $row['cnt']; +} +?> + +
    + + + + + + + + + + + + + + + + + + + $value) { + $count = $value; + + $rate = ($count / $sum_count * 100); + $s_rate = number_format($rate, 1); + + $bg = 'bg'.($i%2); + ?> + + + + + + + + + '; + } + ?> + +
    목록
    그래프접속자수비율(%)
    합계100%
    +
    + +
    +
    자료가 없습니다.
    +
    + + diff --git a/AvocadoEdition/adm/write_count.php b/AvocadoEdition/adm/write_count.php new file mode 100644 index 0000000..700fb33 --- /dev/null +++ b/AvocadoEdition/adm/write_count.php @@ -0,0 +1,210 @@ +', 0); +add_javascript('', 0); +add_javascript('', 0); +add_javascript('', 0); +add_javascript('', 0); +add_javascript('', 0); + +if (!($graph == 'line' || $graph == 'bar')) + $graph = 'line'; + +if ($graph == 'bar') { + // 바 타입으로 사용하는 코드입니다. + add_javascript('', 0); + add_javascript('', 0); + add_javascript('', 0); +} + +$g5['title'] = '글,댓글 현황'; +include_once ('./admin.head.php'); + +$period_array = array( + '오늘'=>array('시간', 0), + '어제'=>array('시간', 0), + '7일전'=>array('일', 7), + '14일전'=>array('일', 14), + '30일전'=>array('일', 30), + '3개월전'=>array('주', 90), + '6개월전'=>array('주', 180), + '1년전'=>array('월', 365), + '2년전'=>array('월', 365*2), + '3년전'=>array('월', 365*3), + '5년전'=>array('년', 365*5), + '10년전'=>array('년', 365*10), +); + +$is_period = false; +foreach($period_array as $key=>$value) { + if ($key == $period) { + $is_period = true; + break; + } +} +if (!$is_period) + $period = '오늘'; + +$day = $period_array[$period][0]; + +$today = date('Y-m-d', G5_SERVER_TIME); +$yesterday = date('Y-m-d', G5_SERVER_TIME - 86400); + +if ($period == '오늘') { + $from = $today; + $to = $from; +} else if ($period == '어제') { + $from = $yesterday; + $to = $from; +} else if ($period == '내일') { + $from = date('Y-m-d', G5_SERVER_TIME + (86400 * 2)); + $to = $from; +} else { + $from = date('Y-m-d', G5_SERVER_TIME - (86400 * $period_array[$period][1])); + $to = $yesterday; +} + +$sql_bo_table = ''; +if ($bo_table) + $sql_bo_table = "and bo_table = '$bo_table'"; + +switch ($day) { + case '시간' : + $sql = " select substr(bn_datetime,6,8) as hours, sum(if(wr_id=wr_parent,1,0)) as wcount, sum(if(wr_id=wr_parent,0,1)) as ccount from {$g5['board_new_table']} where substr(bn_datetime,1,10) between '$from' and '$to' {$sql_bo_table} group by hours order by bn_datetime "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + // 월-일 시간 + $line1[] = "['".substr($row['hours'],0,8)."',".$row['wcount'].']'; + $line2[] = "['".substr($row['hours'],0,8)."',".$row['ccount'].']'; + } + break; + case '일' : + $sql = " select substr(bn_datetime,1,10) as days, sum(if(wr_id=wr_parent,1,0)) as wcount, sum(if(wr_id=wr_parent,0,1)) as ccount from {$g5['board_new_table']} where substr(bn_datetime,1,10) between '$from' and '$to' {$sql_bo_table} group by days order by bn_datetime "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + // 월-일 + $line1[] = "['".substr($row['days'],5,5)."',".$row['wcount'].']'; + $line2[] = "['".substr($row['days'],5,5)."',".$row['ccount'].']'; + } + break; + case '주' : + $sql = " select concat(substr(bn_datetime,1,4), '-', weekofyear(bn_datetime)) as weeks, sum(if(wr_id=wr_parent,1,0)) as wcount, sum(if(wr_id=wr_parent,0,1)) as ccount from {$g5['board_new_table']} where substr(bn_datetime,1,10) between '$from' and '$to' {$sql_bo_table} group by weeks order by bn_datetime "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + // 올해의 몇주로 보여주면 바로 확인이 안되므로 주를 날짜로 바꾼다. + // 년-월-일 + list($lyear, $lweek) = explode('-', $row['weeks']); + $date = date('y-m-d', strtotime($lyear.'W'.str_pad($lweek, 2, '0', STR_PAD_LEFT))); + $line1[] = "['".$date."',".$row['wcount'].']'; + $line2[] = "['".$date."',".$row['ccount'].']'; + } + break; + case '월' : + $sql = " select substr(bn_datetime,1,7) as months, sum(if(wr_id=wr_parent,1,0)) as wcount, sum(if(wr_id=wr_parent,0,1)) as ccount from {$g5['board_new_table']} where substr(bn_datetime,1,10) between '$from' and '$to' {$sql_bo_table} group by months order by bn_datetime "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + // 년-월 + $line1[] = "['".substr($row['months'],2,5)."',".$row['wcount'].']'; + $line2[] = "['".substr($row['months'],2,5)."',".$row['ccount'].']'; + } + break; + case '년' : + $sql = " select substr(bn_datetime,1,4) as years, sum(if(wr_id=wr_parent,1,0)) as wcount, sum(if(wr_id=wr_parent,0,1)) as ccount from {$g5['board_new_table']} where substr(bn_datetime,1,10) between '$from' and '$to' {$sql_bo_table} group by years order by bn_datetime "; + $result = sql_query($sql); + for ($i=0; $row=sql_fetch_array($result); $i++) { + // 년(4자리) + $line1[] = "['".substr($row['years'],0,4)."',".$row['wcount'].']'; + $line2[] = "['".substr($row['years'],0,4)."',".$row['ccount'].']'; + } + break; +} +?> +
    +
    + + + + + + + +
    +
      +
    • 글 수
    • +
    • 댓글 수
    • +
    +
    +
    +
    +그래프를 만들 데이터가 없습니다.\n"; +} else { +?> +
    +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/ajax/_common.php b/AvocadoEdition/ajax/_common.php new file mode 100644 index 0000000..7d8b2a1 --- /dev/null +++ b/AvocadoEdition/ajax/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/ajax/_search_character.php b/AvocadoEdition/ajax/_search_character.php new file mode 100644 index 0000000..5ab9afb --- /dev/null +++ b/AvocadoEdition/ajax/_search_character.php @@ -0,0 +1,35 @@ +
  • 회원만 검색 가능합니다.
  • "; +} else { + if($keyword == "") { + echo "
    • 키워드를 입력해 주시길 바랍니다.
    "; + } else { + echo "
    "; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/ajax/_search_item.php b/AvocadoEdition/ajax/_search_item.php new file mode 100644 index 0000000..eea1c22 --- /dev/null +++ b/AvocadoEdition/ajax/_search_item.php @@ -0,0 +1,44 @@ +
  • 회원만 검색 가능합니다.
  • "; +} else { + if($keyword == "") { + echo "
    • 키워드를 입력해 주시길 바랍니다.
    "; + } else { + echo "
      "; + $sql = " select it_img, it_name, it_id, it_content from {$g5['item_table']} where it_name like '%{$keyword}%'"; + + if($option) { + if($option == '뽑기') { + $sql .= " and it_type = '{$option}'"; + } else if($option == '레시피') { + $sql .= " and it_use_recepi = '1'"; + } + } + $sql .= "order by it_name asc"; + $result = sql_query($sql); + for($i=0; $row = sql_fetch_array($result); $i++) { + ?> +
    • + +
      + +
      +
      +

      아이템:

      +

      설명:

      +
      +
      +
    • + [ ".$keyword." ]에 대한 검색결과가 존재하지 않습니다."; + } + echo "
    "; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/ajax/_search_member.php b/AvocadoEdition/ajax/_search_member.php new file mode 100644 index 0000000..49b7387 --- /dev/null +++ b/AvocadoEdition/ajax/_search_member.php @@ -0,0 +1,36 @@ +
  • 회원만 검색 가능합니다.
  • "; +} else { + if($keyword == "") { + echo "
    • 키워드를 입력해 주시길 바랍니다.
    "; + } else { + echo "
      "; + $sql = " select mb_nick, mb_name, mb_id, ch_id from {$g5['member_table']} where mb_name like '%{$keyword}%' and mb_level > 1 order by mb_nick asc"; + $result = sql_query($sql); + for($i=0; $row = sql_fetch_array($result); $i++) { + $ch = sql_fetch("select ch_thumb, ch_name from {$g5['character_table']} where ch_id = '{$row['ch_id']}'"); + ?> +
    • + +
      + +
      +
      +

      대표캐릭명:

      +

      오너명:

      +
      +
      +
    • + [ ".$keyword." ]에 대한 검색결과가 존재하지 않습니다."; + } + echo "
    "; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/ajax/_search_title.php b/AvocadoEdition/ajax/_search_title.php new file mode 100644 index 0000000..b075f40 --- /dev/null +++ b/AvocadoEdition/ajax/_search_title.php @@ -0,0 +1,34 @@ +
  • 회원만 검색 가능합니다.
  • "; +} else { + if($keyword == "") { + echo "
    • 키워드를 입력해 주시길 바랍니다.
    "; + } else { + echo "
      "; + $sql = " select ti_id, ti_title, ti_img from {$g5['title_table']} where ti_title like '%{$keyword}%' order by ti_title asc"; + $result = sql_query($sql); + for($i=0; $row = sql_fetch_array($result); $i++) { + ?> +
    • + +
      + +
      +
      +

      타이틀명:

      +
      +
      +
    • + [ ".$keyword." ]에 대한 검색결과가 존재하지 않습니다."; + } + echo "
    "; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/ajax/board_call.php b/AvocadoEdition/ajax/board_call.php new file mode 100644 index 0000000..947ed20 --- /dev/null +++ b/AvocadoEdition/ajax/board_call.php @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/AvocadoEdition/ajax/close_call.php b/AvocadoEdition/ajax/close_call.php new file mode 100644 index 0000000..8f1dfcd --- /dev/null +++ b/AvocadoEdition/ajax/close_call.php @@ -0,0 +1,9 @@ + diff --git a/AvocadoEdition/ajax/close_memo.php b/AvocadoEdition/ajax/close_memo.php new file mode 100644 index 0000000..7f4543d --- /dev/null +++ b/AvocadoEdition/ajax/close_memo.php @@ -0,0 +1,8 @@ + diff --git a/AvocadoEdition/ajax/inventory_popup.php b/AvocadoEdition/ajax/inventory_popup.php new file mode 100644 index 0000000..92b437b --- /dev/null +++ b/AvocadoEdition/ajax/inventory_popup.php @@ -0,0 +1,111 @@ + + +
    +
    +
    +
    + CLOSE +
    + + \ No newline at end of file diff --git a/AvocadoEdition/ajax/load_board_call.php b/AvocadoEdition/ajax/load_board_call.php new file mode 100644 index 0000000..32ae5d5 --- /dev/null +++ b/AvocadoEdition/ajax/load_board_call.php @@ -0,0 +1,60 @@ + + +
    +
    +
    +

    + 님이 호출하셨습니다. [ 확인하지 않은 호출 건 ] +

    + 호출내역확인 + 바로가기 + 닫기 +
    +
    +
    + + + + + + + diff --git a/AvocadoEdition/ajax/load_memo_call.php b/AvocadoEdition/ajax/load_memo_call.php new file mode 100644 index 0000000..e448e16 --- /dev/null +++ b/AvocadoEdition/ajax/load_memo_call.php @@ -0,0 +1,59 @@ + +
    +
    +
    +

    + 님으로부터 쪽지가 도착하였습니다."?> +

    + 쪽지함 바로가기 + 닫기 +
    +
    +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/ajax/memo_call.MP3 b/AvocadoEdition/ajax/memo_call.MP3 new file mode 100644 index 0000000000000000000000000000000000000000..a260602591677f7f5e63ab5714f41f0623367031 GIT binary patch literal 107206 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/ajax/memo_call.php b/AvocadoEdition/ajax/memo_call.php new file mode 100644 index 0000000..ebf9029 --- /dev/null +++ b/AvocadoEdition/ajax/memo_call.php @@ -0,0 +1,40 @@ + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/_common.php b/AvocadoEdition/bbs/_common.php new file mode 100644 index 0000000..b556cc9 --- /dev/null +++ b/AvocadoEdition/bbs/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/_head.php b/AvocadoEdition/bbs/_head.php new file mode 100644 index 0000000..c9bf5a4 --- /dev/null +++ b/AvocadoEdition/bbs/_head.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/_head.sub.php b/AvocadoEdition/bbs/_head.sub.php new file mode 100644 index 0000000..0067cf7 --- /dev/null +++ b/AvocadoEdition/bbs/_head.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/_tail.php b/AvocadoEdition/bbs/_tail.php new file mode 100644 index 0000000..ab638fe --- /dev/null +++ b/AvocadoEdition/bbs/_tail.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/_tail.sub.php b/AvocadoEdition/bbs/_tail.sub.php new file mode 100644 index 0000000..392cf17 --- /dev/null +++ b/AvocadoEdition/bbs/_tail.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.autosave.php b/AvocadoEdition/bbs/ajax.autosave.php new file mode 100644 index 0000000..f8e1308 --- /dev/null +++ b/AvocadoEdition/bbs/ajax.autosave.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.autosavedel.php b/AvocadoEdition/bbs/ajax.autosavedel.php new file mode 100644 index 0000000..c3e7d9d --- /dev/null +++ b/AvocadoEdition/bbs/ajax.autosavedel.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.autosavelist.php b/AvocadoEdition/bbs/ajax.autosavelist.php new file mode 100644 index 0000000..7aff8e1 --- /dev/null +++ b/AvocadoEdition/bbs/ajax.autosavelist.php @@ -0,0 +1,21 @@ +\n"; +echo "\n"; +for ($i=0; $row=sql_fetch_array($result); $i++) { + $subject = htmlspecialchars(utf8_strcut($row['as_subject'], 25), ENT_QUOTES); + $datetime = substr($row['as_datetime'],2,14); + echo "\n"; + echo "{$row['as_id']}\n"; + echo "{$row['as_uid']}\n"; + echo "\n"; + echo "{$datetime}\n"; + echo "\n"; +} +echo ""; +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.autosaveload.php b/AvocadoEdition/bbs/ajax.autosaveload.php new file mode 100644 index 0000000..2e55e5f --- /dev/null +++ b/AvocadoEdition/bbs/ajax.autosaveload.php @@ -0,0 +1,18 @@ +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.comment_token.php b/AvocadoEdition/bbs/ajax.comment_token.php new file mode 100644 index 0000000..c90b09b --- /dev/null +++ b/AvocadoEdition/bbs/ajax.comment_token.php @@ -0,0 +1,14 @@ +$token))); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.filter.php b/AvocadoEdition/bbs/ajax.filter.php new file mode 100644 index 0000000..0e3a21e --- /dev/null +++ b/AvocadoEdition/bbs/ajax.filter.php @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.mb_email.php b/AvocadoEdition/bbs/ajax.mb_email.php new file mode 100644 index 0000000..fbd1632 --- /dev/null +++ b/AvocadoEdition/bbs/ajax.mb_email.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.mb_hp.php b/AvocadoEdition/bbs/ajax.mb_hp.php new file mode 100644 index 0000000..eeeef88 --- /dev/null +++ b/AvocadoEdition/bbs/ajax.mb_hp.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.mb_id.php b/AvocadoEdition/bbs/ajax.mb_id.php new file mode 100644 index 0000000..9adfd1e --- /dev/null +++ b/AvocadoEdition/bbs/ajax.mb_id.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.mb_nick.php b/AvocadoEdition/bbs/ajax.mb_nick.php new file mode 100644 index 0000000..9c22c5d --- /dev/null +++ b/AvocadoEdition/bbs/ajax.mb_nick.php @@ -0,0 +1,17 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/ajax.mb_recommend.php b/AvocadoEdition/bbs/ajax.mb_recommend.php new file mode 100644 index 0000000..bdc7964 --- /dev/null +++ b/AvocadoEdition/bbs/ajax.mb_recommend.php @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/alert.php b/AvocadoEdition/bbs/alert.php new file mode 100644 index 0000000..f6f779c --- /dev/null +++ b/AvocadoEdition/bbs/alert.php @@ -0,0 +1,113 @@ +", $msg); + +$url = clean_xss_tags($url); +if (!$url) $url = clean_xss_tags($_SERVER['HTTP_REFERER']); + +$url = preg_replace("/[\<\>\'\"\\\'\\\"\(\)]/", "", $url); + +// url 체크 +check_url_host($url); + +if($error) { + $header2 = "다음 항목에 오류가 있습니다."; +} else { + $header2 = "다음 내용을 확인해 주세요."; +} +?> + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/alert_close.php b/AvocadoEdition/bbs/alert_close.php new file mode 100644 index 0000000..830b3c6 --- /dev/null +++ b/AvocadoEdition/bbs/alert_close.php @@ -0,0 +1,61 @@ +", $msg); + +if($error) { + $header2 = "다음 항목에 오류가 있습니다."; + $msg3 = "새창을 닫으시고 이전 작업을 다시 시도해 주세요."; +} else { + $header2 = "다음 내용을 확인해 주세요."; + $msg3 = "새창을 닫으신 후 서비스를 이용해 주세요."; +} +?> + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/board.php b/AvocadoEdition/bbs/board.php new file mode 100644 index 0000000..fd12e81 --- /dev/null +++ b/AvocadoEdition/bbs/board.php @@ -0,0 +1,247 @@ + ".((G5_IS_MOBILE && $board['bo_mobile_subject']) ? $board['bo_mobile_subject'] : $board['bo_subject']); +} else { + if ($member['mb_level'] < $board['bo_list_level']) { + if ($member['mb_id']) + alert('목록을 볼 권한이 없습니다.', G5_URL); + else + alert('목록을 볼 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?'.$qstr.'&url='.urlencode(G5_BBS_URL.'/board.php?bo_table='.$bo_table.($qstr?'&':''))); + } + + // 본인확인을 사용한다면 + if ($config['cf_cert_use'] && !$is_admin) { + // 인증된 회원만 가능 + if ($board['bo_use_cert'] != '' && $is_guest) { + alert('이 게시판은 본인확인 하신 회원님만 글읽기가 가능합니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?wr_id='.$wr_id.$qstr.'&url='.urlencode(G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.$qstr)); + } + + if ($board['bo_use_cert'] == 'cert' && !$member['mb_certify']) { + alert('이 게시판은 본인확인 하신 회원님만 글읽기가 가능합니다.\\n\\n회원정보 수정에서 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'adult' && !$member['mb_adult']) { + alert('이 게시판은 본인확인으로 성인인증 된 회원님만 글읽기가 가능합니다.\\n\\n현재 성인인데 글읽기가 안된다면 회원정보 수정에서 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-cert' && $member['mb_certify'] != 'hp') { + alert('이 게시판은 휴대폰 본인확인 하신 회원님만 글읽기가 가능합니다.\\n\\n회원정보 수정에서 휴대폰 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-adult' && (!$member['mb_adult'] || $member['mb_certify'] != 'hp')) { + alert('이 게시판은 휴대폰 본인확인으로 성인인증 된 회원님만 글읽기가 가능합니다.\\n\\n현재 성인인데 글읽기가 안된다면 회원정보 수정에서 휴대폰 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } + } + + if (!isset($page) || (isset($page) && $page == 0)) $page = 1; + + $g5['title'] = ((G5_IS_MOBILE && $board['bo_mobile_subject']) ? $board['bo_mobile_subject'] : $board['bo_subject']).' '.$page.' 페이지'; +} + +include_once(G5_PATH.'/head.sub.php'); + +$width = $board['bo_table_width']; +if ($width <= 100) + $width .= '%'; +else + $width .='px'; + +// IP보이기 사용 여부 +$ip = ""; +$is_ip_view = $board['bo_use_ip_view']; +if ($is_admin) { + $is_ip_view = true; + if (array_key_exists('wr_ip', $write)) { + $ip = $write['wr_ip']; + } +} else { + // 관리자가 아니라면 IP 주소를 감춘후 보여줍니다. + if (isset($write['wr_ip'])) { + $ip = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $write['wr_ip']); + } +} + +// 분류 사용 +$is_category = false; +$category_name = ''; +if ($board['bo_use_category']) { + $is_category = true; + if (array_key_exists('ca_name', $write)) { + $category_name = $write['ca_name']; // 분류명 + } +} + +// 추천 사용 +$is_good = false; +if ($board['bo_use_good']) + $is_good = true; + +// 비추천 사용 +$is_nogood = false; +if ($board['bo_use_nogood']) + $is_nogood = true; + +$admin_href = ""; +// 최고관리자 또는 그룹관리자라면 +if ($member['mb_id'] && ($is_admin == 'super' || $group['gr_admin'] == $member['mb_id'])) + $admin_href = G5_ADMIN_URL.'/board_form.php?w=u&bo_table='.$bo_table; + +include_once(G5_BBS_PATH.'/board_head.php'); + +// 게시물 아이디가 있다면 게시물 보기를 INCLUDE +if (isset($wr_id) && $wr_id) { + include_once(G5_BBS_PATH.'/view.php'); +} + +// 전체목록보이기 사용이 "예" 또는 wr_id 값이 없다면 목록을 보임 +//if ($board['bo_use_list_view'] || empty($wr_id)) +if ($member['mb_level'] >= $board['bo_list_level'] && $board['bo_use_list_view'] || empty($wr_id)) { + if($board['bo_type'] == 'mmb') + include_once (G5_BBS_PATH.'/list.mmb.php'); + else + include_once (G5_BBS_PATH.'/list.php'); + +} + +include_once(G5_BBS_PATH.'/board_tail.php'); + +echo "\n\n"; + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/board_head.php b/AvocadoEdition/bbs/board_head.php new file mode 100644 index 0000000..f426956 --- /dev/null +++ b/AvocadoEdition/bbs/board_head.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/board_list_update.php b/AvocadoEdition/bbs/board_list_update.php new file mode 100644 index 0000000..a439240 --- /dev/null +++ b/AvocadoEdition/bbs/board_list_update.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/board_tail.php b/AvocadoEdition/bbs/board_tail.php new file mode 100644 index 0000000..d0f8289 --- /dev/null +++ b/AvocadoEdition/bbs/board_tail.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/character_list.php b/AvocadoEdition/bbs/character_list.php new file mode 100644 index 0000000..e1210fd --- /dev/null +++ b/AvocadoEdition/bbs/character_list.php @@ -0,0 +1,317 @@ +전체목록'; + +$g5['title'] = '캐릭터 관리'; +include_once('./admin.head.php'); + +$sql = " select * {$sql_common} {$sql_search} {$sql_order} limit {$from_record}, {$rows} "; +$result = sql_query($sql); + +$colspan = 8; + + +/** 세력 정보 **/ +$ch_si = array(); +if($config['cf_side_title']) { + $side_result = sql_query("select si_id, si_name from {$g5['side_table']} where si_auth <= '{$member['mb_level']}' order by si_id asc"); + for($i=0; $row = sql_fetch_array($side_result); $i++) { + $ch_si[$i]['name'] = $row['si_name']; + $ch_si[$i]['id'] = $row['si_id']; + } +} + +/** 종족 정보 **/ +$ch_cl = array(); +if($config['cf_class_title']) { + $class_result = sql_query("select cl_id, cl_name from {$g5['class_table']} where cl_auth <= '{$member['mb_level']}' order by cl_id asc"); + for($i=0; $row = sql_fetch_array($class_result); $i++) { + $ch_cl[$i]['name'] = $row['cl_name']; + $ch_cl[$i]['id'] = $row['cl_id']; + } + +} + +$profile = sql_fetch(" select ad_use_rank from {$g5['article_default_table']} "); +if($profile['ad_use_rank']) { + $colspan++; +} + + +?> + +
    + + 총캐릭터수 명 + + 승인대기 명 | + 수정중 명 | + 삭제 명 + +
    + +
    + + + 0) { +?> + + + 0) { +?> + + + + + + + +
    + + + + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 수정'; + $s_del = '제거'; + ?> + + + + + + + + + + + + + + + + + + + + + + + + "; + ?> + +
    목록
    + + + 유형이름랭킹상태관리
    + + + + + + + + + + + + + +   
    자료가 없습니다.
    +
    + +
    +

    선택삭제 - 상태를 삭제로 변경, 차후 문제 시 복구가 가능합니다. / 선택제거 - 캐리터 정보 삭제. 복구 불가능. 캐릭터와 관련된 아이템, 포인트 등의 정보 까지 모두 제거 됩니다.

    +
    + +
    + + + + +
    + +
    + + + + + + + + diff --git a/AvocadoEdition/bbs/confirm.php b/AvocadoEdition/bbs/confirm.php new file mode 100644 index 0000000..fcf94e0 --- /dev/null +++ b/AvocadoEdition/bbs/confirm.php @@ -0,0 +1,44 @@ + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/content.php b/AvocadoEdition/bbs/content.php new file mode 100644 index 0000000..cc9a78a --- /dev/null +++ b/AvocadoEdition/bbs/content.php @@ -0,0 +1,94 @@ +관리자 모드에서 게시판관리->내용 관리를 먼저 확인해 주세요.'); +} + + + +// 내용 +$sql = " select * from {$g5['content_table']} where co_id = '$co_id' "; +$co = sql_fetch($sql); +if (!$co['co_id']) + alert('등록된 내용이 없습니다.'); + +$g5['title'] = $co['co_subject']; + + +if (is_include_path_check($co['co_include_head'])) + @include_once($co['co_include_head']); +else + include_once('./_head.php'); + +if (G5_IS_MOBILE) { + $str = conv_content($co['co_mobile_content'], $co['co_html'], $co['co_tag_filter_use']); +} else { + $str = conv_content($co['co_content'], $co['co_html'], $co['co_tag_filter_use']); +} + +// $src 를 $dst 로 변환 +unset($src); +unset($dst); +$src[] = "/{{쇼핑몰명}}|{{홈페이지제목}}/"; +$dst[] = $config['cf_title']; +$src[] = "/{{회사명}}|{{상호}}/"; +$dst[] = $default['de_admin_company_name']; +$src[] = "/{{대표자명}}/"; +$dst[] = $default['de_admin_company_owner']; +$src[] = "/{{사업자등록번호}}/"; +$dst[] = $default['de_admin_company_saupja_no']; +$src[] = "/{{대표전화번호}}/"; +$dst[] = $default['de_admin_company_tel']; +$src[] = "/{{팩스번호}}/"; +$dst[] = $default['de_admin_company_fax']; +$src[] = "/{{통신판매업신고번호}}/"; +$dst[] = $default['de_admin_company_tongsin_no']; +$src[] = "/{{사업장우편번호}}/"; +$dst[] = $default['de_admin_company_zip']; +$src[] = "/{{사업장주소}}/"; +$dst[] = $default['de_admin_company_addr']; +$src[] = "/{{운영자명}}|{{관리자명}}/"; +$dst[] = $default['de_admin_name']; +$src[] = "/{{운영자e-mail}}|{{관리자e-mail}}/i"; +$dst[] = $default['de_admin_email']; +$src[] = "/{{정보관리책임자명}}/"; +$dst[] = $default['de_admin_info_name']; +$src[] = "/{{정보관리책임자e-mail}}|{{정보책임자e-mail}}/i"; +$dst[] = $default['de_admin_info_email']; + +$str = preg_replace($src, $dst, $str); + +// 스킨경로 +if(trim($co['co_skin']) == '') + $co['co_skin'] = 'basic'; + +$content_skin_path = get_skin_path('content', $co['co_skin']); +$content_skin_url = get_skin_url('content', $co['co_skin']); +$skin_file = $content_skin_path.'/content.skin.php'; + +if ($is_admin) + echo ''; +?> + +
    '; + + include($skin_file); + + $timg = G5_DATA_PATH.'/content/'.$co_id.'_t'; + if (file_exists($timg)) // 하단 이미지 + echo '
    '; +} else { + echo '

    '.str_replace(G5_PATH.'/', '', $skin_file).'이 존재하지 않습니다.

    '; +} + +if (is_include_path_check($co['co_include_tail'])) + @include_once($co['co_include_tail']); +else + include_once('./_tail.php'); +?> diff --git a/AvocadoEdition/bbs/current_connect.php b/AvocadoEdition/bbs/current_connect.php new file mode 100644 index 0000000..3532a00 --- /dev/null +++ b/AvocadoEdition/bbs/current_connect.php @@ -0,0 +1,38 @@ + '{$config['cf_admin']}' + order by a.lo_datetime desc "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) { + $row['lo_url'] = get_text($row['lo_url']); + $list[$i] = $row; + + if ($row['mb_id']) { + $list[$i]['name'] = get_sideview($row['mb_id'], cut_str($row['mb_nick'], $config['cf_cut_name']), $row['mb_email'], $row['mb_homepage']); + } else { + $ip_member = sql_fetch("select mb_name, mb_id from {$g5['member_table']} where mb_login_ip = '{$row['lo_ip']}' OR mb_ip = '{$row['lo_ip']}'"); + if($ip_member['mb_id']) { + $list[$i]['name'] = $ip_member['mb_name']; + } else { + if ($is_admin) + $list[$i]['name'] = $row['lo_ip']; + else + $list[$i]['name'] = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $row['lo_ip']); + } + } + + $list[$i]['num'] = sprintf('%03d',$i+1); +} + +include_once($connect_skin_path.'/current_connect.skin.php'); + +include_once('./_tail.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/db_table.optimize.php b/AvocadoEdition/bbs/db_table.optimize.php new file mode 100644 index 0000000..8289230 --- /dev/null +++ b/AvocadoEdition/bbs/db_table.optimize.php @@ -0,0 +1,69 @@ += G5_TIME_YMD) + return; + +// 설정일이 지난 접속자로그 삭제 +if($config['cf_visit_del'] > 0) { + $tmp_before_date = date("Y-m-d", G5_SERVER_TIME - ($config['cf_visit_del'] * 86400)); + $sql = " delete from {$g5['visit_table']} where vi_date < '$tmp_before_date' "; + sql_query($sql); + sql_query(" OPTIMIZE TABLE `{$g5['visit_table']}`, `{$g5['visit_sum_table']}` "); +} + +// 설정일이 지난 인기검색어 삭제 +if($config['cf_popular_del'] > 0) { + $tmp_before_date = date("Y-m-d", G5_SERVER_TIME - ($config['cf_popular_del'] * 86400)); + $sql = " delete from {$g5['popular_table']} where pp_date < '$tmp_before_date' "; + sql_query($sql); + sql_query(" OPTIMIZE TABLE `{$g5['popular_table']}` "); +} + +// 설정일이 지난 최근게시물 삭제 +if($config['cf_new_del'] > 0) { + $sql = " delete from {$g5['board_new_table']} where (TO_DAYS('".G5_TIME_YMDHIS."') - TO_DAYS(bn_datetime)) > '{$config['cf_new_del']}' "; + sql_query($sql); + sql_query(" OPTIMIZE TABLE `{$g5['board_new_table']}` "); +} + +// 설정일이 지난 쪽지 삭제 +if($config['cf_memo_del'] > 0) { + $sql = " delete from {$g5['memo_table']} where (TO_DAYS('".G5_TIME_YMDHIS."') - TO_DAYS(me_send_datetime)) > '{$config['cf_memo_del']}' "; + sql_query($sql); + sql_query(" OPTIMIZE TABLE `{$g5['memo_table']}` "); +} + +// 탈퇴회원 자동 삭제 +if($config['cf_leave_day'] > 0) { + $sql = " select mb_id from {$g5['member_table']} + where (TO_DAYS('".G5_TIME_YMDHIS."') - TO_DAYS(mb_leave_date)) > '{$config['cf_leave_day']}' + and mb_memo not regexp '^[0-9]{8}.*삭제함' "; + $result = sql_query($sql); + while ($row=sql_fetch_array($result)) + { + // 회원자료 삭제 + member_delete($row['mb_id']); + } +} + +// 음성 캡챠 파일 삭제 +$captcha_mp3 = glob(G5_PATH.'/data/cache/kcaptcha-*.mp3'); +if($captcha_mp3 && is_array($captcha_mp3)) { + foreach ($captcha_mp3 as $file) { + if (filemtime($file) + 86400 < G5_SERVER_TIME) { + @unlink($file); + } + } +} + +// 실행일 기록 +if(isset($config['cf_optimize_date'])) { + sql_query(" update {$g5['config_table']} set cf_optimize_date = '".G5_TIME_YMD."' "); +} +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/delete.php b/AvocadoEdition/bbs/delete.php new file mode 100644 index 0000000..1a288f0 --- /dev/null +++ b/AvocadoEdition/bbs/delete.php @@ -0,0 +1,139 @@ + '{$write['wr_id']}' + and wr_num = '{$write['wr_num']}' + and wr_is_comment = 0 "; +$row = sql_fetch($sql); +if ($row['cnt'] && !$is_admin) + alert('이 글과 관련된 답변글이 존재하므로 삭제 할 수 없습니다.\\n\\n우선 답변글부터 삭제하여 주십시오.'); + +// 코멘트 달린 원글의 삭제 여부 +$sql = " select count(*) as cnt from $write_table + where wr_parent = '$wr_id' + and mb_id <> '{$member['mb_id']}' + and wr_is_comment = 1 "; +$row = sql_fetch($sql); +$board['bo_count_delete'] = 1000; +if ($row['cnt'] >= $board['bo_count_delete'] && !$is_admin) + alert('이 글과 관련된 코멘트가 존재하므로 삭제 할 수 없습니다.\\n\\n코멘트가 '.$board['bo_count_delete'].'건 이상 달린 원글은 삭제할 수 없습니다.'); + + +// 사용자 코드 실행 +@include_once($board_skin_path.'/delete.skin.php'); + + +// 나라오름님 수정 : 원글과 코멘트수가 정상적으로 업데이트 되지 않는 오류를 잡아 주셨습니다. +//$sql = " select wr_id, mb_id, wr_comment from $write_table where wr_parent = '$write['wr_id']' order by wr_id "; +$sql = " select wr_id, mb_id, wr_is_comment, wr_content from $write_table where wr_parent = '{$write['wr_id']}' order by wr_id "; +$result = sql_query($sql); +while ($row = sql_fetch_array($result)) +{ + // 원글이라면 + if (!$row['wr_is_comment']) + { + // 원글 포인트 삭제 + if (!delete_point($row['mb_id'], $bo_table, $row['wr_id'], '쓰기')) + insert_point($row['mb_id'], $board['bo_write_point'] * (-1), "{$board['bo_subject']} {$row['wr_id']} 글삭제"); + + // 업로드된 파일이 있다면 파일삭제 + $sql2 = " select * from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' "; + $result2 = sql_query($sql2); + while ($row2 = sql_fetch_array($result2)) { + @unlink(G5_DATA_PATH.'/file/'.$bo_table.'/'.$row2['bf_file']); + // 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $row2['bf_file'])) { + delete_board_thumbnail($bo_table, $row2['bf_file']); + } + } + + // 에디터 썸네일 삭제 + delete_editor_thumbnail($row['wr_content']); + + // 파일테이블 행 삭제 + sql_query(" delete from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' "); + + $count_write++; + } + else + { + // 코멘트 포인트 삭제 + if (!delete_point($row['mb_id'], $bo_table, $row['wr_id'], '댓글')) + insert_point($row['mb_id'], $board['bo_comment_point'] * (-1), "{$board['bo_subject']} {$write['wr_id']}-{$row['wr_id']} 댓글삭제"); + + $count_comment++; + } +} + +// 게시글 삭제 +sql_query(" delete from $write_table where wr_parent = '{$write['wr_id']}' "); + +// 최근게시물 삭제 +sql_query(" delete from {$g5['board_new_table']} where bo_table = '$bo_table' and wr_parent = '{$write['wr_id']}' "); + +// 스크랩 삭제 +sql_query(" delete from {$g5['scrap_table']} where bo_table = '$bo_table' and wr_id = '{$write['wr_id']}' "); + +/* +// 공지사항 삭제 +$notice_array = explode("\n", trim($board['bo_notice'])); +$bo_notice = ""; +for ($k=0; $k 0 || $count_comment > 0) + sql_query(" update {$g5['board_table']} set bo_count_write = bo_count_write - '$count_write', bo_count_comment = bo_count_comment - '$count_comment' where bo_table = '$bo_table' "); + +@include_once($board_skin_path.'/delete.tail.skin.php'); + +delete_cache_latest($bo_table); + +goto_url('./board.php?bo_table='.$bo_table.'&page='.$page.$qstr); +?> diff --git a/AvocadoEdition/bbs/delete_all.php b/AvocadoEdition/bbs/delete_all.php new file mode 100644 index 0000000..178b260 --- /dev/null +++ b/AvocadoEdition/bbs/delete_all.php @@ -0,0 +1,160 @@ + (G5_IS_MOBILE ? $board['bo_mobile_page_rows'] : $board['bo_page_rows'])) + alert('올바른 방법으로 이용해 주십시오.'); + +// 사용자 코드 실행 +@include_once($board_skin_path.'/delete_all.skin.php'); + +// 거꾸로 읽는 이유는 답변글부터 삭제가 되어야 하기 때문임 +for ($i=$chk_count-1; $i>=0; $i--) +{ + $write = sql_fetch(" select * from $write_table where wr_id = '$tmp_array[$i]' "); + + if ($is_admin == 'super') // 최고관리자 통과 + ; + else if ($is_admin == 'group') // 그룹관리자 + { + $mb = get_member($write['mb_id']); + if ($member['mb_id'] == $group['gr_admin']) // 자신이 관리하는 그룹인가? + { + if ($member['mb_level'] >= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + continue; + } + else + continue; + } + else if ($is_admin == 'board') // 게시판관리자이면 + { + $mb = get_member($write['mb_id']); + if ($member['mb_id'] == $board['bo_admin']) // 자신이 관리하는 게시판인가? + if ($member['mb_level'] >= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + continue; + else + continue; + } + else if ($member['mb_id'] && $member['mb_id'] == $write['mb_id']) // 자신의 글이라면 + { + ; + } + else if ($wr_password && !$write['mb_id'] && check_password($wr_password, $write['wr_password'])) // 비밀번호가 같다면 + { + ; + } + else + continue; // 나머지는 삭제 불가 + + $len = strlen($write['wr_reply']); + if ($len < 0) $len = 0; + $reply = substr($write['wr_reply'], 0, $len); + + // 원글만 구한다. + $sql = " select count(*) as cnt from $write_table + where wr_reply like '$reply%' + and wr_id <> '{$write['wr_id']}' + and wr_num = '{$write['wr_num']}' + and wr_is_comment = 0 "; + $row = sql_fetch($sql); + if ($row['cnt']) + continue; + + // 나라오름님 수정 : 원글과 코멘트수가 정상적으로 업데이트 되지 않는 오류를 잡아 주셨습니다. + //$sql = " select wr_id, mb_id, wr_comment from {$write_table} where wr_parent = '{$write['wr_id']}' order by wr_id "; + $sql = " select wr_id, mb_id, wr_is_comment, wr_content from $write_table where wr_parent = '{$write['wr_id']}' order by wr_id "; + $result = sql_query($sql); + while ($row = sql_fetch_array($result)) + { + // 원글이라면 + if (!$row['wr_is_comment']) + { + // 원글 포인트 삭제 + if (!delete_point($row['mb_id'], $bo_table, $row['wr_id'], '쓰기')) + insert_point($row['mb_id'], $board['bo_write_point'] * (-1), "{$board['bo_subject']} {$row['wr_id']} 글 삭제"); + + // 업로드된 파일이 있다면 + $sql2 = " select * from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' "; + $result2 = sql_query($sql2); + while ($row2 = sql_fetch_array($result2)) { + // 파일삭제 + @unlink(G5_DATA_PATH.'/file/'.$bo_table.'/'.$row2['bf_file']); + + // 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $row2['bf_file'])) { + delete_board_thumbnail($bo_table, $row2['bf_file']); + } + } + + // 에디터 썸네일 삭제 + delete_editor_thumbnail($row['wr_content']); + + // 파일테이블 행 삭제 + sql_query(" delete from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row['wr_id']}' "); + + $count_write++; + } + else + { + // 코멘트 포인트 삭제 + if (!delete_point($row['mb_id'], $bo_table, $row['wr_id'], '댓글')) + insert_point($row['mb_id'], $board['bo_comment_point'] * (-1), "{$board['bo_subject']} {$write['wr_id']}-{$row['wr_id']} 댓글삭제"); + + $count_comment++; + } + } + + // 게시글 삭제 + sql_query(" delete from $write_table where wr_parent = '{$write['wr_id']}' "); + + // 최근게시물 삭제 + sql_query(" delete from {$g5['board_new_table']} where bo_table = '$bo_table' and wr_parent = '{$write['wr_id']}' "); + + // 스크랩 삭제 + sql_query(" delete from {$g5['scrap_table']} where bo_table = '$bo_table' and wr_id = '{$write['wr_id']}' "); + + /* + // 공지사항 삭제 + $notice_array = explode(',', trim($board['bo_notice'])); + $bo_notice = ""; + for ($k=0; $k 0 || $count_comment > 0) + sql_query(" update {$g5['board_table']} set bo_count_write = bo_count_write - '$count_write', bo_count_comment = bo_count_comment - '$count_comment' where bo_table = '$bo_table' "); + +// 4.11 +@include_once($board_skin_path.'/delete_all.tail.skin.php'); + +delete_cache_latest($bo_table); + +goto_url('./board.php?bo_table='.$bo_table.'&page='.$page.$qstr); +?> diff --git a/AvocadoEdition/bbs/delete_comment.php b/AvocadoEdition/bbs/delete_comment.php new file mode 100644 index 0000000..ac656e3 --- /dev/null +++ b/AvocadoEdition/bbs/delete_comment.php @@ -0,0 +1,88 @@ += $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert('그룹관리자의 권한보다 높은 회원의 코멘트이므로 삭제할 수 없습니다.'); + } else + alert('자신이 관리하는 그룹의 게시판이 아니므로 코멘트를 삭제할 수 없습니다.'); +} else if ($is_admin == 'board') { // 게시판관리자이면 + $mb = get_member($write['mb_id']); + if ($member['mb_id'] == $board['bo_admin']) { // 자신이 관리하는 게시판인가? + if ($member['mb_level'] >= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert('게시판관리자의 권한보다 높은 회원의 코멘트이므로 삭제할 수 없습니다.'); + } else + alert('자신이 관리하는 게시판이 아니므로 코멘트를 삭제할 수 없습니다.'); +} else if ($member['mb_id']) { + if ($member['mb_id'] != $write['mb_id']) + alert('자신의 글이 아니므로 삭제할 수 없습니다.'); +} else { + if (!check_password($wr_password, $write['wr_password'])) + alert('비밀번호가 틀립니다.'); +} + +$len = strlen($write['wr_comment_reply']); +if ($len < 0) $len = 0; +$comment_reply = substr($write['wr_comment_reply'], 0, $len); + +$sql = " select count(*) as cnt from {$write_table} + where wr_comment_reply like '{$comment_reply}%' + and wr_id <> '{$comment_id}' + and wr_parent = '{$write['wr_parent']}' + and wr_comment = '{$write['wr_comment']}' + and wr_is_comment = 1 "; +$row = sql_fetch($sql); +if ($row['cnt'] && !$is_admin) + alert('이 코멘트와 관련된 답변코멘트가 존재하므로 삭제 할 수 없습니다.'); + +// 코멘트 포인트 삭제 +if (!delete_point($write['mb_id'], $bo_table, $comment_id, '댓글')) + insert_point($write['mb_id'], $board['bo_comment_point'] * (-1), "{$board['bo_subject']} {$write['wr_parent']}-{$comment_id} 댓글삭제"); + +// 코멘트 삭제 +sql_query(" delete from {$write_table} where wr_id = '{$comment_id}' "); + +// 코멘트가 삭제되므로 해당 게시물에 대한 최근 시간을 다시 얻는다. +$sql = " select max(wr_datetime) as wr_last from {$write_table} where wr_parent = '{$write['wr_parent']}' "; +$row = sql_fetch($sql); + +// 원글의 코멘트 숫자를 감소 +sql_query(" update {$write_table} set wr_comment = wr_comment - 1, wr_last = '{$row['wr_last']}' where wr_id = '{$write['wr_parent']}' "); + +// 코멘트 숫자 감소 +sql_query(" update {$g5['board_table']} set bo_count_comment = bo_count_comment - 1 where bo_table = '{$bo_table}' "); + +// 새글 삭제 +sql_query(" delete from {$g5['board_new_table']} where bo_table = '{$bo_table}' and wr_id = '{$comment_id}' "); + +// 사용자 코드 실행 +@include_once($board_skin_path.'/delete_comment.skin.php'); +@include_once($board_skin_path.'/delete_comment.tail.skin.php'); + +delete_cache_latest($bo_table); + +goto_url('./board.php?bo_table='.$bo_table.'&wr_id='.$write['wr_parent'].'&page='.$page. $qstr); +?> diff --git a/AvocadoEdition/bbs/download.php b/AvocadoEdition/bbs/download.php new file mode 100644 index 0000000..977f176 --- /dev/null +++ b/AvocadoEdition/bbs/download.php @@ -0,0 +1,122 @@ += 1) // 회원이상 다운로드가 가능하다면 + { + // 다운로드 포인트가 음수이고 회원의 포인트가 0 이거나 작다면 + if ($member['mb_point'] + $board['bo_download_point'] < 0) + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 다운로드('.number_format($board['bo_download_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 다운로드 해 주십시오.'); + + // 게시물당 한번만 차감하도록 수정 + insert_point($member['mb_id'], $board['bo_download_point'], "{$board['bo_subject']} $wr_id 파일 다운로드", $bo_table, $wr_id, "다운로드"); + } + + // 다운로드 카운트 증가 + $sql = " update {$g5['board_file_table']} set bf_download = bf_download + 1 where bo_table = '$bo_table' and wr_id = '$wr_id' and bf_no = '$no' "; + sql_query($sql); + + set_session($ss_name, TRUE); +} + +$g5['title'] = '다운로드 > '.conv_subject($write['wr_subject'], 255); + +//$original = urlencode($file['bf_source']); +$original = iconv('utf-8', 'euc-kr', $file['bf_source']); // SIR 잉끼님 제안코드 + +@include_once($board_skin_path.'/download.tail.skin.php'); + +if(preg_match("/msie/i", $_SERVER['HTTP_USER_AGENT']) && preg_match("/5\.5/", $_SERVER['HTTP_USER_AGENT'])) { + header("content-type: doesn/matter"); + header("content-length: ".filesize("$filepath")); + header("content-disposition: attachment; filename=\"$original\""); + header("content-transfer-encoding: binary"); +} else { + header("content-type: file/unknown"); + header("content-length: ".filesize("$filepath")); + header("content-disposition: attachment; filename=\"$original\""); + header("content-description: php generated data"); +} +header("pragma: no-cache"); +header("expires: 0"); +flush(); + +$fp = fopen($filepath, 'rb'); + +// 4.00 대체 +// 서버부하를 줄이려면 print 나 echo 또는 while 문을 이용한 방법보다는 이방법이... +//if (!fpassthru($fp)) { +// fclose($fp); +//} + +$download_rate = 10; + +while(!feof($fp)) { + //echo fread($fp, 100*1024); + /* + echo fread($fp, 100*1024); + flush(); + */ + + print fread($fp, round($download_rate * 1024)); + flush(); + usleep(1000); +} +fclose ($fp); +flush(); +?> diff --git a/AvocadoEdition/bbs/email_certify.php b/AvocadoEdition/bbs/email_certify.php new file mode 100644 index 0000000..80b4bf0 --- /dev/null +++ b/AvocadoEdition/bbs/email_certify.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/email_stop.php b/AvocadoEdition/bbs/email_stop.php new file mode 100644 index 0000000..3635bb3 --- /dev/null +++ b/AvocadoEdition/bbs/email_stop.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/faq.php b/AvocadoEdition/bbs/faq.php new file mode 100644 index 0000000..86a31e2 --- /dev/null +++ b/AvocadoEdition/bbs/faq.php @@ -0,0 +1,98 @@ +관리자 모드에서 게시판관리->FAQ관리를 먼저 확인해 주세요.'); +} + +// FAQ MASTER +$faq_master_list = array(); +$sql = " select * from {$g5['faq_master_table']} order by fm_order,fm_id "; +$result = sql_query($sql); +while ($row=sql_fetch_array($result)) +{ + $key = $row['fm_id']; + if (!$fm_id) $fm_id = $key; + $faq_master_list[$key] = $row; +} + +if ($fm_id){ + $qstr .= '&fm_id=' . $fm_id; // 마스터faq key_id +} + +$fm = $faq_master_list[$fm_id]; +if (!$fm['fm_id']) + alert('등록된 내용이 없습니다.'); + +$g5['title'] = $fm['fm_subject']; + +$skin_file = $faq_skin_path.'/list.skin.php'; + +include_once('./_head.php'); + +if(is_file($skin_file)) { + $admin_href = ''; + $himg_src = ''; + $timg_src = ''; + if($is_admin) + $admin_href = G5_ADMIN_URL.'/faqmasterform.php?w=u&fm_id='.$fm_id; + + if(!G5_IS_MOBILE) { + $himg = G5_DATA_PATH.'/faq/'.$fm_id.'_h'; + if (is_file($himg)){ + $himg_src = G5_DATA_URL.'/faq/'.$fm_id.'_h'; + } + + $timg = G5_DATA_PATH.'/faq/'.$fm_id.'_t'; + if (is_file($timg)){ + $timg_src = G5_DATA_URL.'/faq/'.$fm_id.'_t'; + } + } + + $category_href = G5_BBS_URL.'/faq.php'; + $category_stx = ''; + $faq_list = array(); + + $stx = trim($stx); + $sql_search = ''; + + if($stx) { + $sql_search = " and ( INSTR(fa_subject, '$stx') > 0 or INSTR(fa_content, '$stx') > 0 ) "; + } + + if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) + + $page_rows = G5_IS_MOBILE ? $config['cf_mobile_page_rows'] : $config['cf_page_rows']; + + $sql = " select count(*) as cnt + from {$g5['faq_table']} + where fm_id = '$fm_id' + $sql_search "; + $total = sql_fetch($sql); + $total_count = $total['cnt']; + + $total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 + $from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + + $sql = " select * + from {$g5['faq_table']} + where fm_id = '$fm_id' + $sql_search + order by fa_order , fa_id + limit $from_record, $page_rows "; + $result = sql_query($sql); + for ($i=0;$row=sql_fetch_array($result);$i++){ + $faq_list[] = $row; + if($stx) { + $faq_list[$i]['fa_subject'] = search_font($stx, conv_content($faq_list[$i]['fa_subject'], 1)); + $faq_list[$i]['fa_content'] = search_font($stx, conv_content($faq_list[$i]['fa_content'], 1)); + } + } + include_once($skin_file); +} else { + echo '

    '.str_replace(G5_PATH.'/', '', $skin_file).'이 존재하지 않습니다.

    '; +} + +include_once('./_tail.php'); +?> diff --git a/AvocadoEdition/bbs/formmail.php b/AvocadoEdition/bbs/formmail.php new file mode 100644 index 0000000..fe099d2 --- /dev/null +++ b/AvocadoEdition/bbs/formmail.php @@ -0,0 +1,54 @@ + 3) + alert_close('한번 접속후 일정수의 메일만 발송할 수 있습니다.\\n\\n계속해서 메일을 보내시려면 다시 로그인 또는 접속하여 주십시오.'); + +$g5['title'] = '메일 쓰기'; +include_once(G5_PATH.'/head.sub.php'); + +$email_enc = new str_encrypt(); +$email_dec = $email_enc->decrypt($email); + +$email = get_email_address($email_dec); +if(!$email) + alert_close('이메일이 올바르지 않습니다.'); + +$email = $email_enc->encrypt($email); + +if (!$name) + $name = $email; +else + $name = get_text(stripslashes($name), true); + +if (!isset($type)) + $type = 0; + +$type_checked[0] = $type_checked[1] = $type_checked[2] = ""; +$type_checked[$type] = 'checked'; + +include_once($member_skin_path.'/formmail.skin.php'); + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/formmail_send.php b/AvocadoEdition/bbs/formmail_send.php new file mode 100644 index 0000000..0902094 --- /dev/null +++ b/AvocadoEdition/bbs/formmail_send.php @@ -0,0 +1,60 @@ +decrypt($to); + +if (substr_count($to, "@") > 1) + alert_close('한번에 한사람에게만 메일을 발송할 수 있습니다.'); + + +if (!chk_captcha()) { + alert('자동등록방지 숫자가 틀렸습니다.'); +} + + +$file = array(); +for ($i=1; $i<=$attach; $i++) { + if ($_FILES['file'.$i]['name']) + $file[] = attach_file($_FILES['file'.$i]['name'], $_FILES['file'.$i]['tmp_name']); +} + +$content = stripslashes($content); +if ($type == 2) { + $type = 1; + $content = str_replace("\n", "
    ", $content); +} + +// html 이면 +if ($type) { + $current_url = G5_URL; + $mail_content = '메일보내기'.$content.''; +} +else + $mail_content = $content; + +mailer($fnick, $fmail, $to, $subject, $mail_content, $type, $file); + +// 임시 첨부파일 삭제 +if(!empty($file)) { + foreach($file as $f) { + @unlink($f['path']); + } +} + +//$html_title = $tmp_to . "님께 메일발송"; +$html_title = '메일 발송중'; +include_once(G5_PATH.'/head.sub.php'); + +alert_close('메일을 정상적으로 발송하였습니다.'); + +include_once(G5_PATH.'/tail.sub.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/good.php b/AvocadoEdition/bbs/good.php new file mode 100644 index 0000000..d1714c9 --- /dev/null +++ b/AvocadoEdition/bbs/good.php @@ -0,0 +1,155 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/group.php b/AvocadoEdition/bbs/group.php new file mode 100644 index 0000000..34ef08d --- /dev/null +++ b/AvocadoEdition/bbs/group.php @@ -0,0 +1,58 @@ + + + + + 'mobile' "; +if(!$is_admin) + $sql .= " and bo_use_cert = '' "; +$sql .= " order by bo_order "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) { + $lt_style = ""; + if ($i%2==1) $lt_style = "margin-left:20px"; + else $lt_style = ""; +?> +
    + +
    + + + + diff --git a/AvocadoEdition/bbs/index.php b/AvocadoEdition/bbs/index.php new file mode 100644 index 0000000..d214256 --- /dev/null +++ b/AvocadoEdition/bbs/index.php @@ -0,0 +1,39 @@ + diff --git a/AvocadoEdition/bbs/link.php b/AvocadoEdition/bbs/link.php new file mode 100644 index 0000000..e74536c --- /dev/null +++ b/AvocadoEdition/bbs/link.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/list.mmb.php b/AvocadoEdition/bbs/list.mmb.php new file mode 100644 index 0000000..90ff438 --- /dev/null +++ b/AvocadoEdition/bbs/list.mmb.php @@ -0,0 +1,249 @@ +'; + } +} + +$sop = strtolower($sop); +if ($sop != 'and' && $sop != 'or') + $sop = 'and'; + +// 분류 선택 또는 검색어가 있다면 +$stx = trim($stx); +if ($sca || $stx || $hash || $log) { + // 검색구문 호출 기능 커스텀한 것으로 재호출 + $sql_search = get_sql_search_mmb($sca, $sfl, $stx, $hash, $sop, $log, $single); + + // 가장 작은 번호를 얻어서 변수에 저장 (하단의 페이징에서 사용) + $sql = " select MIN(wr_num) as min_wr_num from {$write_table} "; + $row = sql_fetch($sql); + $min_spt = (int)$row['min_wr_num']; + + if (!$spt) $spt = $min_spt; + + $sql_search .= " and (wr_num between {$spt} and ({$spt} + {$config['cf_search_part']})) "; + + // 원글만 얻는다. (코멘트의 내용도 검색하기 위함) + // 라엘님 제안 코드로 대체 http://sir.co.kr/bbs/board.php?bo_table=g5_bug&wr_id=2922 + $sql = " SELECT COUNT(DISTINCT `wr_parent`) AS `cnt` FROM {$write_table} WHERE {$sql_search} "; + $row = sql_fetch($sql); + $total_count = $row['cnt']; + /* + $sql = " select distinct wr_parent from {$write_table} where {$sql_search} "; + $result = sql_query($sql); + $total_count = mysql_num_rows($result); + */ +} else { + $sql_search = ""; + $total_count = $board['bo_count_write']; +} + +if(G5_IS_MOBILE) { + $page_rows = 5; + $list_page_rows = 5; +} else { + $page_rows = $board['bo_page_rows']; + $list_page_rows = $board['bo_page_rows']; +} + +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) + +// 년도 2자리 +$today2 = G5_TIME_YMD; + +$list = array(); +$i = 0; +$notice_count = 0; +$notice_array = array(); + +// 공지 처리 +if (!$sca && !$stx && !$hash && !$log) { + $arr_notice = explode(',', trim($board['bo_notice'])); + $from_notice_idx = ($page - 1) * $page_rows; + if($from_notice_idx < 0) + $from_notice_idx = 0; + $board_notice_count = count($arr_notice); + + for ($k=0; $k<$board_notice_count; $k++) { + if (trim($arr_notice[$k]) == '') continue; + + $row = sql_fetch(" select * from {$write_table} where wr_id = '{$arr_notice[$k]}' "); + + if (!$row['wr_id']) continue; + + $notice_array[] = $row['wr_id']; + + if($k < $from_notice_idx) continue; + + $list[$i] = get_list($row, $board, $board_skin_url, G5_IS_MOBILE ? $board['bo_mobile_subject_len'] : $board['bo_subject_len']); + $list[$i]['is_notice'] = true; + + $i++; + $notice_count++; + + if($notice_count >= $list_page_rows) + break; + } +} + +$total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 +$from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + +// 공지글이 있으면 변수에 반영 +if(!empty($notice_array)) { + $from_record -= count($notice_array); + + if($from_record < 0) + $from_record = 0; + + if($notice_count > 0) + $page_rows -= $notice_count; + + if($page_rows < 0) + $page_rows = $list_page_rows; +} + +// 관리자라면 CheckBox 보임 +$is_checkbox = false; +if ($is_member && ($is_admin == 'super' || $group['gr_admin'] == $member['mb_id'] || $board['bo_admin'] == $member['mb_id'])) + $is_checkbox = true; + +// 정렬에 사용하는 QUERY_STRING +$qstr2 = 'bo_table='.$bo_table.'&sop='.$sop; + +// 0 으로 나눌시 오류를 방지하기 위하여 값이 없으면 1 로 설정 +$bo_gallery_cols = $board['bo_gallery_cols'] ? $board['bo_gallery_cols'] : 1; +$td_width = (int)(100 / $bo_gallery_cols); + +// 정렬 +// 인덱스 필드가 아니면 정렬에 사용하지 않음 +//if (!$sst || ($sst && !(strstr($sst, 'wr_id') || strstr($sst, "wr_datetime")))) { +if (!$sst) { + if ($board['bo_sort_field']) { + $sst = $board['bo_sort_field']; + } else { + $sst = "wr_num, wr_reply"; + $sod = ""; + } +} else { + // 게시물 리스트의 정렬 대상 필드가 아니라면 공백으로 (nasca 님 09.06.16) + // 리스트에서 다른 필드로 정렬을 하려면 아래의 코드에 해당 필드를 추가하세요. + // $sst = preg_match("/^(wr_subject|wr_datetime|wr_hit|wr_good|wr_nogood)$/i", $sst) ? $sst : ""; + $sst = preg_match("/^(wr_datetime|wr_hit|wr_good|wr_nogood)$/i", $sst) ? $sst : ""; +} + +if(!$sst) + $sst = "wr_num, wr_reply"; + +if ($sst) { + $sql_order = " order by {$sst} {$sod} "; +} + +if ($sca || $stx || $hash || $log) { + $sql = " select distinct wr_parent from {$write_table} where {$sql_search} {$sql_order} limit {$from_record}, $page_rows "; +} else { + $sql = " select * from {$write_table} where wr_is_comment = 0 "; + if(!empty($notice_array)) + $sql .= " and wr_id not in (".implode(', ', $notice_array).") "; + $sql .= " {$sql_order} limit {$from_record}, $page_rows "; +} + +// 페이지의 공지개수가 목록수 보다 작을 때만 실행 +if($page_rows > 0) { + $result = sql_query($sql); + + $k = 0; + + while ($row = sql_fetch_array($result)) + { + // 검색일 경우 wr_id만 얻었으므로 다시 한행을 얻는다 + if ($sca || $stx || $hash || $log) + $row = sql_fetch(" select * from {$write_table} where wr_id = '{$row['wr_parent']}' "); + + $list[$i] = get_list($row, $board, $board_skin_url, G5_IS_MOBILE ? $board['bo_mobile_subject_len'] : $board['bo_subject_len']); + if (strstr($sfl, 'subject')) { + $list[$i]['subject'] = search_font($stx, $list[$i]['subject']); + } + $list[$i]['is_notice'] = false; + $list_num = $total_count - ($page - 1) * $list_page_rows - $notice_count; + $list[$i]['num'] = $list_num - $k; + + $i++; + $k++; + } +} + +$hash_pattern = "/\\#([0-9a-zA-Z가-힣_]*)/"; +$real_str = preg_replace($hash_pattern, '%23$1', $_REQUEST['hash']); + +$qstr .="&hash=".$real_str."&log=".$_REQUEST['log']."&single=".$single; + +$write_pages = get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, './board.php?bo_table='.$bo_table.$qstr.'&page='); + +$list_href = ''; +$prev_part_href = ''; +$next_part_href = ''; +if ($sca || $stx || $hash || $log) { + $list_href = './board.php?bo_table='.$bo_table; + + $patterns = array('#&page=[0-9]*#', '#&spt=[0-9\-]*#'); + + //if ($prev_spt >= $min_spt) + $prev_spt = $spt - $config['cf_search_part']; + if (isset($min_spt) && $prev_spt >= $min_spt) { + $qstr1 = preg_replace($patterns, '', $qstr); + $prev_part_href = './board.php?bo_table='.$bo_table.$qstr1.'&spt='.$prev_spt.'&page=1'; + $write_pages = page_insertbefore($write_pages, '이전검색'); + } + + $next_spt = $spt + $config['cf_search_part']; + if ($next_spt < 0) { + $qstr1 = preg_replace($patterns, '', $qstr); + $next_part_href = './board.php?bo_table='.$bo_table.$qstr1.'&spt='.$next_spt.'&page=1'; + $write_pages = page_insertafter($write_pages, '다음검색'); + } +} + + +$write_href = ''; +if ($member['mb_level'] >= $board['bo_write_level']) { + $write_href = './write.php?bo_table='.$bo_table; +} + +$nobr_begin = $nobr_end = ""; +if (preg_match("/gecko|firefox/i", $_SERVER['HTTP_USER_AGENT'])) { + $nobr_begin = ''; + $nobr_end = ''; +} + +// RSS 보기 사용에 체크가 되어 있어야 RSS 보기 가능 061106 +$rss_href = ''; +if ($board['bo_use_rss_view']) { + $rss_href = './rss.php?bo_table='.$bo_table; +} + +$stx = get_text(stripslashes($stx)); +include_once($board_skin_path.'/list.skin.php'); + +?> diff --git a/AvocadoEdition/bbs/list.php b/AvocadoEdition/bbs/list.php new file mode 100644 index 0000000..47ec5a3 --- /dev/null +++ b/AvocadoEdition/bbs/list.php @@ -0,0 +1,245 @@ +'; + } +} + +$sop = strtolower($sop); +if ($sop != 'and' && $sop != 'or') + $sop = 'and'; + +// 분류 선택 또는 검색어가 있다면 +$stx = trim($stx); +if ($sca || $stx) { + $sql_search = get_sql_search($sca, $sfl, $stx, $sop); + + // 가장 작은 번호를 얻어서 변수에 저장 (하단의 페이징에서 사용) + $sql = " select MIN(wr_num) as min_wr_num from {$write_table} "; + $row = sql_fetch($sql); + $min_spt = (int)$row['min_wr_num']; + + if (!$spt) $spt = $min_spt; + + $sql_search .= " and (wr_num between {$spt} and ({$spt} + {$config['cf_search_part']})) "; + + // 원글만 얻는다. (코멘트의 내용도 검색하기 위함) + // 라엘님 제안 코드로 대체 http://sir.kr/g5_bug/2922 + $sql = " SELECT COUNT(DISTINCT `wr_parent`) AS `cnt` FROM {$write_table} WHERE {$sql_search} "; + $row = sql_fetch($sql); + $total_count = $row['cnt']; + /* + $sql = " select distinct wr_parent from {$write_table} where {$sql_search} "; + $result = sql_query($sql); + $total_count = sql_num_rows($result); + */ +} else { + $sql_search = ""; + + $total_count = $board['bo_count_write']; +} + +if(G5_IS_MOBILE) { + $page_rows = 5; + $list_page_rows = 5; +} else { + $page_rows = $board['bo_page_rows']; + $list_page_rows = $board['bo_page_rows']; +} + +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) + +// 년도 2자리 +$today2 = G5_TIME_YMD; + +$list = array(); +$i = 0; +$notice_count = 0; +$notice_array = array(); + +// 공지 처리 +if (!$sca && !$stx) { + $arr_notice = explode(',', trim($board['bo_notice'])); + $from_notice_idx = ($page - 1) * $page_rows; + if($from_notice_idx < 0) + $from_notice_idx = 0; + $board_notice_count = count($arr_notice); + + for ($k=0; $k<$board_notice_count; $k++) { + if (trim($arr_notice[$k]) == '') continue; + + $row = sql_fetch(" select * from {$write_table} where wr_id = '{$arr_notice[$k]}' "); + + if (!$row['wr_id']) continue; + + $notice_array[] = $row['wr_id']; + + if($k < $from_notice_idx) continue; + + $list[$i] = get_list($row, $board, $board_skin_url, G5_IS_MOBILE ? $board['bo_mobile_subject_len'] : $board['bo_subject_len']); + $list[$i]['is_notice'] = true; + + $i++; + $notice_count++; + + if($notice_count >= $list_page_rows) + break; + } +} + +$total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 +$from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + +// 공지글이 있으면 변수에 반영 +if(!empty($notice_array)) { + $from_record -= count($notice_array); + + if($from_record < 0) + $from_record = 0; + + if($notice_count > 0) + $page_rows -= $notice_count; + + if($page_rows < 0) + $page_rows = $list_page_rows; +} + +// 관리자라면 CheckBox 보임 +$is_checkbox = false; +if ($is_member && ($is_admin == 'super' || $group['gr_admin'] == $member['mb_id'] || $board['bo_admin'] == $member['mb_id'])) + $is_checkbox = true; + +// 정렬에 사용하는 QUERY_STRING +$qstr2 = 'bo_table='.$bo_table.'&sop='.$sop; + +// 0 으로 나눌시 오류를 방지하기 위하여 값이 없으면 1 로 설정 +$bo_gallery_cols = $board['bo_gallery_cols'] ? $board['bo_gallery_cols'] : 1; +$td_width = (int)(100 / $bo_gallery_cols); + +// 정렬 +// 인덱스 필드가 아니면 정렬에 사용하지 않음 +//if (!$sst || ($sst && !(strstr($sst, 'wr_id') || strstr($sst, "wr_datetime")))) { +if (!$sst) { + if ($board['bo_sort_field']) { + $sst = $board['bo_sort_field']; + } else { + $sst = "wr_num, wr_reply"; + $sod = ""; + } +} else { + // 게시물 리스트의 정렬 대상 필드가 아니라면 공백으로 (nasca 님 09.06.16) + // 리스트에서 다른 필드로 정렬을 하려면 아래의 코드에 해당 필드를 추가하세요. + // $sst = preg_match("/^(wr_subject|wr_datetime|wr_hit|wr_good|wr_nogood)$/i", $sst) ? $sst : ""; + $sst = preg_match("/^(wr_datetime|wr_hit|wr_good|wr_nogood)$/i", $sst) ? $sst : ""; +} + +if(!$sst) + $sst = "wr_num, wr_reply"; + +if ($sst) { + $sql_order = " order by {$sst} {$sod} "; +} + +if ($sca || $stx) { + $sql = " select distinct wr_parent from {$write_table} where {$sql_search} {$sql_order} limit {$from_record}, $page_rows "; +} else { + $sql = " select * from {$write_table} where wr_is_comment = 0 "; + if(!empty($notice_array)) + $sql .= " and wr_id not in (".implode(', ', $notice_array).") "; + $sql .= " {$sql_order} limit {$from_record}, $page_rows "; +} + +// 페이지의 공지개수가 목록수 보다 작을 때만 실행 +if($page_rows > 0) { + $result = sql_query($sql); + + $k = 0; + + while ($row = sql_fetch_array($result)) + { + // 검색일 경우 wr_id만 얻었으므로 다시 한행을 얻는다 + if ($sca || $stx) + $row = sql_fetch(" select * from {$write_table} where wr_id = '{$row['wr_parent']}' "); + + $list[$i] = get_list($row, $board, $board_skin_url, G5_IS_MOBILE ? $board['bo_mobile_subject_len'] : $board['bo_subject_len']); + if (strstr($sfl, 'subject')) { + $list[$i]['subject'] = search_font($stx, $list[$i]['subject']); + } + $list[$i]['is_notice'] = false; + $list_num = $total_count - ($page - 1) * $list_page_rows - $notice_count; + $list[$i]['num'] = $list_num - $k; + + $i++; + $k++; + } +} + +$write_pages = get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, './board.php?bo_table='.$bo_table.$qstr.'&page='); + +$list_href = ''; +$prev_part_href = ''; +$next_part_href = ''; +if ($sca || $stx) { + $list_href = './board.php?bo_table='.$bo_table; + + $patterns = array('#&page=[0-9]*#', '#&spt=[0-9\-]*#'); + + //if ($prev_spt >= $min_spt) + $prev_spt = $spt - $config['cf_search_part']; + if (isset($min_spt) && $prev_spt >= $min_spt) { + $qstr1 = preg_replace($patterns, '', $qstr); + $prev_part_href = './board.php?bo_table='.$bo_table.$qstr1.'&spt='.$prev_spt.'&page=1'; + $write_pages = page_insertbefore($write_pages, '이전검색'); + } + + $next_spt = $spt + $config['cf_search_part']; + if ($next_spt < 0) { + $qstr1 = preg_replace($patterns, '', $qstr); + $next_part_href = './board.php?bo_table='.$bo_table.$qstr1.'&spt='.$next_spt.'&page=1'; + $write_pages = page_insertafter($write_pages, '다음검색'); + } +} + + +$write_href = ''; +if ($member['mb_level'] >= $board['bo_write_level']) { + $write_href = './write.php?bo_table='.$bo_table; +} + +$nobr_begin = $nobr_end = ""; +if (preg_match("/gecko|firefox/i", $_SERVER['HTTP_USER_AGENT'])) { + $nobr_begin = ''; + $nobr_end = ''; +} + +// RSS 보기 사용에 체크가 되어 있어야 RSS 보기 가능 061106 +$rss_href = ''; +if ($board['bo_use_rss_view']) { + $rss_href = './rss.php?bo_table='.$bo_table; +} + +$stx = get_text(stripslashes($stx)); +include_once($board_skin_path.'/list.skin.php'); +?> diff --git a/AvocadoEdition/bbs/login.php b/AvocadoEdition/bbs/login.php new file mode 100644 index 0000000..a9e3432 --- /dev/null +++ b/AvocadoEdition/bbs/login.php @@ -0,0 +1,31 @@ + diff --git a/AvocadoEdition/bbs/login_check.php b/AvocadoEdition/bbs/login_check.php new file mode 100644 index 0000000..319cd39 --- /dev/null +++ b/AvocadoEdition/bbs/login_check.php @@ -0,0 +1,98 @@ +$value) { + if ($key != 'mb_id' && $key != 'mb_password' && $key != 'x' && $key != 'y' && $key != 'url') { + $link .= "$split$key=$value"; + $split = "&"; + } + } +} else { + $link = G5_URL; +} + +goto_url($link); +?> diff --git a/AvocadoEdition/bbs/logout.php b/AvocadoEdition/bbs/logout.php new file mode 100644 index 0000000..3bcb99c --- /dev/null +++ b/AvocadoEdition/bbs/logout.php @@ -0,0 +1,27 @@ + diff --git a/AvocadoEdition/bbs/member_confirm.php b/AvocadoEdition/bbs/member_confirm.php new file mode 100644 index 0000000..e5abe16 --- /dev/null +++ b/AvocadoEdition/bbs/member_confirm.php @@ -0,0 +1,27 @@ + diff --git a/AvocadoEdition/bbs/member_leave.php b/AvocadoEdition/bbs/member_leave.php new file mode 100644 index 0000000..c58910b --- /dev/null +++ b/AvocadoEdition/bbs/member_leave.php @@ -0,0 +1,25 @@ + diff --git a/AvocadoEdition/bbs/memo.php b/AvocadoEdition/bbs/memo.php new file mode 100644 index 0000000..4d9c012 --- /dev/null +++ b/AvocadoEdition/bbs/memo.php @@ -0,0 +1,74 @@ + diff --git a/AvocadoEdition/bbs/memo_delete.php b/AvocadoEdition/bbs/memo_delete.php new file mode 100644 index 0000000..e80fc95 --- /dev/null +++ b/AvocadoEdition/bbs/memo_delete.php @@ -0,0 +1,27 @@ + diff --git a/AvocadoEdition/bbs/memo_form.php b/AvocadoEdition/bbs/memo_form.php new file mode 100644 index 0000000..4ada2cc --- /dev/null +++ b/AvocadoEdition/bbs/memo_form.php @@ -0,0 +1,42 @@ +' + ."\n".' >' + ."\n".' >'.str_replace("\n", "\n> ", get_text($row['me_memo'], 0)) + ."\n".' >' + .' >'; + + } +} + +$g5['title'] = '쪽지 보내기'; +include_once(G5_PATH.'/head.sub.php'); + +$memo_action_url = G5_HTTPS_BBS_URL."/memo_form_update.php"; +include_once($member_skin_path.'/memo_form.skin.php'); + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/memo_form_update.php b/AvocadoEdition/bbs/memo_form_update.php new file mode 100644 index 0000000..cc9f00a --- /dev/null +++ b/AvocadoEdition/bbs/memo_form_update.php @@ -0,0 +1,81 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/memo_view.php b/AvocadoEdition/bbs/memo_view.php new file mode 100644 index 0000000..7fdb561 --- /dev/null +++ b/AvocadoEdition/bbs/memo_view.php @@ -0,0 +1,71 @@ + '{$me_id}' + and me_{$kind}_mb_id = '{$member['mb_id']}' + order by me_id asc + limit 1 "; +$prev = sql_fetch($sql); +if ($prev['me_id']) + $prev_link = './memo_view.php?kind='.$kind.'&me_id='.$prev['me_id']; +else + //$prev_link = 'javascript:alert(\'쪽지의 처음입니다.\');'; + $prev_link = ''; + + +// 다음 쪽지 +$sql = " select * from {$g5['memo_table']} + where me_id < '{$me_id}' + and me_{$kind}_mb_id = '{$member['mb_id']}' + order by me_id desc + limit 1 "; +$next = sql_fetch($sql); +if ($next['me_id']) + $next_link = './memo_view.php?kind='.$kind.'&me_id='.$next['me_id']; +else + //$next_link = 'javascript:alert(\'쪽지의 마지막입니다.\');'; + $next_link = ''; + +$mb = get_member($memo['me_'.$unkind.'_mb_id']); + +include_once($member_skin_path.'/memo_view.skin.php'); + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/move.php b/AvocadoEdition/bbs/move.php new file mode 100644 index 0000000..a9441e4 --- /dev/null +++ b/AvocadoEdition/bbs/move.php @@ -0,0 +1,161 @@ + '$bo_table' "; +// 원본 게시판을 선택 할 수 있도록 함. +$sql = " select * from {$g5['board_table']} a, {$g5['group_table']} b where a.gr_id = b.gr_id "; +if ($is_admin == 'group') + $sql .= " and b.gr_admin = '{$member['mb_id']}' "; +else if ($is_admin == 'board') + $sql .= " and a.bo_admin = '{$member['mb_id']}' "; +$sql .= " order by a.gr_id, a.bo_order, a.bo_table "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) +{ + $list[$i] = $row; +} +?> + +
    +

    + +
    + + + + + + + + + + + + +
    + + + + + + + + + + 현재게시판'; + $atc_bg = 'copymove_currentbg'; + } + ?> + + + + + + +
    할 게시판을 한개 이상 선택하여 주십시오.
    + + + 게시판
    + + + + +
    +
    + +
    + +
    +
    + +
    + + + + diff --git a/AvocadoEdition/bbs/move_update.php b/AvocadoEdition/bbs/move_update.php new file mode 100644 index 0000000..ac6c058 --- /dev/null +++ b/AvocadoEdition/bbs/move_update.php @@ -0,0 +1,218 @@ +'; + $log_tag2 = '
    '; + } else { + $log_tag1 = "\n"; + $log_tag2 = ''; + } + + $row2['wr_content'] .= "\n".$log_tag1.'[이 게시물은 '.$nick.'님에 의해 '.G5_TIME_YMDHIS.' '.$board['bo_subject'].'에서 '.($sw == 'copy' ? '복사' : '이동').' 됨]'.$log_tag2; + } + + // 게시글 추천, 비추천수 + $wr_good = $wr_nogood = 0; + if ($sw == 'move' && $i == 0) { + $wr_good = $row2['wr_good']; + $wr_nogood = $row2['wr_nogood']; + } + + $sql = " insert into $move_write_table + set wr_num = '$next_wr_num', + wr_reply = '{$row2['wr_reply']}', + wr_is_comment = '{$row2['wr_is_comment']}', + wr_comment = '{$row2['wr_comment']}', + wr_comment_reply = '{$row2['wr_comment_reply']}', + ca_name = '".addslashes($row2['ca_name'])."', + wr_option = '{$row2['wr_option']}', + wr_subject = '".addslashes($row2['wr_subject'])."', + wr_content = '".addslashes($row2['wr_content'])."', + wr_link1 = '".addslashes($row2['wr_link1'])."', + wr_link2 = '".addslashes($row2['wr_link2'])."', + wr_link1_hit = '{$row2['wr_link1_hit']}', + wr_link2_hit = '{$row2['wr_link2_hit']}', + wr_hit = '{$row2['wr_hit']}', + wr_good = '{$wr_good}', + wr_nogood = '{$wr_nogood}', + mb_id = '{$row2['mb_id']}', + wr_password = '{$row2['wr_password']}', + wr_name = '".addslashes($row2['wr_name'])."', + wr_email = '".addslashes($row2['wr_email'])."', + wr_homepage = '".addslashes($row2['wr_homepage'])."', + wr_datetime = '{$row2['wr_datetime']}', + wr_file = '{$row2['wr_file']}', + wr_last = '{$row2['wr_last']}', + wr_ip = '{$row2['wr_ip']}', + wr_1 = '".addslashes($row2['wr_1'])."', + wr_2 = '".addslashes($row2['wr_2'])."', + wr_3 = '".addslashes($row2['wr_3'])."', + wr_4 = '".addslashes($row2['wr_4'])."', + wr_5 = '".addslashes($row2['wr_5'])."', + wr_6 = '".addslashes($row2['wr_6'])."', + wr_7 = '".addslashes($row2['wr_7'])."', + wr_8 = '".addslashes($row2['wr_8'])."', + wr_9 = '".addslashes($row2['wr_9'])."', + wr_10 = '".addslashes($row2['wr_10'])."' "; + sql_query($sql); + + $insert_id = sql_insert_id(); + + // 코멘트가 아니라면 + if (!$row2['wr_is_comment']) + { + $save_parent = $insert_id; + + $sql3 = " select * from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '{$row2['wr_id']}' order by bf_no "; + $result3 = sql_query($sql3); + for ($k=0; $row3 = sql_fetch_array($result3); $k++) + { + if ($row3['bf_file']) + { + // 원본파일을 복사하고 퍼미션을 변경 + @copy($src_dir.'/'.$row3['bf_file'], $dst_dir.'/'.$row3['bf_file']); + @chmod($dst_dir/$row3['bf_file'], G5_FILE_PERMISSION); + } + + $sql = " insert into {$g5['board_file_table']} + set bo_table = '$move_bo_table', + wr_id = '$insert_id', + bf_no = '{$row3['bf_no']}', + bf_source = '".addslashes($row3['bf_source'])."', + bf_file = '{$row3['bf_file']}', + bf_download = '{$row3['bf_download']}', + bf_content = '".addslashes($row3['bf_content'])."', + bf_filesize = '{$row3['bf_filesize']}', + bf_width = '{$row3['bf_width']}', + bf_height = '{$row3['bf_height']}', + bf_type = '{$row3['bf_type']}', + bf_datetime = '{$row3['bf_datetime']}' "; + sql_query($sql); + + if ($sw == 'move' && $row3['bf_file']) + $save[$cnt]['bf_file'][$k] = $src_dir.'/'.$row3['bf_file']; + } + + $count_write++; + + if ($sw == 'move' && $i == 0) + { + // 스크랩 이동 + sql_query(" update {$g5['scrap_table']} set bo_table = '$move_bo_table', wr_id = '$save_parent' where bo_table = '$bo_table' and wr_id = '{$row2['wr_id']}' "); + + // 최신글 이동 + sql_query(" update {$g5['board_new_table']} set bo_table = '$move_bo_table', wr_id = '$save_parent', wr_parent = '$save_parent' where bo_table = '$bo_table' and wr_id = '{$row2['wr_id']}' "); + + // 추천데이터 이동 + sql_query(" update {$g5['board_good_table']} set bo_table = '$move_bo_table', wr_id = '$save_parent' where bo_table = '$bo_table' and wr_id = '{$row2['wr_id']}' "); + } + } + else + { + $count_comment++; + + if ($sw == 'move') + { + // 최신글 이동 + sql_query(" update {$g5['board_new_table']} set bo_table = '$move_bo_table', wr_id = '$insert_id', wr_parent = '$save_parent' where bo_table = '$bo_table' and wr_id = '{$row2['wr_id']}' "); + } + } + + sql_query(" update $move_write_table set wr_parent = '$save_parent' where wr_id = '$insert_id' "); + + if ($sw == 'move') + $save[$cnt]['wr_id'] = $row2['wr_parent']; + + $cnt++; + } + + sql_query(" update {$g5['board_table']} set bo_count_write = bo_count_write + '$count_write' where bo_table = '$move_bo_table' "); + sql_query(" update {$g5['board_table']} set bo_count_comment = bo_count_comment + '$count_comment' where bo_table = '$move_bo_table' "); + + delete_cache_latest($move_bo_table); + } + + $save_count_write += $count_write; + $save_count_comment += $count_comment; +} + +delete_cache_latest($bo_table); + +if ($sw == 'move') +{ + for ($i=0; $i + + +HEREDOC; +?> diff --git a/AvocadoEdition/bbs/new.php b/AvocadoEdition/bbs/new.php new file mode 100644 index 0000000..3894333 --- /dev/null +++ b/AvocadoEdition/bbs/new.php @@ -0,0 +1,116 @@ + a.wr_parent "; +else + $view = ''; + +$mb_id = isset($_GET['mb_id']) ? ($_GET['mb_id']) : ''; +$mb_id = substr(preg_replace('#[^a-z0-9_]#i', '', $mb_id), 0, 20); + +if ($mb_id) { + $sql_common .= " and a.mb_id = '{$mb_id}' "; +} +$sql_order = " order by a.bn_id desc "; + +$sql = " select count(*) as cnt {$sql_common} "; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$rows = G5_IS_MOBILE ? $config['cf_mobile_page_rows'] : $config['cf_new_rows']; +$total_page = ceil($total_count / $rows); // 전체 페이지 계산 +if ($page < 1) $page = 1; // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $rows; // 시작 열을 구함 + +$group_select = ''; + +$list = array(); +$sql = " select a.*, b.bo_subject, b.bo_mobile_subject, c.gr_subject, c.gr_id {$sql_common} {$sql_order} limit {$from_record}, {$rows} "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) { + $tmp_write_table = $g5['write_prefix'].$row['bo_table']; + + if ($row['wr_id'] == $row['wr_parent']) { + + // 원글 + $comment = ""; + $comment_link = ""; + $row2 = sql_fetch(" select * from {$tmp_write_table} where wr_id = '{$row['wr_id']}' "); + $list[$i] = $row2; + + $name = get_sideview($row2['mb_id'], get_text(cut_str($row2['wr_name'], $config['cf_cut_name'])), $row2['wr_email'], $row2['wr_homepage']); + // 당일인 경우 시간으로 표시함 + $datetime = substr($row2['wr_datetime'],0,10); + $datetime2 = $row2['wr_datetime']; + if ($datetime == G5_TIME_YMD) { + $datetime2 = substr($datetime2,11,5); + } else { + $datetime2 = substr($datetime2,5,5); + } + + } else { + + // 코멘트 + $comment = '[코] '; + $comment_link = '#c_'.$row['wr_id']; + $row2 = sql_fetch(" select * from {$tmp_write_table} where wr_id = '{$row['wr_parent']}' "); + $row3 = sql_fetch(" select mb_id, wr_name, wr_email, wr_homepage, wr_datetime from {$tmp_write_table} where wr_id = '{$row['wr_id']}' "); + $list[$i] = $row2; + $list[$i]['wr_id'] = $row['wr_id']; + $list[$i]['mb_id'] = $row3['mb_id']; + $list[$i]['wr_name'] = $row3['wr_name']; + $list[$i]['wr_email'] = $row3['wr_email']; + $list[$i]['wr_homepage'] = $row3['wr_homepage']; + + $name = get_sideview($row3['mb_id'], get_text(cut_str($row3['wr_name'], $config['cf_cut_name'])), $row3['wr_email'], $row3['wr_homepage']); + // 당일인 경우 시간으로 표시함 + $datetime = substr($row3['wr_datetime'],0,10); + $datetime2 = $row3['wr_datetime']; + if ($datetime == G5_TIME_YMD) { + $datetime2 = substr($datetime2,11,5); + } else { + $datetime2 = substr($datetime2,5,5); + } + + } + + $list[$i]['gr_id'] = $row['gr_id']; + $list[$i]['bo_table'] = $row['bo_table']; + $list[$i]['name'] = $name; + $list[$i]['comment'] = $comment; + $list[$i]['href'] = './board.php?bo_table='.$row['bo_table'].'&wr_id='.$row2['wr_id'].$comment_link; + $list[$i]['datetime'] = $datetime; + $list[$i]['datetime2'] = $datetime2; + + $list[$i]['gr_subject'] = $row['gr_subject']; + $list[$i]['bo_subject'] = ((G5_IS_MOBILE && $row['bo_mobile_subject']) ? $row['bo_mobile_subject'] : $row['bo_subject']); + $list[$i]['wr_subject'] = $row2['wr_subject']; +} + +$write_pages = get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, "?gr_id=$gr_id&view=$view&mb_id=$mb_id&page="); + +include_once($new_skin_path.'/new.skin.php'); + +include_once('./_tail.php'); +?> diff --git a/AvocadoEdition/bbs/new_delete.php b/AvocadoEdition/bbs/new_delete.php new file mode 100644 index 0000000..4a9c3fa --- /dev/null +++ b/AvocadoEdition/bbs/new_delete.php @@ -0,0 +1,147 @@ + 0 || $count_comment > 0) { + sql_query(" update {$g5['board_table']} set bo_count_write = bo_count_write - '$count_write', bo_count_comment = bo_count_comment - '$count_comment' where bo_table = '$bo_table' "); + } + } + } + else // 코멘트 삭제 + { + //-------------------------------------------------------------------- + // 코멘트 삭제시 답변 코멘트 까지 삭제되지는 않음 + //-------------------------------------------------------------------- + //print_r2($write); + + $comment_id = $wr_id; + + $len = strlen($write['wr_comment_reply']); + if ($len < 0) $len = 0; + $comment_reply = substr($write['wr_comment_reply'], 0, $len); + + // 코멘트 삭제 + if (!delete_point($write['mb_id'], $bo_table, $comment_id, '코멘트')) { + insert_point($write['mb_id'], $board['bo_comment_point'] * (-1), "{$board['bo_subject']} {$write['wr_parent']}-{$comment_id} 코멘트삭제"); + } + + // 코멘트 삭제 + sql_query(" delete from $write_table where wr_id = '$comment_id' "); + + // 코멘트가 삭제되므로 해당 게시물에 대한 최근 시간을 다시 얻는다. + $sql = " select max(wr_datetime) as wr_last from $write_table where wr_parent = '{$write['wr_parent']}' "; + $row = sql_fetch($sql); + + // 원글의 코멘트 숫자를 감소 + sql_query(" update $write_table set wr_comment = wr_comment - 1, wr_last = '$row['wr_last']' where wr_id = '{$write['wr_parent']}' "); + + // 코멘트 숫자 감소 + sql_query(" update {$g5['board_table']} set bo_count_comment = bo_count_comment - 1 where bo_table = '$bo_table' "); + + // 새글 삭제 + sql_query(" delete from {$g5['board_new_table']} where bo_table = '$bo_table' and wr_id = '$comment_id' "); + } +} + +$save_bo_table = array_unique($save_bo_table); +foreach ($save_bo_table as $key=>$value) { + delete_cache_latest($value); +} + +goto_url("new.php?sfl=$sfl&stx=$stx&page=$page"); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/newwin.inc.php b/AvocadoEdition/bbs/newwin.inc.php new file mode 100644 index 0000000..a54010f --- /dev/null +++ b/AvocadoEdition/bbs/newwin.inc.php @@ -0,0 +1,53 @@ + + + +
    +

    팝업레이어 알림

    + + + +
    +
    + +
    + +
    +팝업레이어 알림이 없습니다.'; +?> +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/password.php b/AvocadoEdition/bbs/password.php new file mode 100644 index 0000000..072a98d --- /dev/null +++ b/AvocadoEdition/bbs/password.php @@ -0,0 +1,64 @@ + diff --git a/AvocadoEdition/bbs/password_check.php b/AvocadoEdition/bbs/password_check.php new file mode 100644 index 0000000..07e12f6 --- /dev/null +++ b/AvocadoEdition/bbs/password_check.php @@ -0,0 +1,35 @@ + diff --git a/AvocadoEdition/bbs/password_lost.php b/AvocadoEdition/bbs/password_lost.php new file mode 100644 index 0000000..23dff68 --- /dev/null +++ b/AvocadoEdition/bbs/password_lost.php @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/password_lost2.php b/AvocadoEdition/bbs/password_lost2.php new file mode 100644 index 0000000..610ee2f --- /dev/null +++ b/AvocadoEdition/bbs/password_lost2.php @@ -0,0 +1,75 @@ + 1) + alert('동일한 메일주소가 2개 이상 존재합니다.\\n\\n관리자에게 문의하여 주십시오.'); + +$sql = " select mb_no, mb_id, mb_name, mb_nick, mb_email, mb_datetime from {$g5['member_table']} where mb_email = '$email' "; +$mb = sql_fetch($sql); +if (!$mb['mb_id']) + alert('존재하지 않는 회원입니다.'); +else if (is_admin($mb['mb_id'])) + alert('관리자 아이디는 접근 불가합니다.'); + +// 임시비밀번호 발급 +$change_password = rand(100000, 999999); +$mb_lost_certify = get_encrypt_string($change_password); + +// 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용 +$mb_nonce = md5(pack('V*', rand(), rand(), rand(), rand())); + +// 임시비밀번호와 난수를 mb_lost_certify 필드에 저장 +$sql = " update {$g5['member_table']} set mb_lost_certify = '$mb_nonce $mb_lost_certify' where mb_id = '{$mb['mb_id']}' "; +sql_query($sql); + +// 인증 링크 생성 +$href = G5_BBS_URL.'/password_lost_certify.php?mb_no='.$mb['mb_no'].'&mb_nonce='.$mb_nonce; + +$subject = "[".$config['cf_title']."] 요청하신 회원정보 찾기 안내 메일입니다."; + +$content = ""; + +$content .= '
    '; +$content .= '
    '; +$content .= '

    '; +$content .= '회원정보 찾기 안내'; +$content .= '

    '; +$content .= ''; +$content .= ''.$config['cf_title'].''; +$content .= ''; +$content .= '

    '; +$content .= addslashes($mb['mb_name'])." (".addslashes($mb['mb_nick']).")"." 회원님은 ".G5_TIME_YMDHIS." 에 회원정보 찾기 요청을 하셨습니다.
    "; +$content .= '저희 사이트는 관리자라도 회원님의 비밀번호를 알 수 없기 때문에, 비밀번호를 알려드리는 대신 새로운 비밀번호를 생성하여 안내 해드리고 있습니다.
    '; +$content .= '아래에서 변경될 비밀번호를 확인하신 후, 비밀번호 변경 링크를 클릭 하십시오.
    '; +$content .= '비밀번호가 변경되었다는 인증 메세지가 출력되면, 홈페이지에서 회원아이디와 변경된 비밀번호를 입력하시고 로그인 하십시오.
    '; +$content .= '로그인 후에는 정보수정 메뉴에서 새로운 비밀번호로 변경해 주십시오.'; +$content .= '

    '; +$content .= '

    '; +$content .= '회원아이디 '.$mb['mb_id'].'
    '; +$content .= '변경될 비밀번호 '.$change_password.''; +$content .= '

    '; +$content .= '비밀번호 변경'; +$content .= '
    '; +$content .= '
    '; + +mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb['mb_email'], $subject, $content, 1); + +alert_close($email.' 메일로 회원아이디와 비밀번호를 인증할 수 있는 메일이 발송 되었습니다.\\n\\n메일을 확인하여 주십시오.'); +?> diff --git a/AvocadoEdition/bbs/password_lost_certify.php b/AvocadoEdition/bbs/password_lost_certify.php new file mode 100644 index 0000000..a0be35b --- /dev/null +++ b/AvocadoEdition/bbs/password_lost_certify.php @@ -0,0 +1,27 @@ + diff --git a/AvocadoEdition/bbs/point.php b/AvocadoEdition/bbs/point.php new file mode 100644 index 0000000..e37fe67 --- /dev/null +++ b/AvocadoEdition/bbs/point.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/poll.php b/AvocadoEdition/bbs/poll.php new file mode 100644 index 0000000..61b56db --- /dev/null +++ b/AvocadoEdition/bbs/poll.php @@ -0,0 +1,11 @@ + diff --git a/AvocadoEdition/bbs/poll_etc_update.php b/AvocadoEdition/bbs/poll_etc_update.php new file mode 100644 index 0000000..14bf555 --- /dev/null +++ b/AvocadoEdition/bbs/poll_etc_update.php @@ -0,0 +1,59 @@ + diff --git a/AvocadoEdition/bbs/poll_etc_update_mail.php b/AvocadoEdition/bbs/poll_etc_update_mail.php new file mode 100644 index 0000000..141decc --- /dev/null +++ b/AvocadoEdition/bbs/poll_etc_update_mail.php @@ -0,0 +1,30 @@ + + + + + + +설문조사 기타의견 메일 + + + + +
    +
    +

    + +

    + + 작성자 () + +

    + +

    +
    +
    + + + diff --git a/AvocadoEdition/bbs/poll_result.php b/AvocadoEdition/bbs/poll_result.php new file mode 100644 index 0000000..939758d --- /dev/null +++ b/AvocadoEdition/bbs/poll_result.php @@ -0,0 +1,115 @@ + $max) + $max = $count; +} +$nf_total_po_cnt = number_format($total_po_cnt); + +$list = array(); + +for ($i=1; $i<=9; $i++) { + $poll = $po['po_poll'.$i]; + if ($poll == '') { break; } + + $list[$i]['content'] = $poll; + $list[$i]['cnt'] = $po['po_cnt'.$i]; + if ($total_po_cnt > 0) + $list[$i]['rate'] = ($list[$i]['cnt'] / $total_po_cnt) * 100; + + $bar = (int)($list[$i]['cnt'] / $max * 100); + + $list[$i]['bar'] = $bar; + $list[$i]['num'] = $i; +} + +$list2 = array(); + +// 기타의견 리스트 +$sql = " select a.*, b.mb_open + from {$g5['poll_etc_table']} a + left join {$g5['member_table']} b on (a.mb_id = b.mb_id) + where po_id = '{$po_id}' order by pc_id desc "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) { + $list2[$i]['pc_name'] = get_text($row['pc_name']); + $list2[$i]['name'] = get_sideview($row['mb_id'], get_text(cut_str($row['pc_name'],10)), '', '', $row['mb_open']); + $list2[$i]['idea'] = get_text(cut_str($row['pc_idea'], 255)); + $list2[$i]['datetime'] = $row['pc_datetime']; + + $list2[$i]['del'] = ''; + if ($is_admin == 'super' || ($row['mb_id'] == $member['mb_id'] && $row['mb_id'])) + $list2[$i]['del'] = ''; +} + +// 기타의견 입력 +$is_etc = false; +if ($po['po_etc']) { + $is_etc = true; + $po_etc = $po['po_etc']; + if ($member['mb_id']) + $name = ''.$member['mb_nick'].' '; + else + $name = ''; +} + +$list3 = array(); + +// 다른투표 +$sql = " select po_id, po_subject, po_date from {$g5['poll_table']} order by po_id desc "; +$result = sql_query($sql); +for ($i=0; $row2=sql_fetch_array($result); $i++) { + $list3[$i]['po_id'] = $row2['po_id']; + $list3[$i]['date'] = substr($row2['po_date'],2,8); + $list3[$i]['subject'] = cut_str($row2['po_subject'],60,"…"); +} + +if(preg_match('#^theme/(.+)$#', $skin_dir, $match)) { + if (G5_IS_MOBILE) { + $poll_skin_path = G5_THEME_MOBILE_PATH.'/'.G5_SKIN_DIR.'/poll/'.$match[1]; + if(!is_dir($poll_skin_path)) + $poll_skin_path = G5_THEME_PATH.'/'.G5_SKIN_DIR.'/poll/'.$match[1]; + $poll_skin_url = str_replace(G5_PATH, G5_URL, $poll_skin_path); + } else { + $poll_skin_path = G5_THEME_PATH.'/'.G5_SKIN_DIR.'/poll/'.$match[1]; + $poll_skin_url = str_replace(G5_PATH, G5_URL, $poll_skin_path); + } + //$skin_dir = $match[1]; +} else { + if (G5_IS_MOBILE) { + $poll_skin_path = G5_MOBILE_PATH.'/'.G5_SKIN_DIR.'/poll/'.$skin_dir; + $poll_skin_url = G5_MOBILE_URL.'/'.G5_SKIN_DIR.'/poll/'.$skin_dir; + } else { + $poll_skin_path = G5_SKIN_PATH.'/poll/'.$skin_dir; + $poll_skin_url = G5_SKIN_URL.'/poll/'.$skin_dir; + } +} + +include_once(G5_PATH.'/head.sub.php'); + +if (!file_exists($poll_skin_path.'/poll_result.skin.php')) die('skin error'); +include_once ($poll_skin_path.'/poll_result.skin.php'); + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/poll_update.php b/AvocadoEdition/bbs/poll_update.php new file mode 100644 index 0000000..292e3ae --- /dev/null +++ b/AvocadoEdition/bbs/poll_update.php @@ -0,0 +1,61 @@ + diff --git a/AvocadoEdition/bbs/profile.php b/AvocadoEdition/bbs/profile.php new file mode 100644 index 0000000..c9f53b8 --- /dev/null +++ b/AvocadoEdition/bbs/profile.php @@ -0,0 +1,33 @@ + diff --git a/AvocadoEdition/bbs/qadelete.php b/AvocadoEdition/bbs/qadelete.php new file mode 100644 index 0000000..bc22d1e --- /dev/null +++ b/AvocadoEdition/bbs/qadelete.php @@ -0,0 +1,76 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/qadownload.php b/AvocadoEdition/bbs/qadownload.php new file mode 100644 index 0000000..3c1a838 --- /dev/null +++ b/AvocadoEdition/bbs/qadownload.php @@ -0,0 +1,70 @@ + diff --git a/AvocadoEdition/bbs/qahead.php b/AvocadoEdition/bbs/qahead.php new file mode 100644 index 0000000..e9fd0c0 --- /dev/null +++ b/AvocadoEdition/bbs/qahead.php @@ -0,0 +1,13 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/qalist.php b/AvocadoEdition/bbs/qalist.php new file mode 100644 index 0000000..2f5891b --- /dev/null +++ b/AvocadoEdition/bbs/qalist.php @@ -0,0 +1,122 @@ +'; + } +} + +if(is_file($skin_file)) { + $sql_common = " from {$g5['qa_content_table']} "; + $sql_search = " where qa_type = '0' "; + + if(!$is_admin) + $sql_search .= " and mb_id = '{$member['mb_id']}' "; + + if($sca) { + if (preg_match("/[a-zA-Z]/", $sca)) + $sql_search .= " and INSTR(LOWER(qa_category), LOWER('$sca')) > 0 "; + else + $sql_search .= " and INSTR(qa_category, '$sca') > 0 "; + } + + $stx = trim($stx); + if($stx) { + if (preg_match("/[a-zA-Z]/", $stx)) + $sql_search .= " and ( INSTR(LOWER(qa_subject), LOWER('$stx')) > 0 or INSTR(LOWER(qa_content), LOWER('$stx')) > 0 )"; + else + $sql_search .= " and ( INSTR(qa_subject, '$stx') > 0 or INSTR(qa_content, '$stx') > 0 ) "; + } + + $sql_order = " order by qa_num "; + + $sql = " select count(*) as cnt + $sql_common + $sql_search "; + $row = sql_fetch($sql); + $total_count = $row['cnt']; + + $page_rows = $qaconfig['qa_page_rows']; + $total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 + if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) + $from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + + $sql = " select * + $sql_common + $sql_search + $sql_order + limit $from_record, $page_rows "; + $result = sql_query($sql); + + $list = array(); + $num = $total_count - ($page - 1) * $page_rows; + $subject_len = $qaconfig['qa_subject_len']; + for($i=0; $row=sql_fetch_array($result); $i++) { + $list[$i] = $row; + + $list[$i]['category'] = get_text($row['qa_category']); + $list[$i]['subject'] = conv_subject($row['qa_subject'], $subject_len, '…'); + if ($stx) { + $list[$i]['subject'] = search_font($stx, $list[$i]['subject']); + } + + $list[$i]['view_href'] = G5_BBS_URL.'/qaview.php?qa_id='.$row['qa_id'].$qstr; + + $list[$i]['icon_file'] = ''; + if(trim($row['qa_file1']) || trim($row['qa_file2'])) + $list[$i]['icon_file'] = ''; + + $list[$i]['name'] = get_text($row['qa_name']); + $list[$i]['date'] = substr($row['qa_datetime'], 2, 8); + + $list[$i]['num'] = $num - $i; + } + + $is_checkbox = false; + $admin_href = ''; + if($is_admin) { + $is_checkbox = true; + $admin_href = G5_ADMIN_URL.'/qa_config.php'; + } + + $list_href = G5_BBS_URL.'/qalist.php'; + $write_href = G5_BBS_URL.'/qawrite.php'; + + $list_pages = preg_replace('/(\.php)(&|&)/i', '$1?', get_paging($qaconfig['qa_page_rows'], $page, $total_page, './qalist.php'.$qstr.'&page=')); + + $stx = get_text(stripslashes($stx)); + include_once($skin_file); +} else { + echo '
    '.str_replace(G5_PATH.'/', '', $skin_file).'이 존재하지 않습니다.
    '; +} + +include_once('./qatail.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/qatail.php b/AvocadoEdition/bbs/qatail.php new file mode 100644 index 0000000..8cc00e1 --- /dev/null +++ b/AvocadoEdition/bbs/qatail.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/qaview.php b/AvocadoEdition/bbs/qaview.php new file mode 100644 index 0000000..f6b2944 --- /dev/null +++ b/AvocadoEdition/bbs/qaview.php @@ -0,0 +1,175 @@ + '{$view['qa_num']}' order by qa_num asc limit 1 "; + $next = sql_fetch($sql.$next_search); + + $next_href = ''; + if (isset($next['qa_id']) && $next['qa_id']) { + $next_qa_subject = get_text(cut_str($next['qa_subject'], 255)); + $next_href = G5_BBS_URL.'/qaview.php?qa_id='.$next['qa_id'].$qstr; + } + + + // 관련질문 + $rows = 10; + $sql = " select * + from {$g5['qa_content_table']} + where qa_id <> '$qa_id' + and qa_related = '{$view['qa_related']}' + and qa_type = '0' + order by qa_num, qa_type + limit 0, $rows "; + $result = sql_query($sql); + + $rel_list = array(); + $rel_count = 0; + for($i=0; $row=sql_fetch_array($result); $i++) { + $rel_list[$i] = $row; + $rel_list[$i]['category'] = get_text($row['qa_category']); + $rel_list[$i]['subject'] = conv_subject($row['qa_subject'], $subject_len, '…'); + $rel_list[$i]['name'] = get_text($row['qa_name']); + $rel_list[$i]['date'] = substr($row['qa_datetime'], 2, 8); + $rel_list[$i]['view_href'] = G5_BBS_URL.'/qaview.php?qa_id='.$row['qa_id'].$qstr; + $rel_count++; + } + $view['rel_count'] = $rel_count; + + $update_href = ''; + $delete_href = ''; + $write_href = G5_BBS_URL.'/qawrite.php'; + $rewrite_href = G5_BBS_URL.'/qawrite.php?w=r&qa_id='.$view['qa_id']; + $list_href = G5_BBS_URL.'/qalist.php'.preg_replace('/^&/', '?', $qstr); + + /* + if($view['qa_type']) { + if($is_admin) + $update_href = G5_BBS_URL.'/qawrite.php?w=u&qa_id='.$view['qa_id'].$qstr; + } else { + if($view['qa_status'] == 0) + $update_href = G5_BBS_URL.'/qawrite.php?w=u&qa_id='.$view['qa_id'].$qstr; + } + */ + if(($view['qa_type'] && $is_admin) || (!$view['qa_type'] && $view['qa_status'] == 0)) { + $update_href = G5_BBS_URL.'/qawrite.php?w=u&qa_id='.$view['qa_id'].$qstr; + $delete_href = G5_BBS_URL.'/qadelete.php?qa_id='.$view['qa_id'].$qstr; + } + + // 질문글이고 등록된 답변이 있다면 + $answer = array(); + $answer_update_href = ''; + $answer_delete_href = ''; + if(!$view['qa_type'] && $view['qa_status']) { + $sql = " select * + from {$g5['qa_content_table']} + where qa_type = '1' + and qa_parent = '{$view['qa_id']}' "; + $answer = sql_fetch($sql); + + if($is_admin) { + $answer_update_href = G5_BBS_URL.'/qawrite.php?w=u&qa_id='.$answer['qa_id'].$qstr; + $answer_delete_href = G5_BBS_URL.'/qadelete.php?qa_id='.$answer['qa_id'].$qstr; + } + } + + $stx = get_text(stripslashes($stx)); + + $is_dhtml_editor = false; + // 모바일에서는 DHTML 에디터 사용불가 + if ($config['cf_editor'] && $qaconfig['qa_use_editor'] && !G5_IS_MOBILE) { + $is_dhtml_editor = true; + } + $editor_html = editor_html('qa_content', $content, $is_dhtml_editor); + $editor_js = ''; + $editor_js .= get_editor_js('qa_content', $is_dhtml_editor); + $editor_js .= chk_editor_js('qa_content', $is_dhtml_editor); + + $ss_name = 'ss_qa_view_'.$qa_id; + if(!get_session($ss_name)) + set_session($ss_name, TRUE); + + // 첨부파일 + $view['img_file'] = array(); + $view['download_href'] = array(); + $view['download_source'] = array(); + $view['img_count'] = 0; + $view['download_count'] = 0; + + for ($i=1; $i<=2; $i++) { + if(preg_match("/\.({$config['cf_image_extension']})$/i", $view['qa_file'.$i])) { + $view['img_file'][] = '
    '; + $view['img_count']++; + continue; + } + + if ($view['qa_file'.$i]) { + $view['download_href'][] = G5_BBS_URL.'/qadownload.php?qa_id='.$view['qa_id'].'&no='.$i; + $view['download_source'][] = $view['qa_source'.$i]; + $view['download_count']++; + } + } + + include_once($skin_file); +} else { + echo '
    '.str_replace(G5_PATH.'/', '', $skin_file).'이 존재하지 않습니다.
    '; +} + +include_once('./qatail.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/qawrite.php b/AvocadoEdition/bbs/qawrite.php new file mode 100644 index 0000000..d9ffd7b --- /dev/null +++ b/AvocadoEdition/bbs/qawrite.php @@ -0,0 +1,138 @@ +


    ====== 이전 답변내용 =======
    '; + else + $content = "\n\n\n\n====== 이전 답변내용 =======\n"; + + $content .= get_text($write['qa_content'], 0); + } else { + $content = get_text($write['qa_content'], 0); + } + + $editor_html = editor_html('qa_content', $content, $is_dhtml_editor); + $editor_js = ''; + $editor_js .= get_editor_js('qa_content', $is_dhtml_editor); + $editor_js .= chk_editor_js('qa_content', $is_dhtml_editor); + + $upload_max_filesize = number_format($qaconfig['qa_upload_size']) . ' 바이트'; + + $html_value = ''; + if ($write['qa_html']) { + $html_checked = 'checked'; + $html_value = $write['qa_html']; + + if($w == 'r' && $write['qa_html'] == 1 && !$is_dhtml_editor) + $html_value = 2; + } + + $is_email = false; + $req_email = ''; + if($qaconfig['qa_use_email']) { + $is_email = true; + + if($qaconfig['qa_req_email']) + $req_email = 'required'; + + if($w == '' || $w == 'r') + $write['qa_email'] = $member['mb_email']; + + if($w == 'u' && $is_admin && $write['qa_type']) + $is_email = false; + } + + $is_hp = false; + $req_hp = ''; + if($qaconfig['qa_use_hp']) { + $is_hp = true; + + if($qaconfig['qa_req_hp']) + $req_hp = 'required'; + + if($w == '' || $w == 'r') + $write['qa_hp'] = $member['mb_hp']; + + if($w == 'u' && $is_admin && $write['qa_type']) + $is_hp = false; + } + + $list_href = G5_BBS_URL.'/qalist.php'.preg_replace('/^&/', '?', $qstr); + + $action_url = https_url(G5_BBS_DIR).'/qawrite_update.php'; + + include_once($skin_file); +} else { + echo '
    '.str_replace(G5_PATH.'/', '', $skin_file).'이 존재하지 않습니다.
    '; +} + +include_once('./qatail.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/qawrite_update.php b/AvocadoEdition/bbs/qawrite_update.php new file mode 100644 index 0000000..b00d082 --- /dev/null +++ b/AvocadoEdition/bbs/qawrite_update.php @@ -0,0 +1,451 @@ +제목
    을 입력하세요.'; +} + +$qa_content = ''; +if (isset($_POST['qa_content'])) { + $qa_content = substr(trim($_POST['qa_content']),0,65536); + $qa_content = preg_replace("#[\\\]+$#", "", $qa_content); +} +if ($qa_content == '') { + $msg[] = '내용을 입력하세요.'; +} + +if (!empty($msg)) { + $msg = implode('
    ', $msg); + alert($msg); +} + +if($qa_hp) + $qa_hp = preg_replace('/[^0-9\-]/', '', strip_tags($qa_hp)); + +// 090710 +if (substr_count($qa_content, '&#') > 50) { + alert('내용에 올바르지 않은 코드가 다수 포함되어 있습니다.'); + exit; +} + +$upload_max_filesize = ini_get('upload_max_filesize'); + +if (empty($_POST)) { + alert("파일 또는 글내용의 크기가 서버에서 설정한 값을 넘어 오류가 발생하였습니다.\\npost_max_size=".ini_get('post_max_size')." , upload_max_filesize=".$upload_max_filesize."\\n게시판관리자 또는 서버관리자에게 문의 바랍니다."); +} + +for ($i=1; $i<=5; $i++) { + $var = "qa_$i"; + $$var = ""; + if (isset($_POST['qa_'.$i]) && $_POST['qa_'.$i]) { + $$var = trim($_POST['qa_'.$i]); + } +} + +if($w == 'u' || $w == 'a' || $w == 'r') { + if($w == 'a' && !$is_admin) + alert('답변은 관리자만 등록할 수 있습니다.'); + + $sql = " select * from {$g5['qa_content_table']} where qa_id = '$qa_id' "; + if(!$is_admin) { + $sql .= " and mb_id = '{$member['mb_id']}' "; + } + + $write = sql_fetch($sql); + + if($w == 'u') { + if(!$write['qa_id']) + alert('게시글이 존재하지 않습니다.\\n삭제되었거나 자신의 글이 아닌 경우입니다.'); + + if(!$is_admin) { + if($write['qa_type'] == 0 && $write['qa_status'] == 1) + alert('답변이 등록된 문의글은 수정할 수 없습니다.'); + + if($write['mb_id'] != $member['mb_id']) + alert('게시글을 수정할 권한이 없습니다.\\n\\n올바른 방법으로 이용해 주십시오.', G5_URL); + } + } + + if($w == 'a') { + if(!$write['qa_id']) + alert('문의글이 존재하지 않아 답변글을 등록할 수 없습니다.'); + + if($write['qa_type'] == 1) + alert('답변글에는 다시 답변을 등록할 수 없습니다.'); + } +} + +// 파일개수 체크 +$file_count = 0; +$upload_count = count($_FILES['bf_file']['name']); + +for ($i=1; $i<=$upload_count; $i++) { + if($_FILES['bf_file']['name'][$i] && is_uploaded_file($_FILES['bf_file']['tmp_name'][$i])) + $file_count++; +} + +if($file_count > 2) + alert('첨부파일을 2개 이하로 업로드 해주십시오.'); + +// 디렉토리가 없다면 생성합니다. (퍼미션도 변경하구요.) +@mkdir(G5_DATA_PATH.'/qa', G5_DIR_PERMISSION); +@chmod(G5_DATA_PATH.'/qa', G5_DIR_PERMISSION); + +$chars_array = array_merge(range(0,9), range('a','z'), range('A','Z')); + +// 가변 파일 업로드 +$file_upload_msg = ''; +$upload = array(); +for ($i=1; $i<=count($_FILES['bf_file']['name']); $i++) { + $upload[$i]['file'] = ''; + $upload[$i]['source'] = ''; + $upload[$i]['del_check'] = false; + + // 삭제에 체크가 되어있다면 파일을 삭제합니다. + if (isset($_POST['bf_file_del'][$i]) && $_POST['bf_file_del'][$i]) { + $upload[$i]['del_check'] = true; + @unlink(G5_DATA_PATH.'/qa/'.$write['qa_file'.$i]); + // 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $write['qa_file'.$i])) { + delete_qa_thumbnail($write['qa_file'.$i]); + } + } + + $tmp_file = $_FILES['bf_file']['tmp_name'][$i]; + $filesize = $_FILES['bf_file']['size'][$i]; + $filename = $_FILES['bf_file']['name'][$i]; + $filename = get_safe_filename($filename); + + // 서버에 설정된 값보다 큰파일을 업로드 한다면 + if ($filename) { + if ($_FILES['bf_file']['error'][$i] == 1) { + $file_upload_msg .= '\"'.$filename.'\" 파일의 용량이 서버에 설정('.$upload_max_filesize.')된 값보다 크므로 업로드 할 수 없습니다.\\n'; + continue; + } + else if ($_FILES['bf_file']['error'][$i] != 0) { + $file_upload_msg .= '\"'.$filename.'\" 파일이 정상적으로 업로드 되지 않았습니다.\\n'; + continue; + } + } + + if (is_uploaded_file($tmp_file)) { + // 관리자가 아니면서 설정한 업로드 사이즈보다 크다면 건너뜀 + if (!$is_admin && $filesize > $qaconfig['qa_upload_size']) { + $file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($qaconfig['qa_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n'; + continue; + } + + //=================================================================\ + // 090714 + // 이미지나 플래시 파일에 악성코드를 심어 업로드 하는 경우를 방지 + // 에러메세지는 출력하지 않는다. + //----------------------------------------------------------------- + $timg = @getimagesize($tmp_file); + // image type + if ( preg_match("/\.({$config['cf_image_extension']})$/i", $filename) || + preg_match("/\.({$config['cf_flash_extension']})$/i", $filename) ) { + if ($timg['2'] < 1 || $timg['2'] > 16) + continue; + } + //================================================================= + + if ($w == 'u') { + // 존재하는 파일이 있다면 삭제합니다. + @unlink(G5_DATA_PATH.'/qa/'.$write['qa_file'.$i]); + // 이미지파일이면 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $write['qa_file'.$i])) { + delete_qa_thumbnail($row['qa_file'.$i]); + } + } + + // 프로그램 원래 파일명 + $upload[$i]['source'] = $filename; + $upload[$i]['filesize'] = $filesize; + + // 아래의 문자열이 들어간 파일은 -x 를 붙여서 웹경로를 알더라도 실행을 하지 못하도록 함 + $filename = preg_replace("/\.(php|phtm|htm|cgi|pl|exe|jsp|asp|inc)/i", "$0-x", $filename); + + shuffle($chars_array); + $shuffle = implode('', $chars_array); + + // 첨부파일 첨부시 첨부파일명에 공백이 포함되어 있으면 일부 PC에서 보이지 않거나 다운로드 되지 않는 현상이 있습니다. (길상여의 님 090925) + $upload[$i]['file'] = abs(ip2long($_SERVER['REMOTE_ADDR'])).'_'.substr($shuffle,0,8).'_'.replace_filename($filename); + + $dest_file = G5_DATA_PATH.'/qa/'.$upload[$i]['file']; + + // 업로드가 안된다면 에러메세지 출력하고 죽어버립니다. + $error_code = move_uploaded_file($tmp_file, $dest_file) or die($_FILES['bf_file']['error'][$i]); + + // 올라간 파일의 퍼미션을 변경합니다. + chmod($dest_file, G5_FILE_PERMISSION); + } +} + +if($w == '' || $w == 'a' || $w == 'r') { + if($w == '' || $w == 'r') { + $row = sql_fetch(" select MIN(qa_num) as min_qa_num from {$g5['qa_content_table']} "); + $qa_num = $row['min_qa_num'] - 1; + } + + if($w == 'a') { + $qa_num = $write['qa_num']; + $qa_parent = $write['qa_id']; + $qa_related = $write['qa_related']; + $qa_category = $write['qa_category']; + $qa_type = 1; + $qa_status = 1; + } + + $sql = " insert into {$g5['qa_content_table']} + set qa_num = '$qa_num', + mb_id = '{$member['mb_id']}', + qa_name = '".addslashes($member['mb_nick'])."', + qa_email = '$qa_email', + qa_hp = '$qa_hp', + qa_type = '$qa_type', + qa_parent = '$qa_parent', + qa_related = '$qa_related', + qa_category = '$qa_category', + qa_email_recv = '$qa_email_recv', + qa_sms_recv = '$qa_sms_recv', + qa_html = '$qa_html', + qa_subject = '$qa_subject', + qa_content = '$qa_content', + qa_status = '$qa_status', + qa_file1 = '{$upload[1]['file']}', + qa_source1 = '{$upload[1]['source']}', + qa_file2 = '{$upload[2]['file']}', + qa_source2 = '{$upload[2]['source']}', + qa_ip = '{$_SERVER['REMOTE_ADDR']}', + qa_datetime = '".G5_TIME_YMDHIS."', + qa_1 = '$qa_1', + qa_2 = '$qa_2', + qa_3 = '$qa_3', + qa_4 = '$qa_4', + qa_5 = '$qa_5' "; + sql_query($sql); + + if($w == '' || $w == 'r') { + $qa_id = sql_insert_id(); + + if($w == 'r' && $write['qa_related']) { + $qa_related = $write['qa_related']; + } else { + $qa_related = $qa_id; + } + + $sql = " update {$g5['qa_content_table']} + set qa_parent = '$qa_id', + qa_related = '$qa_related' + where qa_id = '$qa_id' "; + sql_query($sql); + } + + if($w == 'a') { + $sql = " update {$g5['qa_content_table']} + set qa_status = '1' + where qa_id = '{$write['qa_parent']}' "; + sql_query($sql); + } +} else if($w == 'u') { + if(!$upload[1]['file'] && !$upload[1]['del_check']) { + $upload[1]['file'] = $write['qa_file1']; + $upload[1]['source'] = $write['qa_source1']; + } + + if(!$upload[2]['file'] && !$upload[2]['del_check']) { + $upload[2]['file'] = $write['qa_file2']; + $upload[2]['source'] = $write['qa_source2']; + } + + $sql = " update {$g5['qa_content_table']} + set qa_email = '$qa_email', + qa_hp = '$qa_hp', + qa_category = '$qa_category', + qa_html = '$qa_html', + qa_subject = '$qa_subject', + qa_content = '$qa_content', + qa_file1 = '{$upload[1]['file']}', + qa_source1 = '{$upload[1]['source']}', + qa_file2 = '{$upload[2]['file']}', + qa_source2 = '{$upload[2]['source']}', + qa_1 = '$qa_1', + qa_2 = '$qa_2', + qa_3 = '$qa_3', + qa_4 = '$qa_4', + qa_5 = '$qa_5' "; + if($qa_sms_recv) + $sql .= ", qa_sms_recv = '$qa_sms_recv' "; + $sql .= " where qa_id = '$qa_id' "; + sql_query($sql); +} + +// SMS 알림 +if($config['cf_sms_use'] == 'icode' && $qaconfig['qa_use_sms']) { + if($config['cf_sms_type'] == 'LMS') { + include_once(G5_LIB_PATH.'/icode.lms.lib.php'); + + $port_setting = get_icode_port_type($config['cf_icode_id'], $config['cf_icode_pw']); + + // SMS 모듈 클래스 생성 + if($port_setting !== false) { + // 답변글은 질문 등록자에게 전송 + if($w == 'a' && $write['qa_sms_recv'] && trim($write['qa_hp'])) { + $sms_content = $config['cf_title'].' '.$qaconfig['qa_title'].'에 답변이 등록되었습니다.'; + $send_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_send_number']); + $recv_number = preg_replace('/[^0-9]/', '', $write['qa_hp']); + + if($recv_number) { + $strDest = array(); + $strDest[] = $recv_number; + $strCallBack = $send_number; + $strCaller = iconv_euckr(trim($config['cf_title'])); + $strSubject = ''; + $strURL = ''; + $strData = iconv_euckr($sms_content); + $strDate = ''; + $nCount = count($strDest); + + $SMS = new LMS; + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $port_setting); + $res = $SMS->Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate, $nCount); + + if($res) { + $SMS->Send(); + } + + $SMS->Init(); // 보관하고 있던 결과값을 지웁니다. + } + } + + // 문의글 등록시 관리자에게 전송 + if(($w == '' || $w == 'r') && trim($qaconfig['qa_admin_hp'])) { + $sms_content = $config['cf_title'].' '.$qaconfig['qa_title'].'에 문의글이 등록되었습니다.'; + $send_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_send_number']); + $recv_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_admin_hp']); + + if($recv_number) { + $strDest = array(); + $strDest[] = $recv_number; + $strCallBack = $send_number; + $strCaller = iconv_euckr(trim($config['cf_title']));; + $strSubject = ''; + $strURL = ''; + $strData = iconv_euckr($sms_content); + $strDate = ''; + $nCount = count($strDest); + + $SMS = new LMS; + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $port_setting); + $res = $SMS->Add($strDest, $strCallBack, $strCaller, $strSubject, $strURL, $strData, $strDate, $nCount); + + if($res) { + $SMS->Send(); + } + + $SMS->Init(); // 보관하고 있던 결과값을 지웁니다. + } + } + } + } else { + include_once(G5_LIB_PATH.'/icode.sms.lib.php'); + + // 답변글은 질문 등록자에게 전송 + if($w == 'a' && $write['qa_sms_recv'] && trim($write['qa_hp'])) { + $sms_content = $config['cf_title'].' '.$qaconfig['qa_title'].'에 답변이 등록되었습니다.'; + $send_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_send_number']); + $recv_number = preg_replace('/[^0-9]/', '', $write['qa_hp']); + + if($recv_number) { + $SMS = new SMS; // SMS 연결 + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $config['cf_icode_server_port']); + $SMS->Add($recv_number, $send_number, $config['cf_icode_id'], iconv("utf-8", "euc-kr", stripslashes($sms_content)), ""); + $SMS->Send(); + } + } + + // 문의글 등록시 관리자에게 전송 + if(($w == '' || $w == 'r') && trim($qaconfig['qa_admin_hp'])) { + $sms_content = $config['cf_title'].' '.$qaconfig['qa_title'].'에 문의글이 등록되었습니다.'; + $send_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_send_number']); + $recv_number = preg_replace('/[^0-9]/', '', $qaconfig['qa_admin_hp']); + + if($recv_number) { + $SMS = new SMS; // SMS 연결 + $SMS->SMS_con($config['cf_icode_server_ip'], $config['cf_icode_id'], $config['cf_icode_pw'], $config['cf_icode_server_port']); + $SMS->Add($recv_number, $send_number, $config['cf_icode_id'], iconv("utf-8", "euc-kr", stripslashes($sms_content)), ""); + $SMS->Send(); + } + } + } +} + +// 답변 이메일전송 +if($w == 'a' && $write['qa_email_recv'] && trim($write['qa_email'])) { + include_once(G5_LIB_PATH.'/mailer.lib.php'); + + $subject = $config['cf_title'].' '.$qaconfig['qa_title'].' 답변 알림 메일'; + $content = nl2br(conv_unescape_nl(stripslashes($qa_content))); + + mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $write['qa_email'], $subject, $content, 1); +} + +// 문의글등록 이메일전송 +if(($w == '' || $w == 'r') && trim($qaconfig['qa_admin_email'])) { + include_once(G5_LIB_PATH.'/mailer.lib.php'); + + $subject = $config['cf_title'].' '.$qaconfig['qa_title'].' 질문 알림 메일'; + $content = nl2br(conv_unescape_nl(stripslashes($qa_content))); + + mailer($config['cf_admin_email_name'], $qa_email, $qaconfig['qa_admin_email'], $subject, $content, 1); +} + +if($w == 'a') + $result_url = G5_BBS_URL.'/qaview.php?qa_id='.$qa_id.$qstr; +else if($w == 'u' && $write['qa_type']) + $result_url = G5_BBS_URL.'/qaview.php?qa_id='.$write['qa_parent'].$qstr; +else + $result_url = G5_BBS_URL.'/qalist.php'.preg_replace('/^&/', '?', $qstr); + +if ($file_upload_msg) + alert($file_upload_msg, $result_url); +else + goto_url($result_url); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/register.php b/AvocadoEdition/bbs/register.php new file mode 100644 index 0000000..d46cdf8 --- /dev/null +++ b/AvocadoEdition/bbs/register.php @@ -0,0 +1,24 @@ + diff --git a/AvocadoEdition/bbs/register_email.php b/AvocadoEdition/bbs/register_email.php new file mode 100644 index 0000000..2ff45ca --- /dev/null +++ b/AvocadoEdition/bbs/register_email.php @@ -0,0 +1,58 @@ + + +

    메일인증을 받지 못한 경우 회원정보의 메일주소를 변경 할 수 있습니다.

    + +
    + + +
    + + + + + + + + + + +
    사이트 이용정보 입력
    자동등록방지
    +
    + +
    + + 취소 +
    + +
    + + + diff --git a/AvocadoEdition/bbs/register_email_update.php b/AvocadoEdition/bbs/register_email_update.php new file mode 100644 index 0000000..8f3a4f5 --- /dev/null +++ b/AvocadoEdition/bbs/register_email_update.php @@ -0,0 +1,51 @@ + '{$mb_id}' and mb_email = '$mb_email' "; +$row = sql_fetch($sql); +if ($row['cnt']) { + alert("{$mb_email} 메일은 이미 존재하는 메일주소 입니다.\\n\\n다른 메일주소를 입력해 주십시오."); +} + +// 인증메일 발송 +$subject = '['.$config['cf_title'].'] 인증확인 메일입니다.'; + +$mb_name = $mb['mb_name']; + +// 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용 +$mb_md5 = md5(pack('V*', rand(), rand(), rand(), rand())); + +sql_query(" update {$g5['member_table']} set mb_email_certify2 = '$mb_md5' where mb_id = '$mb_id' "); + +$certify_href = G5_BBS_URL.'/email_certify.php?mb_id='.$mb_id.'&mb_md5='.$mb_md5; + +ob_start(); +include_once ('./register_form_update_mail3.php'); +$content = ob_get_contents(); +ob_end_clean(); + +mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb_email, $subject, $content, 1); + +$sql = " update {$g5['member_table']} set mb_email = '$mb_email' where mb_id = '$mb_id' "; +sql_query($sql); + +alert("인증메일을 {$mb_email} 메일로 다시 보내 드렸습니다.\\n\\n잠시후 {$mb_email} 메일을 확인하여 주십시오.", G5_URL); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/register_form.php b/AvocadoEdition/bbs/register_form.php new file mode 100644 index 0000000..b468019 --- /dev/null +++ b/AvocadoEdition/bbs/register_form.php @@ -0,0 +1,143 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/register_form_update.php b/AvocadoEdition/bbs/register_form_update.php new file mode 100644 index 0000000..3ceb9b0 --- /dev/null +++ b/AvocadoEdition/bbs/register_form_update.php @@ -0,0 +1,463 @@ + date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) + $mb_nick = $member['mb_nick']; + // 회원정보의 메일을 이전 메일로 옮기고 아래에서 비교함 + $old_email = $member['mb_email']; + } + + if ($msg = exist_mb_nick($mb_nick, $mb_id)) alert($msg, "", true, true); + if ($msg = exist_mb_email($mb_email, $mb_id)) alert($msg, "", true, true); +} + +// 사용자 코드 실행 +@include_once($member_skin_path.'/register_form_update.head.skin.php'); + +//=============================================================== +// 본인확인 +//--------------------------------------------------------------- +/*$mb_hp = hyphen_hp_number($mb_hp); +if($config['cf_cert_use'] && $_SESSION['ss_cert_type'] && $_SESSION['ss_cert_dupinfo']) { + // 중복체크 + $sql = " select mb_id from {$g5['member_table']} where mb_id <> '{$member['mb_id']}' and mb_dupinfo = '{$_SESSION['ss_cert_dupinfo']}' "; + $row = sql_fetch($sql); + if ($row['mb_id']) { + alert("입력하신 본인확인 정보로 가입된 내역이 존재합니다.\\n회원아이디 : ".$row['mb_id']); + } +} + +$sql_certify = ''; +$md5_cert_no = $_SESSION['ss_cert_no']; +$cert_type = $_SESSION['ss_cert_type']; +if ($config['cf_cert_use'] && $cert_type && $md5_cert_no) { + // 해시값이 같은 경우에만 본인확인 값을 저장한다. + if ($_SESSION['ss_cert_hash'] == md5($mb_name.$cert_type.$_SESSION['ss_cert_birth'].$md5_cert_no)) { + $sql_certify .= " , mb_hp = '{$mb_hp}' "; + $sql_certify .= " , mb_certify = '{$cert_type}' "; + $sql_certify .= " , mb_adult = '{$_SESSION['ss_cert_adult']}' "; + $sql_certify .= " , mb_birth = '{$_SESSION['ss_cert_birth']}' "; + $sql_certify .= " , mb_sex = '{$_SESSION['ss_cert_sex']}' "; + $sql_certify .= " , mb_dupinfo = '{$_SESSION['ss_cert_dupinfo']}' "; + if($w == 'u') + $sql_certify .= " , mb_name = '{$mb_name}' "; + } else { + $sql_certify .= " , mb_hp = '{$mb_hp}' "; + $sql_certify .= " , mb_certify = '' "; + $sql_certify .= " , mb_adult = 0 "; + $sql_certify .= " , mb_birth = '' "; + $sql_certify .= " , mb_sex = '' "; + } +} else { + if (get_session("ss_reg_mb_name") != $mb_name || get_session("ss_reg_mb_hp") != $mb_hp) { + $sql_certify .= " , mb_hp = '{$mb_hp}' "; + $sql_certify .= " , mb_certify = '' "; + $sql_certify .= " , mb_adult = 0 "; + $sql_certify .= " , mb_birth = '' "; + $sql_certify .= " , mb_sex = '' "; + } +}*/ +//=============================================================== + +if ($w == '') { + $sql = " insert into {$g5['member_table']} + set mb_id = '{$mb_id}', + mb_password = '".get_encrypt_string($mb_password)."', + mb_name = '{$mb_name}', + mb_nick = '{$mb_nick}', + mb_nick_date = '".G5_TIME_YMD."', + mb_email = '{$mb_email}', + mb_homepage = '{$mb_homepage}', + mb_tel = '{$mb_tel}', + mb_zip1 = '{$mb_zip1}', + mb_zip2 = '{$mb_zip2}', + mb_addr1 = '{$mb_addr1}', + mb_addr2 = '{$mb_addr2}', + mb_addr3 = '{$mb_addr3}', + mb_addr_jibeon = '{$mb_addr_jibeon}', + mb_signature = '{$mb_signature}', + mb_profile = '{$mb_profile}', + mb_today_login = '".G5_TIME_YMDHIS."', + mb_datetime = '".G5_TIME_YMDHIS."', + mb_ip = '{$_SERVER['REMOTE_ADDR']}', + mb_level = '{$config['cf_register_level']}', + mb_recommend = '{$mb_recommend}', + mb_login_ip = '{$_SERVER['REMOTE_ADDR']}', + mb_mailling = '{$mb_mailling}', + mb_sms = '{$mb_sms}', + mb_open = '{$mb_open}', + mb_open_date = '".G5_TIME_YMD."', + mb_birth = '{$mb_birth}', + mb_1 = '{$mb_1}', + mb_2 = '{$mb_2}', + mb_3 = '{$mb_3}', + mb_4 = '{$mb_4}', + mb_5 = '{$mb_5}', + mb_6 = '{$mb_6}', + mb_7 = '{$mb_7}', + mb_8 = '{$mb_8}', + mb_9 = '{$mb_9}', + mb_10 = '{$mb_10}' + {$sql_certify} "; + + // 이메일 인증을 사용하지 않는다면 이메일 인증시간을 바로 넣는다 + if (!$config['cf_use_email_certify']) + $sql .= " , mb_email_certify = '".G5_TIME_YMDHIS."' "; + sql_query($sql); + + // 회원가입 포인트 부여 + insert_point($mb_id, $config['cf_register_point'], '회원가입 축하', '@member', $mb_id, '회원가입'); + + // 추천인에게 포인트 부여 + if ($config['cf_use_recommend'] && $mb_recommend) + insert_point($mb_recommend, $config['cf_recommend_point'], $mb_id.'의 추천인', '@member', $mb_recommend, $mb_id.' 추천'); + + // 회원님께 메일 발송 + if ($config['cf_email_mb_member']) { + $subject = '['.$config['cf_title'].'] 회원가입을 축하드립니다.'; + + // 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용 + if ($config['cf_use_email_certify']) { + $mb_md5 = md5(pack('V*', rand(), rand(), rand(), rand())); + sql_query(" update {$g5['member_table']} set mb_email_certify2 = '$mb_md5' where mb_id = '$mb_id' "); + $certify_href = G5_BBS_URL.'/email_certify.php?mb_id='.$mb_id.'&mb_md5='.$mb_md5; + } + + ob_start(); + include_once ('./register_form_update_mail1.php'); + $content = ob_get_contents(); + ob_end_clean(); + + mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb_email, $subject, $content, 1); + + // 메일인증을 사용하는 경우 가입메일에 인증 url이 있으므로 인증메일을 다시 발송되지 않도록 함 + if($config['cf_use_email_certify']) + $old_email = $mb_email; + } + + // 최고관리자님께 메일 발송 + if ($config['cf_email_mb_super_admin']) { + $subject = '['.$config['cf_title'].'] '.$mb_nick .' 님께서 회원으로 가입하셨습니다.'; + + ob_start(); + include_once ('./register_form_update_mail2.php'); + $content = ob_get_contents(); + ob_end_clean(); + + mailer($mb_nick, $mb_email, $config['cf_admin_email'], $subject, $content, 1); + } + + // 메일인증 사용하지 않는 경우에만 로그인 + if (!$config['cf_use_email_certify']) + set_session('ss_mb_id', $mb_id); + + set_session('ss_mb_reg', $mb_id); + +} else if ($w == 'u') { + if (!trim($_SESSION['ss_mb_id'])) + alert('로그인 되어 있지 않습니다.'); + + if (trim($_POST['mb_id']) != $mb_id) + alert("로그인된 정보와 수정하려는 정보가 틀리므로 수정할 수 없습니다.\\n만약 올바르지 않은 방법을 사용하신다면 바로 중지하여 주십시오."); + + $sql_password = ""; + if ($mb_password) + $sql_password = " , mb_password = '".get_encrypt_string($mb_password)."' "; + + $sql_nick_date = ""; + if ($mb_nick_default != $mb_nick) + $sql_nick_date = " , mb_nick_date = '".G5_TIME_YMD."' "; + + $sql_open_date = ""; + if ($mb_open_default != $mb_open) + $sql_open_date = " , mb_open_date = '".G5_TIME_YMD."' "; + + // 이전 메일주소와 수정한 메일주소가 틀리다면 인증을 다시 해야하므로 값을 삭제 + $sql_email_certify = ''; + if ($old_email != $mb_email && $config['cf_use_email_certify']) + $sql_email_certify = " , mb_email_certify = '' "; + + $sql = " update {$g5['member_table']} + set mb_name = '{$mb_name}', + mb_nick = '{$mb_nick}', + mb_mailling = '{$mb_mailling}', + mb_sms = '{$mb_sms}', + mb_open = '{$mb_open}', + mb_email = '{$mb_email}', + mb_homepage = '{$mb_homepage}', + mb_tel = '{$mb_tel}', + mb_zip1 = '{$mb_zip1}', + mb_zip2 = '{$mb_zip2}', + mb_addr1 = '{$mb_addr1}', + mb_addr2 = '{$mb_addr2}', + mb_addr3 = '{$mb_addr3}', + mb_addr_jibeon = '{$mb_addr_jibeon}', + mb_signature = '{$mb_signature}', + mb_profile = '{$mb_profile}', + mb_birth = '{$mb_birth}', + mb_1 = '{$mb_1}', + mb_2 = '{$mb_2}', + mb_3 = '{$mb_3}', + mb_4 = '{$mb_4}', + mb_5 = '{$mb_5}', + mb_6 = '{$mb_6}', + mb_7 = '{$mb_7}', + mb_8 = '{$mb_8}', + mb_9 = '{$mb_9}', + mb_10 = '{$mb_10}' + {$sql_password} + {$sql_nick_date} + {$sql_open_date} + {$sql_email_certify} + {$sql_certify} + where mb_id = '$mb_id' "; + sql_query($sql); +} + + +// 회원 아이콘 +$mb_dir = G5_DATA_PATH.'/member/'.substr($mb_id,0,2); + +// 아이콘 삭제 +if (isset($_POST['del_mb_icon'])) { + @unlink($mb_dir.'/'.$mb_id.'.gif'); +} + +$msg = ""; + +// 아이콘 업로드 +$mb_icon = ''; +if (isset($_FILES['mb_icon']) && is_uploaded_file($_FILES['mb_icon']['tmp_name'])) { + if (preg_match("/(\.gif)$/i", $_FILES['mb_icon']['name'])) { + // 아이콘 용량이 설정값보다 이하만 업로드 가능 + if ($_FILES['mb_icon']['size'] <= $config['cf_member_icon_size']) { + @mkdir($mb_dir, G5_DIR_PERMISSION); + @chmod($mb_dir, G5_DIR_PERMISSION); + $dest_path = $mb_dir.'/'.$mb_id.'.gif'; + move_uploaded_file($_FILES['mb_icon']['tmp_name'], $dest_path); + chmod($dest_path, G5_FILE_PERMISSION); + if (file_exists($dest_path)) { + //=================================================================\ + // 090714 + // gif 파일에 악성코드를 심어 업로드 하는 경우를 방지 + // 에러메세지는 출력하지 않는다. + //----------------------------------------------------------------- + $size = getimagesize($dest_path); + if ($size[2] != 1) // gif 파일이 아니면 올라간 이미지를 삭제한다. + @unlink($dest_path); + else + // 아이콘의 폭 또는 높이가 설정값 보다 크다면 이미 업로드 된 아이콘 삭제 + if ($size[0] > $config['cf_member_icon_width'] || $size[1] > $config['cf_member_icon_height']) + @unlink($dest_path); + //=================================================================\ + } + } else { + $msg .= '회원아이콘을 '.number_format($config['cf_member_icon_size']).'바이트 이하로 업로드 해주십시오.'; + } + + } else { + $msg .= $_FILES['mb_icon']['name'].'은(는) gif 파일이 아닙니다.'; + } +} + + +// 인증메일 발송 +if ($config['cf_use_email_certify'] && $old_email != $mb_email) { + $subject = '['.$config['cf_title'].'] 인증확인 메일입니다.'; + + // 어떠한 회원정보도 포함되지 않은 일회용 난수를 생성하여 인증에 사용 + $mb_md5 = md5(pack('V*', rand(), rand(), rand(), rand())); + + sql_query(" update {$g5['member_table']} set mb_email_certify2 = '$mb_md5' where mb_id = '$mb_id' "); + + $certify_href = G5_BBS_URL.'/email_certify.php?mb_id='.$mb_id.'&mb_md5='.$mb_md5; + + ob_start(); + include_once ('./register_form_update_mail3.php'); + $content = ob_get_contents(); + ob_end_clean(); + + mailer($config['cf_admin_email_name'], $config['cf_admin_email'], $mb_email, $subject, $content, 1); +} + + +// 사용자 코드 실행 +@include_once ($member_skin_path.'/register_form_update.tail.skin.php'); + +unset($_SESSION['ss_cert_type']); +unset($_SESSION['ss_cert_no']); +unset($_SESSION['ss_cert_hash']); +unset($_SESSION['ss_cert_birth']); +unset($_SESSION['ss_cert_adult']); + +if ($msg) + echo ''; + +if ($w == '') { + goto_url(G5_HTTP_BBS_URL.'/register_result.php'); +} else if ($w == 'u') { + $row = sql_fetch(" select mb_password from {$g5['member_table']} where mb_id = '{$member['mb_id']}' "); + $tmp_password = $row['mb_password']; + + if ($old_email != $mb_email && $config['cf_use_email_certify']) { + set_session('ss_mb_id', ''); + alert('회원 정보가 수정 되었습니다.\n\nE-mail 주소가 변경되었으므로 다시 인증하셔야 합니다.', G5_URL); + } else { + echo ' + + + + + 회원정보수정 + +
    + + + + +
    + + + '; + } +} +?> diff --git a/AvocadoEdition/bbs/register_form_update_mail1.php b/AvocadoEdition/bbs/register_form_update_mail1.php new file mode 100644 index 0000000..e2ec67c --- /dev/null +++ b/AvocadoEdition/bbs/register_form_update_mail1.php @@ -0,0 +1,39 @@ + + + + + + +회원가입 축하 메일 + + + + +
    +
    +

    + 회원가입을 축하합니다. +

    + + + +

    + 님의 회원가입을 진심으로 축하합니다.
    + 회원님의 성원에 보답하고자 더욱 더 열심히 하겠습니다.
    + 아래의 메일인증을 클릭하시면 회원가입이 완료됩니다.
    + 감사합니다. +

    + + + 메일인증 + + 사이트바로가기 + +
    +
    + + + diff --git a/AvocadoEdition/bbs/register_form_update_mail2.php b/AvocadoEdition/bbs/register_form_update_mail2.php new file mode 100644 index 0000000..f30b7b9 --- /dev/null +++ b/AvocadoEdition/bbs/register_form_update_mail2.php @@ -0,0 +1,35 @@ + + + + + + +회원가입 알림 메일 + + + + +
    +
    +

    + 회원가입 알림 메일 +

    + + + +

    + 님께서 회원가입 하셨습니다.
    + 회원 아이디 :
    + 회원 이름 :
    + 회원 닉네임 :
    + 추천인아이디 : +

    + 관리자에서 회원정보 확인하기 +
    +
    + + + diff --git a/AvocadoEdition/bbs/register_form_update_mail3.php b/AvocadoEdition/bbs/register_form_update_mail3.php new file mode 100644 index 0000000..5ae4d46 --- /dev/null +++ b/AvocadoEdition/bbs/register_form_update_mail3.php @@ -0,0 +1,39 @@ + + + + + + +회원 인증 메일 + + + + +
    +
    +

    + 회원 인증 메일입니다. +

    + + + +

    + + 님의 E-mail 주소가 변경되었습니다.

    + + + 아래의 주소를 클릭하시면 인증이 완료됩니다.
    +

    + + 회원님의 성원에 보답하고자 더욱 더 열심히 하겠습니다.
    + 감사합니다. +

    + 로그인 +
    +
    + + + diff --git a/AvocadoEdition/bbs/register_result.php b/AvocadoEdition/bbs/register_result.php new file mode 100644 index 0000000..831c986 --- /dev/null +++ b/AvocadoEdition/bbs/register_result.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/rss.php b/AvocadoEdition/bbs/rss.php new file mode 100644 index 0000000..04c9428 --- /dev/null +++ b/AvocadoEdition/bbs/rss.php @@ -0,0 +1,90 @@ +"), array("&", "<", ">"), $str); + + /* + $str = preg_replace("/&/", "&", $str); + $str = preg_replace("//", ">", $str); + */ + + return $str; +} + +$sql = " select gr_id, bo_subject, bo_page_rows, bo_read_level, bo_use_rss_view from {$g5['board_table']} where bo_table = '$bo_table' "; +$row = sql_fetch($sql); +$subj2 = specialchars_replace($row['bo_subject'], 255); +$lines = $row['bo_page_rows']; + +// 비회원 읽기가 가능한 게시판만 RSS 지원 +if ($row['bo_read_level'] >= 2) { + echo '비회원 읽기가 가능한 게시판만 RSS 지원합니다.'; + exit; +} + +// RSS 사용 체크 +if (!$row['bo_use_rss_view']) { + echo 'RSS 보기가 금지되어 있습니다.'; + exit; +} + +header('Content-type: text/xml'); +header('Cache-Control: no-cache, must-revalidate'); +header('Pragma: no-cache'); + +$sql = " select gr_subject from {$g5['group_table']} where gr_id = '{$row['gr_id']}' "; +$row = sql_fetch($sql); +$subj1 = specialchars_replace($row['gr_subject'], 255); + +echo ''."\n"; +?> + + +<?php echo specialchars_replace($config['cf_title'].' > '.$subj1.' > '.$subj2) ?> + +테스트 버전 0.2 (2004-04-26) +ko + + + + +<?php echo specialchars_replace($row['wr_subject']) ?> + +]]> + + + + + +'."\n"; +echo ''."\n"; +?> diff --git a/AvocadoEdition/bbs/scrap.php b/AvocadoEdition/bbs/scrap.php new file mode 100644 index 0000000..61ced3e --- /dev/null +++ b/AvocadoEdition/bbs/scrap.php @@ -0,0 +1,60 @@ + diff --git a/AvocadoEdition/bbs/scrap_delete.php b/AvocadoEdition/bbs/scrap_delete.php new file mode 100644 index 0000000..6d61659 --- /dev/null +++ b/AvocadoEdition/bbs/scrap_delete.php @@ -0,0 +1,11 @@ + diff --git a/AvocadoEdition/bbs/scrap_popin.php b/AvocadoEdition/bbs/scrap_popin.php new file mode 100644 index 0000000..8bb8186 --- /dev/null +++ b/AvocadoEdition/bbs/scrap_popin.php @@ -0,0 +1,60 @@ + + alert('회원만 접근 가능합니다.'); + opener.location.href = '$href2'; + window.close(); + + +HEREDOC; + exit; +} + +echo << + if (window.name != 'win_scrap') { + alert('올바른 방법으로 사용해 주십시오.'); + window.close(); + } + +HEREDOC; + +if ($write['wr_is_comment']) + alert_close('코멘트는 스크랩 할 수 없습니다.'); + +$sql = " select count(*) as cnt from {$g5['scrap_table']} + where mb_id = '{$member['mb_id']}' + and bo_table = '$bo_table' + and wr_id = '$wr_id' "; +$row = sql_fetch($sql); +if ($row['cnt']) { + echo << + if (confirm('이미 스크랩하신 글 입니다.\\n\\n지금 스크랩을 확인하시겠습니까?')) + document.location.href = './scrap.php'; + else + window.close(); + + +HEREDOC; + exit; +} + +include_once($member_skin_path.'/scrap_popin.skin.php'); + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/bbs/scrap_popin_update.php b/AvocadoEdition/bbs/scrap_popin_update.php new file mode 100644 index 0000000..5c94f90 --- /dev/null +++ b/AvocadoEdition/bbs/scrap_popin_update.php @@ -0,0 +1,110 @@ + alert(\'회원만 접근 가능합니다.\'); top.location.href = \''.str_replace('&', '&', $href).'\'; '; + exit; +} + +// 게시글 존재하는지 +if(!$write['wr_id']) + alert_close('스크랩하시려는 게시글이 존재하지 않습니다.'); + +$sql = " select count(*) as cnt from {$g5['scrap_table']} + where mb_id = '{$member['mb_id']}' + and bo_table = '$bo_table' + and wr_id = '$wr_id' "; +$row = sql_fetch($sql); +if ($row['cnt']) +{ + echo ' + + '; + exit; +} + +$wr_content = trim($_POST['wr_content']); + +// 덧글이 넘어오고 코멘트를 쓸 권한이 있다면 +if ($wr_content && ($member['mb_level'] >= $board['bo_comment_level'])) +{ + $wr = get_write($write_table, $wr_id); + // 원글이 존재한다면 + if ($wr['wr_id']) + { + $mb_id = $member['mb_id']; + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_password = $member['mb_password']; + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); + + $sql = " select max(wr_comment) as max_comment from $write_table + where wr_parent = '$wr_id' and wr_is_comment = '1' "; + $row = sql_fetch($sql); + $row['max_comment'] += 1; + + $sql = " insert into $write_table + set ca_name = '{$wr['ca_name']}', + wr_option = '', + wr_num = '{$wr['wr_num']}', + wr_reply = '', + wr_parent = '$wr_id', + wr_is_comment = '1', + wr_comment = '{$row['max_comment']}', + wr_content = '$wr_content', + mb_id = '$mb_id', + wr_password = '$wr_password', + wr_name = '$wr_name', + wr_email = '$wr_email', + wr_homepage = '$wr_homepage', + wr_datetime = '".G5_TIME_YMDHIS."', + wr_ip = '{$_SERVER['REMOTE_ADDR']}' "; + sql_query($sql); + + $comment_id = sql_insert_id(); + + // 원글에 코멘트수 증가 + sql_query(" update $write_table set wr_comment = wr_comment + 1 where wr_id = '$wr_id' "); + + // 새글 INSERT + sql_query(" insert into {$g5['board_new_table']} ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values ( '$bo_table', '$comment_id', '$wr_id', '".G5_TIME_YMDHIS."', '{$member['mb_id']}' ) "); + + // 코멘트 1 증가 + sql_query(" update {$g5['board_table']} set bo_count_comment = bo_count_comment + 1 where bo_table = '$bo_table' "); + + // 포인트 부여 + insert_point($member['mb_id'], $board['bo_comment_point'], "{$board['bo_subject']} {$wr_id}-{$comment_id} 코멘트쓰기", $bo_table, $comment_id, '코멘트'); + } +} + +$sql = " insert into {$g5['scrap_table']} ( mb_id, bo_table, wr_id, ms_datetime ) values ( '{$member['mb_id']}', '$bo_table', '$wr_id', '".G5_TIME_YMDHIS."' ) "; +sql_query($sql); + +delete_cache_latest($bo_table); + +echo << + if (confirm('이 글을 스크랩 하였습니다.\\n\\n지금 스크랩을 확인하시겠습니까?')) + document.location.href = './scrap.php'; + else + window.close(); + + +HEREDOC; +?> diff --git a/AvocadoEdition/bbs/search.php b/AvocadoEdition/bbs/search.php new file mode 100644 index 0000000..32ebf3e --- /dev/null +++ b/AvocadoEdition/bbs/search.php @@ -0,0 +1,236 @@ + '' "; + $row3 = sql_fetch($sql3); + if (!$row3['cnt']) + continue; + } + } + } + $g5_search['tables'][] = $row['bo_table']; + $g5_search['read_level'][] = $row['bo_read_level']; + } + + $search_query = 'sfl='.urlencode($sfl).'&stx='.urlencode($stx).'&sop='.$sop; + + + $text_stx = get_text(stripslashes($stx)); + + $op1 = ''; + + // 검색어를 구분자로 나눈다. 여기서는 공백 + $s = explode(' ', strip_tags($stx)); + + // 검색필드를 구분자로 나눈다. 여기서는 + + $field = explode('||', trim($sfl)); + + $str = '('; + for ($i=0; $i'.((G5_IS_MOBILE && $row2['bo_mobile_subject']) ? $row2['bo_mobile_subject'] : $row2['bo_subject']).''.$row['cnt'].''; + } + } + + $rows = $srows; + $total_page = ceil($total_count / $rows); // 전체 페이지 계산 + if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) + $from_record = ($page - 1) * $rows; // 시작 열을 구함 + + for ($i=0; $i= $rows) + break; + } + sql_free_result($result); + + if ($k >= $rows) + break; + + $from_record = 0; + } + + $write_pages = get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, $_SERVER['SCRIPT_NAME'].'?'.$search_query.'&gr_id='.$gr_id.'&srows='.$srows.'&onetable='.$onetable.'&page='); +} + +$group_select = ''; + +if (!$sfl) $sfl = 'wr_subject'; +if (!$sop) $sop = 'or'; + +include_once($search_skin_path.'/search.skin.php'); + +include_once('./_tail.php'); +?> diff --git a/AvocadoEdition/bbs/sns_send.php b/AvocadoEdition/bbs/sns_send.php new file mode 100644 index 0000000..4a4fd51 --- /dev/null +++ b/AvocadoEdition/bbs/sns_send.php @@ -0,0 +1,23 @@ + \ No newline at end of file diff --git a/AvocadoEdition/bbs/view.php b/AvocadoEdition/bbs/view.php new file mode 100644 index 0000000..1031da6 --- /dev/null +++ b/AvocadoEdition/bbs/view.php @@ -0,0 +1,142 @@ + '{$write['wr_reply']}' {$sql_search} order by wr_num, wr_reply limit 1 "; + $next = sql_fetch($sql); + // 위의 쿼리문으로 값을 얻지 못했다면 + if (!$next['wr_id']) { + $sql = " select wr_id, wr_subject from {$write_table} where wr_is_comment = 0 and wr_num > '{$write['wr_num']}' {$sql_search} order by wr_num, wr_reply limit 1 "; + $next = sql_fetch($sql); + } +} + +// 이전글 링크 +$prev_href = ''; +if (isset($prev['wr_id']) && $prev['wr_id']) { + $prev_wr_subject = get_text(cut_str($prev['wr_subject'], 255)); + $prev_href = './board.php?bo_table='.$bo_table.'&wr_id='.$prev['wr_id'].$qstr; +} + +// 다음글 링크 +$next_href = ''; +if (isset($next['wr_id']) && $next['wr_id']) { + $next_wr_subject = get_text(cut_str($next['wr_subject'], 255)); + $next_href = './board.php?bo_table='.$bo_table.'&wr_id='.$next['wr_id'].$qstr; +} + +// 쓰기 링크 +$write_href = ''; +if ($member['mb_level'] >= $board['bo_write_level']) + $write_href = './write.php?bo_table='.$bo_table; + +// 답변 링크 +$reply_href = ''; +if ($member['mb_level'] >= $board['bo_reply_level']) + $reply_href = './write.php?w=r&bo_table='.$bo_table.'&wr_id='.$wr_id.$qstr; + +// 수정, 삭제 링크 +$update_href = $delete_href = ''; +// 로그인중이고 자신의 글이라면 또는 관리자라면 비밀번호를 묻지 않고 바로 수정, 삭제 가능 +if (($member['mb_id'] && ($member['mb_id'] == $write['mb_id'])) || $is_admin) { + $update_href = './write.php?w=u&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; + set_session('ss_delete_token', $token = uniqid(time())); + $delete_href ='./delete.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&token='.$token.'&page='.$page.urldecode($qstr); +} +else if (!$write['mb_id']) { // 회원이 쓴 글이 아니라면 + $update_href = './password.php?w=u&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; + $delete_href = './password.php?w=d&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; +} + +// 최고, 그룹관리자라면 글 복사, 이동 가능 +$copy_href = $move_href = ''; +if ($write['wr_reply'] == '' && ($is_admin == 'super' || $is_admin == 'group')) { + $copy_href = './move.php?sw=copy&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; + $move_href = './move.php?sw=move&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; +} + +$scrap_href = ''; +$good_href = ''; +$nogood_href = ''; +if ($is_member) { + // 스크랩 링크 + $scrap_href = './scrap_popin.php?bo_table='.$bo_table.'&wr_id='.$wr_id; + + // 추천 링크 + if ($board['bo_use_good']) + $good_href = './good.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&good=good'; + + // 비추천 링크 + if ($board['bo_use_nogood']) + $nogood_href = './good.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&good=nogood'; +} + +$view = get_view($write, $board, $board_skin_path); + +if (strstr($sfl, 'subject')) + $view['subject'] = search_font($stx, $view['subject']); + +$html = 0; +if (strstr($view['wr_option'], 'html1')) + $html = 1; +else if (strstr($view['wr_option'], 'html2')) + $html = 2; + +$view['content'] = conv_content($view['wr_content'], $html); +if (strstr($sfl, 'content')) + $view['content'] = search_font($stx, $view['content']); + +//$view['rich_content'] = preg_replace("/{이미지\:([0-9]+)[:]?([^}]*)}/ie", "view_image(\$view, '\\1', '\\2')", $view['content']); +function conv_rich_content($matches) +{ + global $view; + return view_image($view, $matches[1], $matches[2]); +} +$view['rich_content'] = preg_replace_callback("/{이미지\:([0-9]+)[:]?([^}]*)}/i", "conv_rich_content", $view['content']); + +$is_signature = false; +$signature = ''; +if ($board['bo_use_signature'] && $view['mb_id']) { + $is_signature = true; + $mb = get_member($view['mb_id']); + $signature = $mb['mb_signature']; + + $signature = conv_content($signature, 1); +} + +include_once($board_skin_path.'/view.skin.php'); + +@include_once($board_skin_path.'/view.tail.skin.php'); +?> diff --git a/AvocadoEdition/bbs/view_comment.php b/AvocadoEdition/bbs/view_comment.php new file mode 100644 index 0000000..d0294b4 --- /dev/null +++ b/AvocadoEdition/bbs/view_comment.php @@ -0,0 +1,127 @@ += $board['bo_comment_level']) + $is_comment_write = true; + +// 코멘트 출력 +//$sql = " select * from {$write_table} where wr_parent = '{$wr_id}' and wr_is_comment = 1 order by wr_comment desc, wr_comment_reply "; +$sql = " select * from $write_table where wr_parent = '$wr_id' and wr_is_comment = 1 order by wr_comment, wr_comment_reply "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) +{ + $list[$i] = $row; + + //$list[$i]['name'] = get_sideview($row['mb_id'], cut_str($row['wr_name'], 20, ''), $row['wr_email'], $row['wr_homepage']); + + $tmp_name = get_text(cut_str($row['wr_name'], $config['cf_cut_name'])); // 설정된 자리수 만큼만 이름 출력 + if ($board['bo_use_sideview']) + $list[$i]['name'] = get_sideview($row['mb_id'], $tmp_name, $row['wr_email'], $row['wr_homepage']); + else + $list[$i]['name'] = ''.$tmp_name.''; + + + + // 공백없이 연속 입력한 문자 자르기 (way 보드 참고. way.co.kr) + //$list[$i]['content'] = eregi_replace("[^ \n<>]{130}", "\\0\n", $row['wr_content']); + + $list[$i]['content'] = $list[$i]['content1']= '비밀글 입니다.'; + if (!strstr($row['wr_option'], 'secret') || + $is_admin || + ($write['mb_id']==$member['mb_id'] && $member['mb_id']) || + ($row['mb_id']==$member['mb_id'] && $member['mb_id'])) { + $list[$i]['content1'] = $row['wr_content']; + $list[$i]['content'] = conv_content($row['wr_content'], 0, 'wr_content'); + $list[$i]['content'] = search_font($stx, $list[$i]['content']); + } else { + $ss_name = 'ss_secret_comment_'.$bo_table.'_'.$list[$i]['wr_id']; + + if(!get_session($ss_name)) + $list[$i]['content'] = '댓글내용 확인'; + else { + $list[$i]['content'] = conv_content($row['wr_content'], 0, 'wr_content'); + $list[$i]['content'] = search_font($stx, $list[$i]['content']); + } + } + + $list[$i]['datetime'] = substr($row['wr_datetime'],2,14); + + // 관리자가 아니라면 중간 IP 주소를 감춘후 보여줍니다. + $list[$i]['ip'] = $row['wr_ip']; + if (!$is_admin) + $list[$i]['ip'] = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $row['wr_ip']); + + $list[$i]['is_reply'] = false; + $list[$i]['is_edit'] = false; + $list[$i]['is_del'] = false; + if ($is_comment_write || $is_admin) + { + $token = ''; + + if ($member['mb_id']) + { + if ($row['mb_id'] == $member['mb_id'] || $is_admin) + { + set_session('ss_delete_comment_'.$row['wr_id'].'_token', $token = uniqid(time())); + $list[$i]['del_link'] = './delete_comment.php?bo_table='.$bo_table.'&comment_id='.$row['wr_id'].'&token='.$token.'&page='.$page.$qstr; + $list[$i]['is_edit'] = true; + $list[$i]['is_del'] = true; + } + } + else + { + if (!$row['mb_id']) { + $list[$i]['del_link'] = './password.php?w=x&bo_table='.$bo_table.'&comment_id='.$row['wr_id'].'&page='.$page.$qstr; + $list[$i]['is_del'] = true; + } + } + + if (strlen($row['wr_comment_reply']) < 5) + $list[$i]['is_reply'] = true; + } + + // 05.05.22 + // 답변있는 코멘트는 수정, 삭제 불가 + if ($i > 0 && !$is_admin) + { + if ($row['wr_comment_reply']) + { + $tmp_comment_reply = substr($row['wr_comment_reply'], 0, strlen($row['wr_comment_reply']) - 1); + if ($tmp_comment_reply == $list[$i-1]['wr_comment_reply']) + { + $list[$i-1]['is_edit'] = false; + $list[$i-1]['is_del'] = false; + } + } + } +} + +// 코멘트수 제한 설정값 +if ($is_admin) +{ + $comment_min = $comment_max = 0; +} +else +{ + $comment_min = (int)$board['bo_comment_min']; + $comment_max = (int)$board['bo_comment_max']; +} + +include_once($board_skin_path.'/view_comment.skin.php'); + +if (!$member['mb_id']) // 비회원일 경우에만 + echo ''."\n"; + +@include_once($board_skin_path.'/view_comment.tail.skin.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/view_image.php b/AvocadoEdition/bbs/view_image.php new file mode 100644 index 0000000..779f83a --- /dev/null +++ b/AvocadoEdition/bbs/view_image.php @@ -0,0 +1,110 @@ +'; +} else { + alert_close('파일이 존재하지 않습니다.'); +} +?> + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/bbs/visit_browscap.inc.php b/AvocadoEdition/bbs/visit_browscap.inc.php new file mode 100644 index 0000000..7bfd0db --- /dev/null +++ b/AvocadoEdition/bbs/visit_browscap.inc.php @@ -0,0 +1,21 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE)) + return; + +// Browscap 캐시 파일이 있으면 실행 +if(defined('G5_VISIT_BROWSCAP_USE') && G5_VISIT_BROWSCAP_USE && is_file(G5_DATA_PATH.'/cache/browscap_cache.php')) { + include_once(G5_PLUGIN_PATH.'/browscap/Browscap.php'); + + $browscap = new phpbrowscap\Browscap(G5_DATA_PATH.'/cache'); + $browscap->doAutoUpdate = false; + $browscap->cacheFilename = 'browscap_cache.php'; + + $info = $browscap->getBrowser($_SERVER['HTTP_USER_AGENT']); + + $vi_browser = $info->Comment; + $vi_os = $info->Platform; + $vi_device = $info->Device_Type; +} +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/visit_insert.inc.php b/AvocadoEdition/bbs/visit_insert.inc.php new file mode 100644 index 0000000..50a9bc7 --- /dev/null +++ b/AvocadoEdition/bbs/visit_insert.inc.php @@ -0,0 +1,69 @@ +=') && defined('G5_BROWSCAP_USE') && G5_BROWSCAP_USE) { + include_once(G5_BBS_PATH.'/visit_browscap.inc.php'); + } + $sql = " insert {$g5['visit_table']} ( vi_id, vi_ip, vi_date, vi_time, vi_referer, vi_agent, vi_browser, vi_os, vi_device ) values ( '{$vi_id}', '{$remote_addr}', '".G5_TIME_YMD."', '".G5_TIME_HIS."', '{$referer}', '{$user_agent}', '{$vi_browser}', '{$vi_os}', '{$vi_device}' ) "; + + $result = sql_query($sql, FALSE); + // 정상으로 INSERT 되었다면 방문자 합계에 반영 + if ($result) { + $sql = " insert {$g5['visit_sum_table']} ( vs_count, vs_date) values ( 1, '".G5_TIME_YMD."' ) "; + $result = sql_query($sql, FALSE); + + // DUPLICATE 오류가 발생한다면 이미 날짜별 행이 생성되었으므로 UPDATE 실행 + if (!$result) { + $sql = " update {$g5['visit_sum_table']} set vs_count = vs_count + 1 where vs_date = '".G5_TIME_YMD."' "; + $result = sql_query($sql); + } + + // INSERT, UPDATE 된건이 있다면 기본환경설정 테이블에 저장 + // 방문객 접속시마다 따로 쿼리를 하지 않기 위함 (엄청난 쿼리를 줄임 ^^) + + // 오늘 + $sql = " select vs_count as cnt from {$g5['visit_sum_table']} where vs_date = '".G5_TIME_YMD."' "; + $row = sql_fetch($sql); + $vi_today = $row['cnt']; + + // 어제 + $sql = " select vs_count as cnt from {$g5['visit_sum_table']} where vs_date = DATE_SUB('".G5_TIME_YMD."', INTERVAL 1 DAY) "; + $row = sql_fetch($sql); + $vi_yesterday = $row['cnt']; + + // 최대 + $sql = " select max(vs_count) as cnt from {$g5['visit_sum_table']} "; + $row = sql_fetch($sql); + $vi_max = $row['cnt']; + + // 전체 + $sql = " select sum(vs_count) as total from {$g5['visit_sum_table']} "; + $row = sql_fetch($sql); + $vi_sum = $row['total']; + + $visit = '오늘:'.$vi_today.',어제:'.$vi_yesterday.',최대:'.$vi_max.',전체:'.$vi_sum; + + // 기본설정 테이블에 방문자수를 기록한 후 + // 방문자수 테이블을 읽지 않고 출력한다. + // 쿼리의 수를 상당부분 줄임 + sql_query(" update {$g5['config_table']} set cf_visit = '{$visit}' "); + } +} +?> diff --git a/AvocadoEdition/bbs/write.php b/AvocadoEdition/bbs/write.php new file mode 100644 index 0000000..74e7662 --- /dev/null +++ b/AvocadoEdition/bbs/write.php @@ -0,0 +1,428 @@ + 0) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_write_point'] < 0 && !$is_admin) { + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 글쓰기('.number_format($board['bo_write_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 글쓰기 해 주십시오.'); + } + } + + $title_msg = '글쓰기'; +} else if ($w == 'u') { + // 김선용 1.00 : 글쓰기 권한과 수정은 별도로 처리되어야 함 + //if ($member['mb_level'] < $board['bo_write_level']) { + if($member['mb_id'] && $write['mb_id'] == $member['mb_id']) { + ; + } else if ($member['mb_level'] < $board['bo_write_level']) { + if ($member['mb_id']) { + alert('글을 수정할 권한이 없습니다.'); + } else { + alert('글을 수정할 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + } + + $len = strlen($write['wr_reply']); + if ($len < 0) $len = 0; + $reply = substr($write['wr_reply'], 0, $len); + + // 원글만 구한다. + $sql = " select count(*) as cnt from {$write_table} + where wr_reply like '{$reply}%' + and wr_id <> '{$write['wr_id']}' + and wr_num = '{$write['wr_num']}' + and wr_is_comment = 0 "; + $row = sql_fetch($sql); + if ($row['cnt'] && !$is_admin) + alert('이 글과 관련된 답변글이 존재하므로 수정 할 수 없습니다.\\n\\n답변글이 있는 원글은 수정할 수 없습니다.'); + + // 코멘트 달린 원글의 수정 여부 + $sql = " select count(*) as cnt from {$write_table} + where wr_parent = '{$wr_id}' + and mb_id <> '{$member['mb_id']}' + and wr_is_comment = 1 "; + $row = sql_fetch($sql); + if ($board['bo_count_modify'] && $row['cnt'] >= $board['bo_count_modify'] && !$is_admin) + alert('이 글과 관련된 댓글이 존재하므로 수정 할 수 없습니다.\\n\\n댓글이 '.$board['bo_count_modify'].'건 이상 달린 원글은 수정할 수 없습니다.'); + + $title_msg = '글수정'; +} else if ($w == 'r') { + if ($member['mb_level'] < $board['bo_reply_level']) { + if ($member['mb_id']) + alert('글을 답변할 권한이 없습니다.'); + else + alert('답변글을 작성할 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + $tmp_point = isset($member['mb_point']) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_write_point'] < 0 && !$is_admin) + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 글답변('.number_format($board['bo_comment_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 글답변 해 주십시오.'); + + //if (preg_match("/[^0-9]{0,1}{$wr_id}[\r]{0,1}/",$board['bo_notice'])) + if (in_array((int)$wr_id, $notice_array)) + alert('공지에는 답변 할 수 없습니다.'); + + //---------- + // 4.06.13 : 비밀글을 타인이 열람할 수 있는 오류 수정 (헐랭이, 플록님께서 알려주셨습니다.) + // 코멘트에는 원글의 답변이 불가하므로 + if ($write['wr_is_comment']) + alert('정상적인 접근이 아닙니다.'); + + // 비밀글인지를 검사 + if (strstr($write['wr_option'], 'secret')) { + if ($write['mb_id']) { + // 회원의 경우는 해당 글쓴 회원 및 관리자 + if (!($write['mb_id'] == $member['mb_id'] || $is_admin)) + alert('비밀글에는 자신 또는 관리자만 답변이 가능합니다.'); + } else { + // 비회원의 경우는 비밀글에 답변이 불가함 + if (!$is_admin) + alert('비회원의 비밀글에는 답변이 불가합니다.'); + } + } + //---------- + + // 게시글 배열 참조 + $reply_array = &$write; + + // 최대 답변은 테이블에 잡아놓은 wr_reply 사이즈만큼만 가능합니다. + if (strlen($reply_array['wr_reply']) == 10) + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 10단계 까지만 가능합니다.'); + + $reply_len = strlen($reply_array['wr_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } else { + $begin_reply_char = 'Z'; + $end_reply_char = 'A'; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } + if ($reply_array['wr_reply']) $sql .= " and wr_reply like '{$reply_array['wr_reply']}%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) + $reply_char = $begin_reply_char; + else if ($row['reply'] == $end_reply_char) // A~Z은 26 입니다. + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 26개 까지만 가능합니다.'); + else + $reply_char = chr(ord($row['reply']) + $reply_number); + + $reply = $reply_array['wr_reply'] . $reply_char; + + $title_msg = '글답변'; + + $write['wr_subject'] = 'Re: '.$write['wr_subject']; +} + +// 그룹접근 가능 +if (!empty($group['gr_use_access'])) { + if ($is_guest) { + alert("접근 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.", 'login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + if ($is_admin == 'super' || $group['gr_admin'] == $member['mb_id'] || $board['bo_admin'] == $member['mb_id']) { + ; // 통과 + } else { + // 그룹접근 + $sql = " select gr_id from {$g5['group_member_table']} where gr_id = '{$board['gr_id']}' and mb_id = '{$member['mb_id']}' "; + $row = sql_fetch($sql); + if (!$row['gr_id']) + alert('접근 권한이 없으므로 글쓰기가 불가합니다.\\n\\n궁금하신 사항은 관리자에게 문의 바랍니다.'); + } +} + +// 본인확인을 사용한다면 +if ($config['cf_cert_use'] && !$is_admin) { + // 인증된 회원만 가능 + if ($board['bo_use_cert'] != '' && $is_guest) { + alert('이 게시판은 본인확인 하신 회원님만 글쓰기가 가능합니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', 'login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + if ($board['bo_use_cert'] == 'cert' && !$member['mb_certify']) { + alert('이 게시판은 본인확인 하신 회원님만 글쓰기가 가능합니다.\\n\\n회원정보 수정에서 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'adult' && !$member['mb_adult']) { + alert('이 게시판은 본인확인으로 성인인증 된 회원님만 글쓰기가 가능합니다.\\n\\n성인인데 글쓰기가 안된다면 회원정보 수정에서 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-cert' && $member['mb_certify'] != 'hp') { + alert('이 게시판은 휴대폰 본인확인 하신 회원님만 글읽기가 가능합니다.\\n\\n회원정보 수정에서 휴대폰 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-adult' && (!$member['mb_adult'] || $member['mb_certify'] != 'hp')) { + alert('이 게시판은 휴대폰 본인확인으로 성인인증 된 회원님만 글읽기가 가능합니다.\\n\\n현재 성인인데 글읽기가 안된다면 회원정보 수정에서 휴대폰 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } +} + +// 글자수 제한 설정값 +if ($is_admin || $board['bo_use_dhtml_editor']) +{ + $write_min = $write_max = 0; +} +else +{ + $write_min = (int)$board['bo_write_min']; + $write_max = (int)$board['bo_write_max']; +} + +$g5['title'] = ((G5_IS_MOBILE && $board['bo_mobile_subject']) ? $board['bo_mobile_subject'] : $board['bo_subject']).' '.$title_msg; + +$is_notice = false; +$notice_checked = ''; +if ($is_admin && $w != 'r') { + $is_notice = true; + + if ($w == 'u') { + // 답변 수정시 공지 체크 없음 + if ($write['wr_reply']) { + $is_notice = false; + } else { + if (in_array((int)$wr_id, $notice_array)) { + $notice_checked = 'checked'; + } + } + } +} + +$is_html = false; +if ($member['mb_level'] >= $board['bo_html_level']) + $is_html = true; + +$is_secret = $board['bo_use_secret']; + +$is_mail = false; +if ($config['cf_email_use'] && $board['bo_use_email']) + $is_mail = true; + +$recv_email_checked = ''; +if ($w == '' || strstr($write['wr_option'], 'mail')) + $recv_email_checked = 'checked'; + +$is_name = false; +$is_password = false; +$is_email = false; +$is_homepage = false; +if ($is_guest || ($is_admin && $w == 'u' && $member['mb_id'] != $write['mb_id'])) { + $is_name = true; + $is_password = true; + $is_email = true; + $is_homepage = true; +} + +$is_category = false; +$category_option = ''; +if ($board['bo_use_category']) { + $ca_name = ""; + if (isset($write['ca_name'])) + $ca_name = $write['ca_name']; + $category_option = get_category_option($bo_table, $ca_name); + $is_category = true; +} + +$is_link = false; +if ($member['mb_level'] >= $board['bo_link_level']) { + $is_link = true; +} + +$is_file = false; +if ($member['mb_level'] >= $board['bo_upload_level']) { + $is_file = true; +} + +$is_file_content = false; +if ($board['bo_use_file_content']) { + $is_file_content = true; +} + +$file_count = (int)$board['bo_upload_count']; + +$name = ""; +$email = ""; +$homepage = ""; +if ($w == "" || $w == "r") { + if ($is_member) { + if (isset($write['wr_name'])) { + $name = get_text(cut_str(stripslashes($write['wr_name']),20)); + } + $email = get_email_address($member['mb_email']); + $homepage = get_text(stripslashes($member['mb_homepage'])); + } +} + +$html_checked = ""; +$html_value = ""; +$secret_checked = ""; + +if ($w == '') { + $password_required = 'required'; +} else if ($w == 'u') { + $password_required = ''; + + if (!$is_admin) { + if (!($is_member && $member['mb_id'] == $write['mb_id'])) { + if (!check_password($wr_password, $write['wr_password'])) { + alert('비밀번호가 틀립니다.'); + } + } + } + + $name = get_text(cut_str(stripslashes($write['wr_name']),20)); + $email = get_email_address($write['wr_email']); + $homepage = get_text(stripslashes($write['wr_homepage'])); + + for ($i=1; $i<=G5_LINK_COUNT; $i++) { + $write['wr_link'.$i] = get_text($write['wr_link'.$i]); + $link[$i] = $write['wr_link'.$i]; + } + + if (strstr($write['wr_option'], 'html1')) { + $html_checked = 'checked'; + $html_value = 'html1'; + } else if (strstr($write['wr_option'], 'html2')) { + $html_checked = 'checked'; + $html_value = 'html2'; + } + + if (strstr($write['wr_option'], 'secret')) { + $secret_checked = 'checked'; + } + + $file = get_file($bo_table, $wr_id); + if($file_count < $file['count']) + $file_count = $file['count']; +} else if ($w == 'r') { + if (strstr($write['wr_option'], 'secret')) { + $is_secret = true; + $secret_checked = 'checked'; + } + + $password_required = "required"; + + for ($i=1; $i<=G5_LINK_COUNT; $i++) { + $write['wr_link'.$i] = get_text($write['wr_link'.$i]); + } +} + +set_session('ss_bo_table', $_REQUEST['bo_table']); +set_session('ss_wr_id', $_REQUEST['wr_id']); + +$subject = ""; +if (isset($write['wr_subject'])) { + $subject = str_replace("\"", """, get_text(cut_str($write['wr_subject'], 255), 0)); +} + +$content = ''; +if ($w == '') { + $content = $board['bo_insert_content']; +} else if ($w == 'r') { + if (!strstr($write['wr_option'], 'html')) { + $content = "\n\n\n > " + ."\n > " + ."\n > ".str_replace("\n", "\n> ", get_text($write['wr_content'], 0)) + ."\n > " + ."\n > "; + + } +} else { + $content = get_text($write['wr_content'], 0); +} + +$upload_max_filesize = number_format($board['bo_upload_size']) . ' 바이트'; + +$width = $board['bo_table_width']; +if ($width <= 100) + $width .= '%'; +else + $width .= 'px'; + +$captcha_html = ''; +$captcha_js = ''; +if ($is_guest) { + $captcha_html = captcha_html(); + $captcha_js = chk_captcha_js(); +} + +$is_dhtml_editor = false; +$is_dhtml_editor_use = false; +$editor_content_js = ''; +if(!is_mobile() || defined('G5_IS_MOBILE_DHTML_USE') && G5_IS_MOBILE_DHTML_USE) + $is_dhtml_editor_use = true; + +// 모바일에서는 G5_IS_MOBILE_DHTML_USE 설정에 따라 DHTML 에디터 적용 +if ($config['cf_editor'] && $is_dhtml_editor_use && $board['bo_use_dhtml_editor'] && $member['mb_level'] >= $board['bo_html_level']) { + $is_dhtml_editor = true; + + if(is_file(G5_EDITOR_PATH.'/'.$config['cf_editor'].'/autosave.editor.js')) + $editor_content_js = ''.PHP_EOL; +} +$editor_html = editor_html('wr_content', $content, $is_dhtml_editor); +$editor_js = ''; +$editor_js .= get_editor_js('wr_content', $is_dhtml_editor); +$editor_js .= chk_editor_js('wr_content', $is_dhtml_editor); + +// 임시 저장된 글 수 +$autosave_count = autosave_count($member['mb_id']); + +include_once(G5_PATH.'/head.sub.php'); +@include_once ($board_skin_path.'/write.head.skin.php'); +include_once('./board_head.php'); + +$action_url = https_url(G5_BBS_DIR)."/write_update.php"; + +echo ''; +include_once ($board_skin_path.'/write.skin.php'); + +include_once('./board_tail.php'); +@include_once ($board_skin_path.'/write.tail.skin.php'); +include_once(G5_PATH.'/tail.sub.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/write_comment_update.php b/AvocadoEdition/bbs/write_comment_update.php new file mode 100644 index 0000000..880261f --- /dev/null +++ b/AvocadoEdition/bbs/write_comment_update.php @@ -0,0 +1,350 @@ + 50) { + alert('내용에 올바르지 않은 코드가 다수 포함되어 있습니다.'); + exit; +} + +@include_once($board_skin_path.'/write_comment_update.head.skin.php'); + +$w = $_POST["w"]; +$wr_name = trim($_POST['wr_name']); +$wr_email = ''; +if (!empty($_POST['wr_email'])) + $wr_email = get_email_address(trim($_POST['wr_email'])); + +// 비회원의 경우 이름이 누락되는 경우가 있음 +if ($is_guest) { + if ($wr_name == '') + alert('이름은 필히 입력하셔야 합니다.'); + if(!chk_captcha()) + alert('자동등록방지 숫자가 틀렸습니다.'); +} + +if ($w == "c" || $w == "cu") { + if ($member['mb_level'] < $board['bo_comment_level']) + alert('댓글을 쓸 권한이 없습니다.'); +} +else + alert('w 값이 제대로 넘어오지 않았습니다.'); + +// 세션의 시간 검사 +// 4.00.15 - 댓글 수정시 연속 게시물 등록 메시지로 인한 오류 수정 +if ($w == 'c' && $_SESSION['ss_datetime'] >= (G5_SERVER_TIME - $config['cf_delay_sec']) && !$is_admin) + alert('너무 빠른 시간내에 게시물을 연속해서 올릴 수 없습니다.'); + +set_session('ss_datetime', G5_SERVER_TIME); + +$wr = get_write($write_table, $wr_id); +if (empty($wr['wr_id'])) + alert("글이 존재하지 않습니다.\\n글이 삭제되었거나 이동하였을 수 있습니다."); + + +// "인터넷옵션 > 보안 > 사용자정의수준 > 스크립팅 > Action 스크립팅 > 사용 안 함" 일 경우의 오류 처리 +// 이 옵션을 사용 안 함으로 설정할 경우 어떤 스크립트도 실행 되지 않습니다. +//if (!trim($_POST["wr_content"])) die ("내용을 입력하여 주십시오."); + +if ($is_member) +{ + $mb_id = $member['mb_id']; + // 4.00.13 - 실명 사용일때 댓글에 닉네임으로 입력되던 오류를 수정 + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_password = $member['mb_password']; + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); +} +else +{ + $mb_id = ''; + $wr_password = get_encrypt_string($wr_password); +} + +if ($w == 'c') // 댓글 입력 +{ + /* + if ($member['mb_point'] + $board['bo_comment_point'] < 0 && !$is_admin) + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 댓글쓰기('.number_format($board['bo_comment_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 댓글을 써 주십시오.'); + */ + // 댓글쓰기 포인트설정시 회원의 포인트가 음수인 경우 댓글을 쓰지 못하던 버그를 수정 (곱슬최씨님) + $tmp_point = ($member['mb_point'] > 0) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_comment_point'] < 0 && !$is_admin) + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 댓글쓰기('.number_format($board['bo_comment_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 댓글을 써 주십시오.'); + + // 댓글 답변 + if ($comment_id) + { + $sql = " select wr_id, wr_parent, wr_comment, wr_comment_reply from $write_table + where wr_id = '$comment_id' "; + $reply_array = sql_fetch($sql); + if (!$reply_array['wr_id']) + alert('답변할 댓글이 없습니다.\\n\\n답변하는 동안 댓글이 삭제되었을 수 있습니다.'); + + if($wr['wr_parent'] != $reply_array['wr_parent']) + alert('댓글을 등록할 수 없습니다.'); + + $tmp_comment = $reply_array['wr_comment']; + + if (strlen($reply_array['wr_comment_reply']) == 5) + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 5단계 까지만 가능합니다.'); + + $reply_len = strlen($reply_array['wr_comment_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_comment_reply, $reply_len, 1)) as reply + from $write_table + where wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and SUBSTRING(wr_comment_reply, $reply_len, 1) <> '' "; + } + else + { + $begin_reply_char = 'Z'; + $end_reply_char = 'A'; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_comment_reply, $reply_len, 1)) as reply + from $write_table + where wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and SUBSTRING(wr_comment_reply, $reply_len, 1) <> '' "; + } + if ($reply_array['wr_comment_reply']) + $sql .= " and wr_comment_reply like '{$reply_array['wr_comment_reply']}%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) + $reply_char = $begin_reply_char; + else if ($row['reply'] == $end_reply_char) // A~Z은 26 입니다. + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 26개 까지만 가능합니다.'); + else + $reply_char = chr(ord($row['reply']) + $reply_number); + + $tmp_comment_reply = $reply_array['wr_comment_reply'] . $reply_char; + } + else + { + $sql = " select max(wr_comment) as max_comment from $write_table + where wr_parent = '$wr_id' and wr_is_comment = 1 "; + $row = sql_fetch($sql); + //$row['max_comment'] -= 1; + $row['max_comment'] += 1; + $tmp_comment = $row['max_comment']; + $tmp_comment_reply = ''; + } + + //$wr_subject = get_text(stripslashes($wr['wr_subject'])); + + $sql = " insert into $write_table + set ca_name = '{$wr['ca_name']}', + wr_option = '$wr_secret', + wr_num = '{$wr['wr_num']}', + wr_reply = '', + wr_parent = '$wr_id', + wr_is_comment = 1, + wr_comment = '$tmp_comment', + wr_comment_reply = '$tmp_comment_reply', + wr_subject = '$wr_subject', + wr_content = '$wr_content', + mb_id = '$mb_id', + wr_password = '$wr_password', + wr_name = '$wr_name', + wr_email = '$wr_email', + wr_homepage = '$wr_homepage', + wr_datetime = '".G5_TIME_YMDHIS."', + wr_last = '', + wr_ip = '{$_SERVER['REMOTE_ADDR']}', + + ch_id = '{$character['ch_id']}', + ch_side = '{$character['ch_side']}', + ch_class = '{$character['ch_class']}', + + wr_noname = '$wr_noname', + + ti_id = '{$character['ch_title']}', + + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10' "; + sql_query($sql); + + $comment_id = sql_insert_id(); + + // 원글에 댓글수 증가 & 마지막 시간 반영 + sql_query(" update $write_table set wr_comment = wr_comment + 1, wr_last = '".G5_TIME_YMDHIS."' where wr_id = '$wr_id' "); + + // 새글 INSERT + sql_query(" insert into {$g5['board_new_table']} ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values ( '$bo_table', '$comment_id', '$wr_id', '".G5_TIME_YMDHIS."', '{$member['mb_id']}' ) "); + + // 댓글 1 증가 + sql_query(" update {$g5['board_table']} set bo_count_comment = bo_count_comment + 1 where bo_table = '$bo_table' "); + + // 포인트 부여 + insert_point($member['mb_id'], $board['bo_comment_point'], "{$board['bo_subject']} {$wr_id}-{$comment_id} 댓글쓰기", $bo_table, $comment_id, '댓글'); + + // 메일발송 사용 + if ($config['cf_email_use'] && $board['bo_use_email']) + { + // 관리자의 정보를 얻고 + $super_admin = get_admin('super'); + $group_admin = get_admin('group'); + $board_admin = get_admin('board'); + + $wr_content = nl2br(get_text(stripslashes("원글\n{$wr['wr_subject']}\n\n\n댓글\n$wr_content"))); + + $warr = array( ''=>'입력', 'u'=>'수정', 'r'=>'답변', 'c'=>'댓글 ', 'cu'=>'댓글 수정' ); + $str = $warr[$w]; + + $subject = '['.$config['cf_title'].'] '.$board['bo_subject'].' 게시판에 '.$str.'글이 올라왔습니다.'; + // 4.00.15 - 메일로 보내는 댓글의 바로가기 링크 수정 + $link_url = G5_BBS_URL."/board.php?bo_table=".$bo_table."&wr_id=".$wr_id."&".$qstr."#c_".$comment_id; + + include_once(G5_LIB_PATH.'/mailer.lib.php'); + + ob_start(); + include_once ('./write_update_mail.php'); + $content = ob_get_contents(); + ob_end_clean(); + + $array_email = array(); + // 게시판관리자에게 보내는 메일 + if ($config['cf_email_wr_board_admin']) $array_email[] = $board_admin['mb_email']; + // 게시판그룹관리자에게 보내는 메일 + if ($config['cf_email_wr_group_admin']) $array_email[] = $group_admin['mb_email']; + // 최고관리자에게 보내는 메일 + if ($config['cf_email_wr_super_admin']) $array_email[] = $super_admin['mb_email']; + + // 원글게시자에게 보내는 메일 + if ($config['cf_email_wr_write']) $array_email[] = $wr['wr_email']; + + // 댓글 쓴 모든이에게 메일 발송이 되어 있다면 (자신에게는 발송하지 않는다) + if ($config['cf_email_wr_comment_all']) { + $sql = " select distinct wr_email from {$write_table} + where wr_email not in ( '{$wr['wr_email']}', '{$member['mb_email']}', '' ) + and wr_parent = '$wr_id' "; + $result = sql_query($sql); + while ($row=sql_fetch_array($result)) + $array_email[] = $row['wr_email']; + } + + // 중복된 메일 주소는 제거 + $unique_email = array_unique($array_email); + $unique_email = array_values($unique_email); + for ($i=0; $i= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert('그룹관리자의 권한보다 높은 회원의 댓글이므로 수정할 수 없습니다.'); + } else + alert('자신이 관리하는 그룹의 게시판이 아니므로 댓글을 수정할 수 없습니다.'); + } else if ($is_admin == 'board') { // 게시판관리자이면 + $mb = get_member($comment['mb_id']); + if ($member['mb_id'] == $board['bo_admin']) { // 자신이 관리하는 게시판인가? + if ($member['mb_level'] >= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert('게시판관리자의 권한보다 높은 회원의 댓글이므로 수정할 수 없습니다.'); + } else + alert('자신이 관리하는 게시판이 아니므로 댓글을 수정할 수 없습니다.'); + } else if ($member['mb_id']) { + if ($member['mb_id'] != $comment['mb_id']) + alert('자신의 글이 아니므로 수정할 수 없습니다.'); + } else { + if($comment['wr_password'] != $wr_password) + alert('댓글을 수정할 권한이 없습니다.'); + } + + $sql = " select count(*) as cnt from $write_table + where wr_comment_reply like '$comment_reply%' + and wr_id <> '$comment_id' + and wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and wr_is_comment = 1 "; + $row = sql_fetch($sql); + if ($row['cnt'] && !$is_admin) + alert('이 댓글와 관련된 답변댓글이 존재하므로 수정 할 수 없습니다.'); + + $sql_ip = ""; + if (!$is_admin) + $sql_ip = " , wr_ip = '{$_SERVER['REMOTE_ADDR']}' "; + + $sql_secret = ""; + if ($wr_secret) + $sql_secret = " , wr_option = '$wr_secret' "; + + $sql = " update $write_table + set wr_subject = '$wr_subject', + wr_content = '$wr_content', + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10', + wr_option = '$wr_option' + $sql_ip + $sql_secret + where wr_id = '$comment_id' "; + sql_query($sql); +} + +// 사용자 코드 실행 +@include_once($board_skin_path.'/write_comment_update.skin.php'); +@include_once($board_skin_path.'/write_comment_update.tail.skin.php'); + +delete_cache_latest($bo_table); + +goto_url('./board.php?bo_table='.$bo_table.'&wr_id='.$wr['wr_parent'].'&'.$qstr.'&#c_'.$comment_id); +?> diff --git a/AvocadoEdition/bbs/write_comment_update.sns.php b/AvocadoEdition/bbs/write_comment_update.sns.php new file mode 100644 index 0000000..e991e60 --- /dev/null +++ b/AvocadoEdition/bbs/write_comment_update.sns.php @@ -0,0 +1,72 @@ + $config['cf_facebook_appid'], + 'secret' => $config['cf_facebook_secret'] + )); + + $user = $facebook->getUser(); + + if ($user) { + try { + $link = G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr['wr_parent'].'&#c_'.$comment_id; + $attachment = array( + 'message' => stripslashes($wr_content), + 'name' => $wr_subject, + 'link' => $link, + 'description' => stripslashes(strip_tags($wr['wr_content'])) + ); + // 등록 + $facebook->api('/me/feed/', 'post', $attachment); + //$errors = error_get_last(); print_r2($errros); exit; + + set_cookie('ck_facebook_checked', true, 86400*31); + } catch(FacebookApiException $e) { + ;;; + } + } + + $wr_facebook_user = get_session("ss_facebook_user"); +} +//============================================================================ + + +//============================================================================ +// 트위터 +//---------------------------------------------------------------------------- +$wr_twitter_user = ""; +if ($_POST['twitter_checked']) { + include_once(G5_SNS_PATH."/twitter/twitteroauth/twitteroauth.php"); + include_once(G5_SNS_PATH."/twitter/twitterconfig.php"); + + if ( !(empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) ) { + $comment_url = G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr['wr_parent'].'&#c_'.$comment_id; + + $post = googl_short_url($comment_url).' '.$wr_content; + $post = utf8_strcut($post, 140); + + $access_token = $_SESSION['access_token']; + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); + // 등록 + $connection->post('statuses/update', array('status' => $post)); + + set_cookie('ck_twitter_checked', true, 86400*31); + } + + $wr_twitter_user = get_session("ss_twitter_user"); +} +//============================================================================ +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/write_token.php b/AvocadoEdition/bbs/write_token.php new file mode 100644 index 0000000..e8578ef --- /dev/null +++ b/AvocadoEdition/bbs/write_token.php @@ -0,0 +1,13 @@ +'게시판 정보가 올바르지 않습니다.', 'url'=>G5_URL))); + +set_session('ss_write_'.$bo_table.'_token', ''); + +$token = get_write_token($bo_table); + +die(json_encode(array('error'=>'', 'token'=>$token, 'url'=>''))); +?> \ No newline at end of file diff --git a/AvocadoEdition/bbs/write_update.php b/AvocadoEdition/bbs/write_update.php new file mode 100644 index 0000000..30f6674 --- /dev/null +++ b/AvocadoEdition/bbs/write_update.php @@ -0,0 +1,729 @@ +분류를 선택하세요.'; + } else { + $categories = array_map('trim', explode("|", $board['bo_category_list'].($is_admin ? '|공지' : ''))); + if(!empty($categories) && !in_array($ca_name, $categories)) + $msg[] = '분류를 올바르게 입력하세요.'; + + if(empty($categories)) + $ca_name = ''; + } +} else { + $ca_name = ''; +} + +$wr_subject = ''; +if (isset($_POST['wr_subject'])) { + $wr_subject = substr(trim($_POST['wr_subject']),0,255); + $wr_subject = preg_replace("#[\\\]+$#", "", $wr_subject); +} +if ($wr_subject == '') { + $msg[] = '제목을 입력하세요.'; +} + +$wr_content = ''; +if (isset($_POST['wr_content'])) { + $wr_content = substr(trim($_POST['wr_content']),0,65536); + $wr_content = preg_replace("#[\\\]+$#", "", $wr_content); +} +/*if ($wr_content == '') { + $msg[] = '내용을 입력하세요.'; +}*/ + +$wr_link1 = ''; +if (isset($_POST['wr_link1'])) { + $wr_link1 = substr($_POST['wr_link1'],0,1000); + $wr_link1 = trim(strip_tags($wr_link1)); + $wr_link1 = preg_replace("#[\\\]+$#", "", $wr_link1); +} + +$wr_link2 = ''; +if (isset($_POST['wr_link2'])) { + $wr_link2 = substr($_POST['wr_link2'],0,1000); + $wr_link2 = trim(strip_tags($wr_link2)); + $wr_link2 = preg_replace("#[\\\]+$#", "", $wr_link2); +} + +$msg = implode('
    ', $msg); +if ($msg) { + alert($msg); +} + +// 090710 +if (substr_count($wr_content, '&#') > 50) { + alert('내용에 올바르지 않은 코드가 다수 포함되어 있습니다.'); + exit; +} + +$upload_max_filesize = ini_get('upload_max_filesize'); + +if (empty($_POST)) { + alert("파일 또는 글내용의 크기가 서버에서 설정한 값을 넘어 오류가 발생하였습니다.\\npost_max_size=".ini_get('post_max_size')." , upload_max_filesize=".$upload_max_filesize."\\n게시판관리자 또는 서버관리자에게 문의 바랍니다."); +} + +$notice_array = explode(",", $board['bo_notice']); + +if ($w == 'u' || $w == 'r') { + $wr = get_write($write_table, $wr_id); + if (!$wr['wr_id']) { + alert("글이 존재하지 않습니다.\\n글이 삭제되었거나 이동하였을 수 있습니다."); + } +} + +// 외부에서 글을 등록할 수 있는 버그가 존재하므로 비밀글은 사용일 경우에만 가능해야 함 +if (!$is_admin && !$board['bo_use_secret'] && (stripos($_POST['html'], 'secret') !== false || stripos($_POST['secret'], 'secret') !== false || stripos($_POST['mail'], 'secret') !== false)) { + alert('비밀글 미사용 게시판 이므로 비밀글로 등록할 수 없습니다.'); +} + +$secret = ''; +if (isset($_POST['secret']) && $_POST['secret']) { + if(preg_match('#secret#', strtolower($_POST['secret']), $matches)) + $secret = $matches[0]; +} + +// 외부에서 글을 등록할 수 있는 버그가 존재하므로 비밀글 무조건 사용일때는 관리자를 제외(공지)하고 무조건 비밀글로 등록 +if (!$is_admin && $board['bo_use_secret'] == 2) { + $secret = 'secret'; +} + +$html = ''; +if (isset($_POST['html']) && $_POST['html']) { + if(preg_match('#html(1|2)#', strtolower($_POST['html']), $matches)) + $html = $matches[0]; +} + +$mail = ''; +if (isset($_POST['mail']) && $_POST['mail']) { + if(preg_match('#mail#', strtolower($_POST['mail']), $matches)) + $mail = $matches[0]; +} + +$notice = ''; +if (isset($_POST['notice']) && $_POST['notice']) { + $notice = $_POST['notice']; +} + +for ($i=1; $i<=10; $i++) { + $var = "wr_$i"; + $$var = ""; + if (isset($_POST['wr_'.$i]) && settype($_POST['wr_'.$i], 'string')) { + $$var = trim($_POST['wr_'.$i]); + } +} + +@include_once($board_skin_path.'/write_update.head.skin.php'); + +if ($w == '' || $w == 'u') { + + // 김선용 1.00 : 글쓰기 권한과 수정은 별도로 처리되어야 함 + if($w =='u' && $member['mb_id'] && $wr['mb_id'] == $member['mb_id']) { + ; + } else if ($member['mb_level'] < $board['bo_write_level']) { + alert('글을 쓸 권한이 없습니다.'); + } + + // 외부에서 글을 등록할 수 있는 버그가 존재하므로 공지는 관리자만 등록이 가능해야 함 + if (!$is_admin && $notice) { + alert('관리자만 공지할 수 있습니다.'); + } + +} else if ($w == 'r') { + + if (in_array((int)$wr_id, $notice_array)) { + alert('공지에는 답변 할 수 없습니다.'); + } + + if ($member['mb_level'] < $board['bo_reply_level']) { + alert('글을 답변할 권한이 없습니다.'); + } + + // 게시글 배열 참조 + $reply_array = &$wr; + + // 최대 답변은 테이블에 잡아놓은 wr_reply 사이즈만큼만 가능합니다. + if (strlen($reply_array['wr_reply']) == 10) { + alert("더 이상 답변하실 수 없습니다.\\n답변은 10단계 까지만 가능합니다."); + } + + $reply_len = strlen($reply_array['wr_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_reply, $reply_len, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } else { + $begin_reply_char = 'Z'; + $end_reply_char = 'A'; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } + if ($reply_array['wr_reply']) $sql .= " and wr_reply like '{$reply_array['wr_reply']}%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) { + $reply_char = $begin_reply_char; + } else if ($row['reply'] == $end_reply_char) { // A~Z은 26 입니다. + alert("더 이상 답변하실 수 없습니다.\\n답변은 26개 까지만 가능합니다."); + } else { + $reply_char = chr(ord($row['reply']) + $reply_number); + } + + $reply = $reply_array['wr_reply'] . $reply_char; + +} else { + alert('w 값이 제대로 넘어오지 않았습니다.'); +} + +if ($is_guest && !chk_captcha()) { + alert('자동등록방지 숫자가 틀렸습니다.'); +} + +if ($w == '' || $w == 'r') { + if (isset($_SESSION['ss_datetime'])) { + if ($_SESSION['ss_datetime'] >= (G5_SERVER_TIME - $config['cf_delay_sec']) && !$is_admin) + alert('너무 빠른 시간내에 게시물을 연속해서 올릴 수 없습니다.'); + } + + set_session("ss_datetime", G5_SERVER_TIME); +} + +if (!isset($_POST['wr_subject']) || !trim($_POST['wr_subject'])) + alert('제목을 입력하여 주십시오.'); + +if ($w == '' || $w == 'r') { + + if ($member['mb_id']) { + $mb_id = $member['mb_id']; + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_password = $member['mb_password']; + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); + } else { + $mb_id = ''; + // 비회원의 경우 이름이 누락되는 경우가 있음 + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + if (!$wr_name) + alert('이름은 필히 입력하셔야 합니다.'); + $wr_password = get_encrypt_string($wr_password); + $wr_email = get_email_address(trim($_POST['wr_email'])); + $wr_homepage = clean_xss_tags($wr_homepage); + } + + if ($w == 'r') { + // 답변의 원글이 비밀글이라면 비밀번호는 원글과 동일하게 넣는다. + if ($secret) + $wr_password = $wr['wr_password']; + + $wr_id = $wr_id . $reply; + $wr_num = $write['wr_num']; + $wr_reply = $reply; + } else { + $wr_num = get_next_num($write_table); + $wr_reply = ''; + } + + $sql = " insert into $write_table + set wr_num = '$wr_num', + wr_reply = '$wr_reply', + wr_comment = 0, + ca_name = '$ca_name', + wr_option = '$html,$secret,$mail', + wr_subject = '$wr_subject', + wr_content = '$wr_content', + wr_link1 = '$wr_link1', + wr_link2 = '$wr_link2', + wr_link1_hit = 0, + wr_link2_hit = 0, + wr_hit = 0, + wr_good = 0, + wr_nogood = 0, + mb_id = '{$member['mb_id']}', + wr_password = '$wr_password', + wr_name = '$wr_name', + wr_email = '$wr_email', + wr_homepage = '$wr_homepage', + wr_datetime = '".G5_TIME_YMDHIS."', + wr_last = '".G5_TIME_YMDHIS."', + wr_ip = '{$_SERVER['REMOTE_ADDR']}', + + ch_id = '{$character['ch_id']}', + ch_side = '{$character['ch_side']}', + ch_class = '{$character['ch_class']}', + ti_id = '{$character['ch_title']}', + wr_width = '$wr_width', + wr_height = '$wr_height', + wr_url = '$wr_url', + wr_type = '$wr_type', + + wr_secret = '$wr_secret', + wr_adult = '$wr_adult', + wr_wide = '$wr_wide', + wr_plip = '$wr_plip', + + wr_noname = '$wr_noname', + + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10' "; + sql_query($sql); + + $wr_id = sql_insert_id(); + + // 부모 아이디에 UPDATE + sql_query(" update $write_table set wr_parent = '$wr_id' where wr_id = '$wr_id' "); + + // 새글 INSERT + sql_query(" insert into {$g5['board_new_table']} ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values ( '{$bo_table}', '{$wr_id}', '{$wr_id}', '".G5_TIME_YMDHIS."', '{$member['mb_id']}' ) "); + + // 게시글 1 증가 + sql_query("update {$g5['board_table']} set bo_count_write = bo_count_write + 1 where bo_table = '{$bo_table}'"); + + // 쓰기 포인트 부여 + if ($w == '') { + if ($notice) { + $bo_notice = $wr_id.($board['bo_notice'] ? ",".$board['bo_notice'] : ''); + sql_query(" update {$g5['board_table']} set bo_notice = '{$bo_notice}' where bo_table = '{$bo_table}' "); + } + + insert_point($member['mb_id'], $board['bo_write_point'], "{$board['bo_subject']} {$wr_id} 글쓰기", $bo_table, $wr_id, '쓰기'); + } else { + // 답변은 코멘트 포인트를 부여함 + // 답변 포인트가 많은 경우 코멘트 대신 답변을 하는 경우가 많음 + insert_point($member['mb_id'], $board['bo_comment_point'], "{$board['bo_subject']} {$wr_id} 글답변", $bo_table, $wr_id, '쓰기'); + } +} else if ($w == 'u') { + if (get_session('ss_bo_table') != $_POST['bo_table'] || get_session('ss_wr_id') != $_POST['wr_id']) { + //alert('올바른 방법으로 수정하여 주십시오.', G5_BBS_URL.'/board.php?bo_table='.$bo_table); + } + + $return_url = './board.php?bo_table='.$bo_table.'&wr_id='.$wr_id; + + if ($is_admin == 'super') // 최고관리자 통과 + ; + else if ($is_admin == 'group') { // 그룹관리자 + $mb = get_member($write['mb_id']); + if ($member['mb_id'] != $group['gr_admin']) // 자신이 관리하는 그룹인가? + alert('자신이 관리하는 그룹의 게시판이 아니므로 수정할 수 없습니다.', $return_url); + else if ($member['mb_level'] < $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + alert('자신의 권한보다 높은 권한의 회원이 작성한 글은 수정할 수 없습니다.', $return_url); + } else if ($is_admin == 'board') { // 게시판관리자이면 + $mb = get_member($write['mb_id']); + if ($member['mb_id'] != $board['bo_admin']) // 자신이 관리하는 게시판인가? + alert('자신이 관리하는 게시판이 아니므로 수정할 수 없습니다.', $return_url); + else if ($member['mb_level'] < $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + alert('자신의 권한보다 높은 권한의 회원이 작성한 글은 수정할 수 없습니다.', $return_url); + } else if ($member['mb_id']) { + if ($member['mb_id'] != $write['mb_id']) + alert('자신의 글이 아니므로 수정할 수 없습니다.', $return_url); + } else { + if ($write['mb_id']) + alert('로그인 후 수정하세요.', './login.php?url='.urlencode($return_url)); + } + + if ($member['mb_id']) { + // 자신의 글이라면 + if ($member['mb_id'] == $wr['mb_id']) { + $mb_id = $member['mb_id']; + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); + } else { + $mb_id = $wr['mb_id']; + if(isset($_POST['wr_name']) && $_POST['wr_name']) + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + else + $wr_name = addslashes(clean_xss_tags($wr['wr_name'])); + if(isset($_POST['wr_email']) && $_POST['wr_email']) + $wr_email = get_email_address(trim($_POST['wr_email'])); + else + $wr_email = addslashes($wr['wr_email']); + if(isset($_POST['wr_homepage']) && $_POST['wr_homepage']) + $wr_homepage = addslashes(clean_xss_tags($_POST['wr_homepage'])); + else + $wr_homepage = addslashes(clean_xss_tags($wr['wr_homepage'])); + } + } else { + $mb_id = ""; + // 비회원의 경우 이름이 누락되는 경우가 있음 + if (!trim($wr_name)) alert("이름은 필히 입력하셔야 합니다."); + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + $wr_email = get_email_address(trim($_POST['wr_email'])); + } + + $sql_password = $wr_password ? " , wr_password = '".get_encrypt_string($wr_password)."' " : ""; + + $sql_ip = ''; + if (!$is_admin) + $sql_ip = " , wr_ip = '{$_SERVER['REMOTE_ADDR']}' "; + + $sql = " update {$write_table} + set ca_name = '{$ca_name}', + wr_option = '{$html},{$secret},{$mail}', + wr_subject = '{$wr_subject}', + wr_content = '{$wr_content}', + wr_link1 = '{$wr_link1}', + wr_link2 = '{$wr_link2}', + mb_id = '{$mb_id}', + wr_name = '{$wr_name}', + wr_email = '{$wr_email}', + wr_homepage = '{$wr_homepage}', + + wr_width = '$wr_width', + wr_height = '$wr_height', + wr_url = '$wr_url', + wr_type = '$wr_type', + + wr_secret = '$wr_secret', + wr_adult = '$wr_adult', + wr_wide = '$wr_wide', + wr_plip = '$wr_plip', + + wr_noname = '$wr_noname', + + wr_1 = '{$wr_1}', + wr_2 = '{$wr_2}', + wr_3 = '{$wr_3}', + wr_4 = '{$wr_4}', + wr_5 = '{$wr_5}', + wr_6 = '{$wr_6}', + wr_7 = '{$wr_7}', + wr_8 = '{$wr_8}', + wr_9 = '{$wr_9}', + wr_10= '{$wr_10}' + {$sql_ip} + {$sql_password} + where wr_id = '{$wr['wr_id']}' "; + sql_query($sql); + + // 분류가 수정되는 경우 해당되는 코멘트의 분류명도 모두 수정함 + // 코멘트의 분류를 수정하지 않으면 검색이 제대로 되지 않음 + $sql = " update {$write_table} set ca_name = '{$ca_name}' where wr_parent = '{$wr['wr_id']}' "; + sql_query($sql); + + /* + if ($notice) { + //if (!preg_match("/[^0-9]{0,1}{$wr_id}[\r]{0,1}/",$board['bo_notice'])) + if (!in_array((int)$wr_id, $notice_array)) { + $bo_notice = $wr_id . ',' . $board['bo_notice']; + sql_query(" update {$g5['board_table']} set bo_notice = '{$bo_notice}' where bo_table = '{$bo_table}' "); + } + } else { + $bo_notice = ''; + for ($i=0; $i $board['bo_upload_count']) + alert('기존 파일을 삭제하신 후 첨부파일을 '.number_format($board['bo_upload_count']).'개 이하로 업로드 해주십시오.'); +} else { + if($file_count > $board['bo_upload_count']) + alert('첨부파일을 '.number_format($board['bo_upload_count']).'개 이하로 업로드 해주십시오.'); +} + +// 디렉토리가 없다면 생성합니다. (퍼미션도 변경하구요.) +@mkdir(G5_DATA_PATH.'/file/'.$bo_table, G5_DIR_PERMISSION); +@chmod(G5_DATA_PATH.'/file/'.$bo_table, G5_DIR_PERMISSION); + +$chars_array = array_merge(range(0,9), range('a','z'), range('A','Z')); + +// 가변 파일 업로드 +$file_upload_msg = ''; +$upload = array(); +for ($i=0; $i $board['bo_upload_size']) { + $file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($board['bo_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n'; + continue; + } + + //=================================================================\ + // 090714 + // 이미지나 플래시 파일에 악성코드를 심어 업로드 하는 경우를 방지 + // 에러메세지는 출력하지 않는다. + //----------------------------------------------------------------- + $timg = @getimagesize($tmp_file); + // image type + if ( preg_match("/\.({$config['cf_image_extension']})$/i", $filename) || + preg_match("/\.({$config['cf_flash_extension']})$/i", $filename) ) { + if ($timg['2'] < 1 || $timg['2'] > 16) + continue; + } + //================================================================= + + $upload[$i]['image'] = $timg; + + // 4.00.11 - 글답변에서 파일 업로드시 원글의 파일이 삭제되는 오류를 수정 + if ($w == 'u') { + // 존재하는 파일이 있다면 삭제합니다. + $row = sql_fetch(" select bf_file from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' and bf_no = '$i' "); + @unlink(G5_DATA_PATH.'/file/'.$bo_table.'/'.$row['bf_file']); + // 이미지파일이면 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $row['bf_file'])) { + delete_board_thumbnail($bo_table, $row['bf_file']); + } + } + + // 프로그램 원래 파일명 + $upload[$i]['source'] = $filename; + $upload[$i]['filesize'] = $filesize; + + // 아래의 문자열이 들어간 파일은 -x 를 붙여서 웹경로를 알더라도 실행을 하지 못하도록 함 + $filename = preg_replace("/\.(php|phtm|htm|cgi|pl|exe|jsp|asp|inc)/i", "$0-x", $filename); + + shuffle($chars_array); + $shuffle = implode('', $chars_array); + + // 첨부파일 첨부시 첨부파일명에 공백이 포함되어 있으면 일부 PC에서 보이지 않거나 다운로드 되지 않는 현상이 있습니다. (길상여의 님 090925) + $upload[$i]['file'] = abs(ip2long($_SERVER['REMOTE_ADDR'])).'_'.substr($shuffle,0,8).'_'.replace_filename($filename); + + $dest_file = G5_DATA_PATH.'/file/'.$bo_table.'/'.$upload[$i]['file']; + + // 업로드가 안된다면 에러메세지 출력하고 죽어버립니다. + $error_code = move_uploaded_file($tmp_file, $dest_file) or die($_FILES['bf_file']['error'][$i]); + + // 올라간 파일의 퍼미션을 변경합니다. + chmod($dest_file, G5_FILE_PERMISSION); + } +} + +// 나중에 테이블에 저장하는 이유는 $wr_id 값을 저장해야 하기 때문입니다. +for ($i=0; $i=0; $i--) +{ + $row2 = sql_fetch(" select bf_file from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' and bf_no = '{$i}' "); + + // 정보가 있다면 빠집니다. + if ($row2['bf_file']) break; + + // 그렇지 않다면 정보를 삭제합니다. + sql_query(" delete from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' and bf_no = '{$i}' "); +} + +// 파일의 개수를 게시물에 업데이트 한다. +$row = sql_fetch(" select count(*) as cnt from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' "); +sql_query(" update {$write_table} set wr_file = '{$row['cnt']}' where wr_id = '{$wr_id}' "); + +// 자동저장된 레코드를 삭제한다. +sql_query(" delete from {$g5['autosave_table']} where as_uid = '{$uid}' "); +//------------------------------------------------------------------------------ + +// 비밀글이라면 세션에 비밀글의 아이디를 저장한다. 자신의 글은 다시 비밀번호를 묻지 않기 위함 +if ($secret) + set_session("ss_secret_{$bo_table}_{$wr_num}", TRUE); + +// 메일발송 사용 (수정글은 발송하지 않음) +if (!($w == 'u' || $w == 'cu') && $config['cf_email_use'] && $board['bo_use_email']) { + + // 관리자의 정보를 얻고 + $super_admin = get_admin('super'); + $group_admin = get_admin('group'); + $board_admin = get_admin('board'); + + $wr_subject = get_text(stripslashes($wr_subject)); + + $tmp_html = 0; + if (strstr($html, 'html1')) + $tmp_html = 1; + else if (strstr($html, 'html2')) + $tmp_html = 2; + + $wr_content = conv_content(conv_unescape_nl(stripslashes($wr_content)), $tmp_html); + + $warr = array( ''=>'입력', 'u'=>'수정', 'r'=>'답변', 'c'=>'코멘트', 'cu'=>'코멘트 수정' ); + $str = $warr[$w]; + + $subject = '['.$config['cf_title'].'] '.$board['bo_subject'].' 게시판에 '.$str.'글이 올라왔습니다.'; + + $link_url = G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&'.$qstr; + + include_once(G5_LIB_PATH.'/mailer.lib.php'); + + ob_start(); + include_once ('./write_update_mail.php'); + $content = ob_get_contents(); + ob_end_clean(); + + $array_email = array(); + // 게시판관리자에게 보내는 메일 + if ($config['cf_email_wr_board_admin']) $array_email[] = $board_admin['mb_email']; + // 게시판그룹관리자에게 보내는 메일 + if ($config['cf_email_wr_group_admin']) $array_email[] = $group_admin['mb_email']; + // 최고관리자에게 보내는 메일 + if ($config['cf_email_wr_super_admin']) $array_email[] = $super_admin['mb_email']; + + // 원글게시자에게 보내는 메일 + if ($config['cf_email_wr_write']) { + if($w == '') + $wr['wr_email'] = $wr_email; + + $array_email[] = $wr['wr_email']; + } + + // 옵션에 메일받기가 체크되어 있고, 게시자의 메일이 있다면 + if (strstr($wr['wr_option'], 'mail') && $wr['wr_email']) + $array_email[] = $wr['wr_email']; + + // 중복된 메일 주소는 제거 + $unique_email = array_unique($array_email); + $unique_email = array_values($unique_email); + for ($i=0; $i', $msg); +if ($msg) { + alert($msg); +} + +// 090710 +if (substr_count($wr_content, '&#') > 50) { + alert('내용에 올바르지 않은 코드가 다수 포함되어 있습니다.'); + exit; +} + +$upload_max_filesize = ini_get('upload_max_filesize'); + +if (empty($_POST)) { + alert("파일 또는 글내용의 크기가 서버에서 설정한 값을 넘어 오류가 발생하였습니다.\\npost_max_size=".ini_get('post_max_size')." , upload_max_filesize=".$upload_max_filesize."\\n게시판관리자 또는 서버관리자에게 문의 바랍니다."); +} + +$notice_array = explode(",", $board['bo_notice']); + +if ($w == 'u' || $w == 'r') { + $wr = get_write($write_table, $wr_id); + if (!$wr['wr_id']) { + alert("글이 존재하지 않습니다.\\n글이 삭제되었거나 이동하였을 수 있습니다."); + } +} + +// 외부에서 글을 등록할 수 있는 버그가 존재하므로 비밀글은 사용일 경우에만 가능해야 함 +if (!$is_admin && !$board['bo_use_secret'] && (stripos($_POST['html'], 'secret') !== false || stripos($_POST['secret'], 'secret') !== false || stripos($_POST['mail'], 'secret') !== false)) { + alert('비밀글 미사용 게시판 이므로 비밀글로 등록할 수 없습니다.'); +} + +$secret = ''; +if (isset($_POST['secret']) && $_POST['secret']) { + if(preg_match('#secret#', strtolower($_POST['secret']), $matches)) + $secret = $matches[0]; +} + +// 외부에서 글을 등록할 수 있는 버그가 존재하므로 비밀글 무조건 사용일때는 관리자를 제외(공지)하고 무조건 비밀글로 등록 +if (!$is_admin && $board['bo_use_secret'] == 2) { + $secret = 'secret'; +} + +$html = ''; +if (isset($_POST['html']) && $_POST['html']) { + if(preg_match('#html(1|2)#', strtolower($_POST['html']), $matches)) + $html = $matches[0]; +} + +$mail = ''; +if (isset($_POST['mail']) && $_POST['mail']) { + if(preg_match('#mail#', strtolower($_POST['mail']), $matches)) + $mail = $matches[0]; +} + +$notice = ''; +if (isset($_POST['notice']) && $_POST['notice']) { + $notice = $_POST['notice']; +} + +for ($i=1; $i<=10; $i++) { + $var = "wr_$i"; + $$var = ""; + if (isset($_POST['wr_'.$i]) && settype($_POST['wr_'.$i], 'string')) { + $$var = trim($_POST['wr_'.$i]); + } +} + +@include_once($board_skin_path.'/write_update.head.skin.php'); + +if ($w == '' || $w == 'u') { + + // 김선용 1.00 : 글쓰기 권한과 수정은 별도로 처리되어야 함 + if($w =='u' && $member['mb_id'] && $wr['mb_id'] == $member['mb_id']) { + ; + } else if ($member['mb_level'] < $board['bo_write_level']) { + alert('글을 쓸 권한이 없습니다.'); + } + + // 외부에서 글을 등록할 수 있는 버그가 존재하므로 공지는 관리자만 등록이 가능해야 함 + if (!$is_admin && $notice) { + alert('관리자만 공지할 수 있습니다.'); + } + +} else if ($w == 'r') { + + if (in_array((int)$wr_id, $notice_array)) { + alert('공지에는 답변 할 수 없습니다.'); + } + + if ($member['mb_level'] < $board['bo_reply_level']) { + alert('글을 답변할 권한이 없습니다.'); + } + + // 게시글 배열 참조 + $reply_array = &$wr; + + // 최대 답변은 테이블에 잡아놓은 wr_reply 사이즈만큼만 가능합니다. + if (strlen($reply_array['wr_reply']) == 10) { + alert("더 이상 답변하실 수 없습니다.\\n답변은 10단계 까지만 가능합니다."); + } + + $reply_len = strlen($reply_array['wr_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_reply, $reply_len, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } else { + $begin_reply_char = 'Z'; + $end_reply_char = 'A'; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } + if ($reply_array['wr_reply']) $sql .= " and wr_reply like '{$reply_array['wr_reply']}%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) { + $reply_char = $begin_reply_char; + } else if ($row['reply'] == $end_reply_char) { // A~Z은 26 입니다. + alert("더 이상 답변하실 수 없습니다.\\n답변은 26개 까지만 가능합니다."); + } else { + $reply_char = chr(ord($row['reply']) + $reply_number); + } + + $reply = $reply_array['wr_reply'] . $reply_char; + +} else { + alert('w 값이 제대로 넘어오지 않았습니다.'); +} + +if ($is_guest && !chk_captcha()) { + alert('자동등록방지 숫자가 틀렸습니다.'); +} + +if ($w == '' || $w == 'r') { + if (isset($_SESSION['ss_datetime'])) { + if ($_SESSION['ss_datetime'] >= (G5_SERVER_TIME - $config['cf_delay_sec']) && !$is_admin) + alert('너무 빠른 시간내에 게시물을 연속해서 올릴 수 없습니다.'); + } + + set_session("ss_datetime", G5_SERVER_TIME); +} + +if (!isset($_POST['wr_subject']) || !trim($_POST['wr_subject'])) + alert('제목을 입력하여 주십시오.'); + +if ($w == '' || $w == 'r') { + + if ($member['mb_id']) { + $mb_id = $member['mb_id']; + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_password = $member['mb_password']; + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); + } else { + $mb_id = ''; + // 비회원의 경우 이름이 누락되는 경우가 있음 + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + if (!$wr_name) + alert('이름은 필히 입력하셔야 합니다.'); + $wr_password = get_encrypt_string($wr_password); + $wr_email = get_email_address(trim($_POST['wr_email'])); + $wr_homepage = clean_xss_tags($wr_homepage); + } + + if ($w == 'r') { + // 답변의 원글이 비밀글이라면 비밀번호는 원글과 동일하게 넣는다. + if ($secret) + $wr_password = $wr['wr_password']; + + $wr_id = $wr_id . $reply; + $wr_num = $write['wr_num']; + $wr_reply = $reply; + } else { + $wr_num = get_next_num($write_table); + $wr_reply = ''; + } + + $sql = " insert into $write_table + set wr_num = '$wr_num', + wr_reply = '$wr_reply', + wr_comment = 0, + ca_name = '$ca_name', + wr_option = '$html,$secret,$mail', + wr_subject = '$wr_subject', + wr_content = '$wr_content', + wr_link1 = '$wr_link1', + wr_link2 = '$wr_link2', + wr_link1_hit = 0, + wr_link2_hit = 0, + wr_hit = 0, + wr_good = 0, + wr_nogood = 0, + mb_id = '{$member['mb_id']}', + wr_password = '$wr_password', + wr_name = '$wr_name', + wr_email = '$wr_email', + wr_homepage = '$wr_homepage', + wr_datetime = '".G5_TIME_YMDHIS."', + wr_last = '".G5_TIME_YMDHIS."', + wr_ip = '{$_SERVER['REMOTE_ADDR']}', + + ch_id = '$character['ch_id']', + ch_side = '$character['ch_side']', + ch_class = '$character['ch_class']', + ti_id = '$character['ch_title']', + wr_width = '$wr_width', + wr_height = '$wr_height', + wr_url = '$wr_url', + wr_type = '$wr_type', + + wr_secret = '$wr_secret', + wr_adult = '$wr_adult', + wr_wide = '$wr_wide', + wr_plip = '$wr_plip', + + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10' "; + sql_query($sql); + + $wr_id = sql_insert_id(); + + // 부모 아이디에 UPDATE + sql_query(" update $write_table set wr_parent = '$wr_id' where wr_id = '$wr_id' "); + + // 새글 INSERT + sql_query(" insert into {$g5['board_new_table']} ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values ( '{$bo_table}', '{$wr_id}', '{$wr_id}', '".G5_TIME_YMDHIS."', '{$member['mb_id']}' ) "); + + // 게시글 1 증가 + sql_query("update {$g5['board_table']} set bo_count_write = bo_count_write + 1 where bo_table = '{$bo_table}'"); + + // 쓰기 포인트 부여 + if ($w == '') { + if ($notice) { + $bo_notice = $wr_id.($board['bo_notice'] ? ",".$board['bo_notice'] : ''); + sql_query(" update {$g5['board_table']} set bo_notice = '{$bo_notice}' where bo_table = '{$bo_table}' "); + } + + insert_point($member['mb_id'], $board['bo_write_point'], "{$board['bo_subject']} {$wr_id} 글쓰기", $bo_table, $wr_id, '쓰기'); + } else { + // 답변은 코멘트 포인트를 부여함 + // 답변 포인트가 많은 경우 코멘트 대신 답변을 하는 경우가 많음 + insert_point($member['mb_id'], $board['bo_comment_point'], "{$board['bo_subject']} {$wr_id} 글답변", $bo_table, $wr_id, '쓰기'); + } +} else if ($w == 'u') { + if (get_session('ss_bo_table') != $_POST['bo_table'] || get_session('ss_wr_id') != $_POST['wr_id']) { + alert('올바른 방법으로 수정하여 주십시오.', G5_BBS_URL.'/board.php?bo_table='.$bo_table); + } + + $return_url = './board.php?bo_table='.$bo_table.'&wr_id='.$wr_id; + + if ($is_admin == 'super') // 최고관리자 통과 + ; + else if ($is_admin == 'group') { // 그룹관리자 + $mb = get_member($write['mb_id']); + if ($member['mb_id'] != $group['gr_admin']) // 자신이 관리하는 그룹인가? + alert('자신이 관리하는 그룹의 게시판이 아니므로 수정할 수 없습니다.', $return_url); + else if ($member['mb_level'] < $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + alert('자신의 권한보다 높은 권한의 회원이 작성한 글은 수정할 수 없습니다.', $return_url); + } else if ($is_admin == 'board') { // 게시판관리자이면 + $mb = get_member($write['mb_id']); + if ($member['mb_id'] != $board['bo_admin']) // 자신이 관리하는 게시판인가? + alert('자신이 관리하는 게시판이 아니므로 수정할 수 없습니다.', $return_url); + else if ($member['mb_level'] < $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + alert('자신의 권한보다 높은 권한의 회원이 작성한 글은 수정할 수 없습니다.', $return_url); + } else if ($member['mb_id']) { + if ($member['mb_id'] != $write['mb_id']) + alert('자신의 글이 아니므로 수정할 수 없습니다.', $return_url); + } else { + if ($write['mb_id']) + alert('로그인 후 수정하세요.', './login.php?url='.urlencode($return_url)); + } + + if ($member['mb_id']) { + // 자신의 글이라면 + if ($member['mb_id'] == $wr['mb_id']) { + $mb_id = $member['mb_id']; + $wr_name = addslashes(clean_xss_tags($board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick'])); + $wr_email = addslashes($member['mb_email']); + $wr_homepage = addslashes(clean_xss_tags($member['mb_homepage'])); + } else { + $mb_id = $wr['mb_id']; + if(isset($_POST['wr_name']) && $_POST['wr_name']) + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + else + $wr_name = addslashes(clean_xss_tags($wr['wr_name'])); + if(isset($_POST['wr_email']) && $_POST['wr_email']) + $wr_email = get_email_address(trim($_POST['wr_email'])); + else + $wr_email = addslashes($wr['wr_email']); + if(isset($_POST['wr_homepage']) && $_POST['wr_homepage']) + $wr_homepage = addslashes(clean_xss_tags($_POST['wr_homepage'])); + else + $wr_homepage = addslashes(clean_xss_tags($wr['wr_homepage'])); + } + } else { + $mb_id = ""; + // 비회원의 경우 이름이 누락되는 경우가 있음 + if (!trim($wr_name)) alert("이름은 필히 입력하셔야 합니다."); + $wr_name = clean_xss_tags(trim($_POST['wr_name'])); + $wr_email = get_email_address(trim($_POST['wr_email'])); + } + + $sql_password = $wr_password ? " , wr_password = '".get_encrypt_string($wr_password)."' " : ""; + + $sql_ip = ''; + if (!$is_admin) + $sql_ip = " , wr_ip = '{$_SERVER['REMOTE_ADDR']}' "; + + $sql = " update {$write_table} + set ca_name = '{$ca_name}', + wr_option = '{$html},{$secret},{$mail}', + wr_subject = '{$wr_subject}', + wr_content = '{$wr_content}', + wr_link1 = '{$wr_link1}', + wr_link2 = '{$wr_link2}', + mb_id = '{$mb_id}', + wr_name = '{$wr_name}', + wr_email = '{$wr_email}', + wr_homepage = '{$wr_homepage}', + + wr_width = '$wr_width', + wr_height = '$wr_height', + wr_url = '$wr_url', + wr_type = '$wr_type', + + wr_secret = '$wr_secret', + wr_adult = '$wr_adult', + wr_wide = '$wr_wide', + wr_plip = '$wr_plip', + + wr_1 = '{$wr_1}', + wr_2 = '{$wr_2}', + wr_3 = '{$wr_3}', + wr_4 = '{$wr_4}', + wr_5 = '{$wr_5}', + wr_6 = '{$wr_6}', + wr_7 = '{$wr_7}', + wr_8 = '{$wr_8}', + wr_9 = '{$wr_9}', + wr_10= '{$wr_10}' + {$sql_ip} + {$sql_password} + where wr_id = '{$wr['wr_id']}' "; + sql_query($sql); + + // 분류가 수정되는 경우 해당되는 코멘트의 분류명도 모두 수정함 + // 코멘트의 분류를 수정하지 않으면 검색이 제대로 되지 않음 + $sql = " update {$write_table} set ca_name = '{$ca_name}' where wr_parent = '{$wr['wr_id']}' "; + sql_query($sql); + + /* + if ($notice) { + //if (!preg_match("/[^0-9]{0,1}{$wr_id}[\r]{0,1}/",$board['bo_notice'])) + if (!in_array((int)$wr_id, $notice_array)) { + $bo_notice = $wr_id . ',' . $board['bo_notice']; + sql_query(" update {$g5['board_table']} set bo_notice = '{$bo_notice}' where bo_table = '{$bo_table}' "); + } + } else { + $bo_notice = ''; + for ($i=0; $i $board['bo_upload_count']) + alert('기존 파일을 삭제하신 후 첨부파일을 '.number_format($board['bo_upload_count']).'개 이하로 업로드 해주십시오.'); +} else { + if($file_count > $board['bo_upload_count']) + alert('첨부파일을 '.number_format($board['bo_upload_count']).'개 이하로 업로드 해주십시오.'); +} + +// 디렉토리가 없다면 생성합니다. (퍼미션도 변경하구요.) +@mkdir(G5_DATA_PATH.'/file/'.$bo_table, G5_DIR_PERMISSION); +@chmod(G5_DATA_PATH.'/file/'.$bo_table, G5_DIR_PERMISSION); + +$chars_array = array_merge(range(0,9), range('a','z'), range('A','Z')); + +// 가변 파일 업로드 +$file_upload_msg = ''; +$upload = array(); +for ($i=0; $i $board['bo_upload_size']) { + $file_upload_msg .= '\"'.$filename.'\" 파일의 용량('.number_format($filesize).' 바이트)이 게시판에 설정('.number_format($board['bo_upload_size']).' 바이트)된 값보다 크므로 업로드 하지 않습니다.\\n'; + continue; + } + + //=================================================================\ + // 090714 + // 이미지나 플래시 파일에 악성코드를 심어 업로드 하는 경우를 방지 + // 에러메세지는 출력하지 않는다. + //----------------------------------------------------------------- + $timg = @getimagesize($tmp_file); + // image type + if ( preg_match("/\.({$config['cf_image_extension']})$/i", $filename) || + preg_match("/\.({$config['cf_flash_extension']})$/i", $filename) ) { + if ($timg['2'] < 1 || $timg['2'] > 16) + continue; + } + //================================================================= + + $upload[$i]['image'] = $timg; + + // 4.00.11 - 글답변에서 파일 업로드시 원글의 파일이 삭제되는 오류를 수정 + if ($w == 'u') { + // 존재하는 파일이 있다면 삭제합니다. + $row = sql_fetch(" select bf_file from {$g5['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' and bf_no = '$i' "); + @unlink(G5_DATA_PATH.'/file/'.$bo_table.'/'.$row['bf_file']); + // 이미지파일이면 썸네일삭제 + if(preg_match("/\.({$config['cf_image_extension']})$/i", $row['bf_file'])) { + delete_board_thumbnail($bo_table, $row['bf_file']); + } + } + + // 프로그램 원래 파일명 + $upload[$i]['source'] = $filename; + $upload[$i]['filesize'] = $filesize; + + // 아래의 문자열이 들어간 파일은 -x 를 붙여서 웹경로를 알더라도 실행을 하지 못하도록 함 + $filename = preg_replace("/\.(php|phtm|htm|cgi|pl|exe|jsp|asp|inc)/i", "$0-x", $filename); + + shuffle($chars_array); + $shuffle = implode('', $chars_array); + + // 첨부파일 첨부시 첨부파일명에 공백이 포함되어 있으면 일부 PC에서 보이지 않거나 다운로드 되지 않는 현상이 있습니다. (길상여의 님 090925) + $upload[$i]['file'] = abs(ip2long($_SERVER['REMOTE_ADDR'])).'_'.substr($shuffle,0,8).'_'.replace_filename($filename); + + $dest_file = G5_DATA_PATH.'/file/'.$bo_table.'/'.$upload[$i]['file']; + + // 업로드가 안된다면 에러메세지 출력하고 죽어버립니다. + $error_code = move_uploaded_file($tmp_file, $dest_file) or die($_FILES['bf_file']['error'][$i]); + + // 올라간 파일의 퍼미션을 변경합니다. + chmod($dest_file, G5_FILE_PERMISSION); + } +} + +// 나중에 테이블에 저장하는 이유는 $wr_id 값을 저장해야 하기 때문입니다. +for ($i=0; $i=0; $i--) +{ + $row2 = sql_fetch(" select bf_file from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' and bf_no = '{$i}' "); + + // 정보가 있다면 빠집니다. + if ($row2['bf_file']) break; + + // 그렇지 않다면 정보를 삭제합니다. + sql_query(" delete from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' and bf_no = '{$i}' "); +} + +// 파일의 개수를 게시물에 업데이트 한다. +$row = sql_fetch(" select count(*) as cnt from {$g5['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' "); +sql_query(" update {$write_table} set wr_file = '{$row['cnt']}' where wr_id = '{$wr_id}' "); + +// 자동저장된 레코드를 삭제한다. +sql_query(" delete from {$g5['autosave_table']} where as_uid = '{$uid}' "); +//------------------------------------------------------------------------------ + +// 비밀글이라면 세션에 비밀글의 아이디를 저장한다. 자신의 글은 다시 비밀번호를 묻지 않기 위함 +if ($secret) + set_session("ss_secret_{$bo_table}_{$wr_num}", TRUE); + +// 메일발송 사용 (수정글은 발송하지 않음) +if (!($w == 'u' || $w == 'cu') && $config['cf_email_use'] && $board['bo_use_email']) { + + // 관리자의 정보를 얻고 + $super_admin = get_admin('super'); + $group_admin = get_admin('group'); + $board_admin = get_admin('board'); + + $wr_subject = get_text(stripslashes($wr_subject)); + + $tmp_html = 0; + if (strstr($html, 'html1')) + $tmp_html = 1; + else if (strstr($html, 'html2')) + $tmp_html = 2; + + $wr_content = conv_content(conv_unescape_nl(stripslashes($wr_content)), $tmp_html); + + $warr = array( ''=>'입력', 'u'=>'수정', 'r'=>'답변', 'c'=>'코멘트', 'cu'=>'코멘트 수정' ); + $str = $warr[$w]; + + $subject = '['.$config['cf_title'].'] '.$board['bo_subject'].' 게시판에 '.$str.'글이 올라왔습니다.'; + + $link_url = G5_BBS_URL.'/board.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&'.$qstr; + + include_once(G5_LIB_PATH.'/mailer.lib.php'); + + ob_start(); + include_once ('./write_update_mail.php'); + $content = ob_get_contents(); + ob_end_clean(); + + $array_email = array(); + // 게시판관리자에게 보내는 메일 + if ($config['cf_email_wr_board_admin']) $array_email[] = $board_admin['mb_email']; + // 게시판그룹관리자에게 보내는 메일 + if ($config['cf_email_wr_group_admin']) $array_email[] = $group_admin['mb_email']; + // 최고관리자에게 보내는 메일 + if ($config['cf_email_wr_super_admin']) $array_email[] = $super_admin['mb_email']; + + // 원글게시자에게 보내는 메일 + if ($config['cf_email_wr_write']) { + if($w == '') + $wr['wr_email'] = $wr_email; + + $array_email[] = $wr['wr_email']; + } + + // 옵션에 메일받기가 체크되어 있고, 게시자의 메일이 있다면 + if (strstr($wr['wr_option'], 'mail') && $wr['wr_email']) + $array_email[] = $wr['wr_email']; + + // 중복된 메일 주소는 제거 + $unique_email = array_unique($array_email); + $unique_email = array_values($unique_email); + for ($i=0; $i + + + + +<?php echo $wr_subject ?> 메일 + + + + +
    +
    +

    + +

    + + 작성자 + +
    + +
    + 사이트에서 게시물 확인하기 +
    +
    + + + diff --git a/AvocadoEdition/bgm.php b/AvocadoEdition/bgm.php new file mode 100644 index 0000000..b3a8e4b --- /dev/null +++ b/AvocadoEdition/bgm.php @@ -0,0 +1,14 @@ + + + + + + + + +
    + +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/install/AVOCADO.LICENSE.txt b/AvocadoEdition/install/AVOCADO.LICENSE.txt new file mode 100644 index 0000000..208d2e9 --- /dev/null +++ b/AvocadoEdition/install/AVOCADO.LICENSE.txt @@ -0,0 +1,19 @@ +프로그램 명칭 : 아보카도 에디션 (Avocado Edition) + +저작자 : Avocado https://avocado-edition-rout.postype.com/ + +--------------------------------------------------- + +본 프로그램은 그누보드5를 기반으로 하여 자캐 커뮤니티 제작을 목적으로 만들어졌습니다. +게시판과 회원시스템을 제외한 나머지 프로그램은 자체개발로 제작되었으며, 게시판의 일부 기능이 커스텀 되어 있습니다. + +해당 소스를 변형하여 재배포, 커미션 행위를 하는 것은 가능하나 상업적인 용도를 위한 판매는 불가합니다. + +※ 상업적인 용도의 구분 기준 +1. 개인이 아닌 기업체가 납품의 용도로 이용하는 경우 +2. 커미션 수준의 금액이 아닌 외주 수준의 금액이 오가는 목적으로 이용하여 납품하는 경우 +3. 자캐커뮤니티 용도가 아닌 다른 용도의 사이트로 제작되는 경우 +4. 기타 통상적인 커미션의 용도에서 벗어나는 용도로 이용되는 경우 + + +위의 경우로 이용됨이 적발 될 시 법적 처분을 받을 수 있습니다. \ No newline at end of file diff --git a/AvocadoEdition/install/LICENSE.txt b/AvocadoEdition/install/LICENSE.txt new file mode 100644 index 0000000..94d5361 --- /dev/null +++ b/AvocadoEdition/install/LICENSE.txt @@ -0,0 +1,242 @@ +소프트웨어 제품은 저작권법 및 국제저작권 협약을 비롯하여, 기타 지적재산권법 및 협약의 보호를 받습니다. + +프로그램 명칭 : 그누보드5 ( GNU Board 5 ) + +저작자 : (주)에스아이알소프트 http://sir.kr + +라이센스 (License) + +번역문 아래에 원문이 있습니다. + +주의 ) +1. 번역문과 원문의 내용상 차이가 있는 경우 원문의 내용을 우선으로 따릅니다. +2. 법적인 분쟁이 발생한 경우 저작자의 회사 소재지를 관할하는 관할법원에서 분쟁을 해결합니다. +3. 이 라이센스 파일 및 내용은 저작자를 제외한 어느 누구도 추가, 수정, 삭제할 수 없습니다. + +----- LGPL 번역문 -------------------------------------------------------- + +GNU 약소 일반 공중 사용 허가서 + +2.1판, 1999년 2월 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +누구든지 본 사용 허가서를 있는 그대로 복제하고 배포할 수 있습니다. +그러나 본문에 대한 수정은 허용되지 않습니다. + +[이 문서는 GNU 약소 일반 공중 사용 허가서의 이름으로 공표된 최초의 판본입니다. +본 사용 허가서는 GNU 라이브러리 일반 공중 사용 허가서 2판의 후속판으로 +간주되기 때문에 2.1의 판번호를 갖고 있습니다.] +전 문 + +소프트웨어에 적용되는 대부분의 사용 허가서들은 소프트웨어에 대한 수정과 공유의 자유를 제한하려는 것을 그 목적으로 합니다. 그러나 GNU 일반 공중 사용 허가서들은 자유 소프트웨어에 대한 수정과 공유의 자유를 모든 사용자들에게 보장하기 위해서 성립된 것입니다. +본 사용 허가서인 GNU 약소 일반 공중 사용 허가서(이하, ``LGPL''이라고 칭합니다.)는 자유 소프트웨어 재단과 그밖의 저작자들이 이를 채택하기로 결정한, 주로 라이브러리와 같은 일부 특정한 소프트웨어 꾸러미에 적용됩니다. 누구든지 자신의 프로그램에 LGPL을 적용할 수 있지만, 어떤 상황에서 어떤 사용 허가서를 선택하는 것이 보다 나은 전략인지에 대해서 다음의 설명을 기준으로 먼저 신중히 고려해 보시기 바랍니다. +자유 소프트웨어라는 말에서 사용된 ``자유''라는 단어는 무료를 의미하는 금전적인 측면의 자유가 아니라 구속되지 않는다는 관점에서의 자유를 의미하며, GNU 일반 공중 사용 허가서들은 자유 소프트웨어를 이용한 복제와 개작 및 배포와 수익 사업 등의 가능한 모든 형태의 자유를 실질적으로 보장하고 있습니다. 여기에는 원시 코드의 일부 또는 전부를 원용해서 보다 개선된 프로그램을 만들거나 새로운 프로그램을 창작할 수 있는 자유가 보장되어 있으며, 자신에게 양도된 이러한 자유와 권리를 보다 명확하게 인식할 수 있도록 하기 위한 규정도 포함되어 있습니다. +소프트웨어를 양도받은 사람의 권리를 보호하기 위해서 우리는 배포자들이 이러한 권리를 부정하거나 포기하도록 피양도자에게 요구하는 행위를 금지시킬 필요가 있습니다. 이러한 금지 사항은 라이브러리를 개작하거나 배포하는 모든 사람들이 예외없이 지켜야 할 의무와 같습니다. +예를 들어, LGPL 라이브러리를 배포할 경우에는 이를 유료로 판매하거나 무료로 배포하는 것에 관계없이 자신이 해당 라이브러리에 대해서 가질 수 있었던 모든 권리를 피양도자에게 그대로 양도해 주어야 하고, 라이브러리의 원시 코드를 함께 제공하거나 원시 코드를 구할 수 있는 방법을 확실히 알려주어야 합니다. 또한 라이브러리에 다른 코드를 링크시켰다면, 라이브러리를 수정한 뒤에도 정상적으로 컴파일을 진행할 수 있도록 링크 되었던 코드에 해당하는 완전한 목적 파일 전체를 함께 제공해야 합니다. 또한 피양도자에게 이러한 모든 사항들을 분명히 알 수 있도록 해 주어야 합니다. +자유 소프트웨어 재단은 다음과 같은 두 가지 단계를 통해서 사용자들의 권리를 보호합니다. (1) 라이브러리에 저작권을 설정합니다. (2) 저작권의 양도에 관한 실정법에 의해서 유효한 법률적 효력을 갖는 LGPL을 통해서 소프트웨어를 복제하거나 개작 및 배포할 수 있는 권리를 사용자에게 부여합니다. +모든 배포자들을 보호하기 위해서 우리는 자유 라이브러리에 대한 어떠한 보증도 제공하지 않는다는 점을 명확히 밝혀둡니다. 라이브러리를 사용하는 사람들은 반복적인 재배포 과정을 통해 라이브러리 자체에 수정과 변형이 일어날 수도 있으며, 이는 최초의 저작자가 만든 라이브러리가 갖고 있는 문제가 아닐 수 있다는 개연성을 인식하고 있어야 합니다. 우리는 개작과 재배포 과정에서 다른 사람에 의해 발생된 문제로 인해 라이브러리의 원저작자의 신망이 실추되는 것을 원하지 않습니다. +특허 제도는 자유 소프트웨어의 존재를 위협하는 요소일 수밖에 없습니다. 우리는 특허권자로부터 기업이 제한적인 사용 허가를 얻은 뒤에 이를 통해 자유 프로그램의 사용자들을 규제할 수 없게 되기를 희망합니다. 따라서 우리는 특정한 버전의 라이브러리에 대한 어떠한 특허 사용 허가의 취득도 LGPL에 규정된 자유를 완전히 만족시키는 범위 내에서 이루어 져야 할 것을 요구합니다. +몇몇 라이브러리를 포함한 대부분의 GNU 소프트웨어에는 GPL이 적용됩니다. 본 사용 허가서인 LGPL은 특정한 라이브러리에만 적용되며 GPL과는 상당히 다른 면을 갖고 있습니다. LGPL은 특정한 라이브러리가 자유 소프트웨어가 아닌 프로그램과 함께 링크되는 것을 허용하려는 목적으로 사용됩니다. +어떤 프로그램이 라이브러리와 함께 링크된다면, 라이브러리가 정적으로 링크되든지 공유 라이브러리로 사용되든지 간에 이 두개의 조합은 법적으로 말할 때 결합 저작물, 즉 최초의 라이브러리로부터 파생된 2차적 저작물로 간주됩니다. GPL은 이러한 형태의 링크가 일어날 경우에 결합된 전체 저작물이 GPL을 만족할 때에 한해서만 링크를 허용합니다. 그러나 LGPL은 보다 유연한 링크 조건을 허용하고 있습니다. +우리가 본 사용 허가서를 ``약소'' 일반 공중 사용 허가서라고 부르는 이유는 사용자들의 자유를 보호하는 강도를 GPL보다 경감시켰기 때문입니다. 또한 LGPL은 자유 소프트웨어가 아닌 프로그램과 경쟁하는데 있어서 자유 소프트웨어 개발자들에게 GPL보다 이점을 덜 제공합니다. 우리가 많은 종류의 라이브러리에 LGPL이 아닌 일반적인 GPL을 사용하는 것은 이러한 이유 때문입니다. 그러나 특수한 상황에서는 오히려 LGPL을 사용하는 것이 유리할 수 있습니다. +극히 드문 예이긴 하지만, 어떤 라이브러리의 사용 폭을 가능한 넓게 유도해서 그것을 사실상의 표준으로 만들어야 할 특별한 필요가 있다고 생각해 봅시다. 이것을 가능하게 만들기 위해서는 자유 소프트웨어가 아닌 프로그램도 이러한 라이브러리를 사용할 수 있도록 허용해야 합니다. 이보다 흔한 또 한가지 예로 자유 소프트웨어가 아닌 라이브러리가 폭넓게 사용되고 있을 때 이와 동일한 기능을 제공하는 자유 라이브러리가 만들어진 경우를 생각해 볼 수 있습니다. 이러한 상황에서는 자유 라이브러리의 사용을 자유 소프트웨어에만 한정함으로써 얻을 수 있는 이익이 거의 없습니다. 이런 경우에 우리는 LGPL을 사용합니다. +또 하나의 예는 자유 소프트웨어가 아닌 프로그램에 특정한 라이브러리의 사용을 허용함으로써 보다 많은 사람들이 자유 소프트웨어를 사용할 수 있게 만드는 경우입니다. 예를 들면, 자유 소프트웨어가 아닌 프로그램들이 GNU C 라이브러리를 사용할 수 있도록 허용해서 사람들이 GNU 운영체제와 GNU/리눅스 운영체제를 사용하도록 유도할 수 있습니다. +LGPL이 사용자의 자유를 보다 약소적으로 보호하고 있음에도 불구하고, LGPL로 설정된 라이브러리와 링크된 프로그램을 사용하는 사용자는 라이브러리가 개작되더라도 개작된 버전을 사용해서 프로그램을 실행할 수 있는 확실한 자유와 이에 필요한 수단을 갖고 있습니다. +복제와 개작 및 배포에 관련된 구체적인 조건과 규정은 다음과 같습니다. ``라이브러리에 기반한 저작물''과 ``라이브러리를 사용하는 저작물''의 차이에 특별한 주의를 기울이기 바랍니다. 전자는 라이브러리로부터 파생된 코드를 담고 있는 저작물을 의미하는데 반해서 후자는 실행되기 위해서 라이브러리와 결합되어야 하는 저작물을 말합니다. +복제와 개작 및 배포에 관한 조건과 규정 + +제 0 조. 본 사용 허가 계약은 GNU 약소 일반 공중 사용 허가서(이하, ``LGPL''이라고 칭합니다.)의 규정에 따라 배포될 수 있다는 사항이 저작권자 또는 그에 준하는 정당한 권리을 갖고 있는 자에 의해서 명시된 모든 종류의 소프트웨어 라이브러리와 컴퓨터 프로그램 저작물(이하, ``프로그램''이라고 칭합니다.)에 대해서 동일하게 적용됩니다. ``피양도자''란 LGPL의 규정에 따라 프로그램을 양도받은 사람을 의미합니다. +``라이브러리''란 소프트웨어 함수와 데이터를 함께 또는 개별적으로 수집해 놓은 것으로 이들 중 일부를 사용하는 응용 프로그램과 링크되어 실행물을 생성하는데 편리하도록 미리 준비된 것을 의미합니다. +이하로 언급되는 ``라이브러리''는 본 사용 허가서에 의해서 배포되고 있는 모든 소프트웨어 라이브러리와 저작물을 의미합니다. ``라이브러리에 기반한 저작물''은 라이브러리 또는 저작권법에 따른 라이브러리의 2차적 저작물을 모두 의미합니다. 다시 말하면, 전술한 라이브러리 자신 또는 저작권법의 규정에 따라 라이브러리의 전부 또는 상당 부분을 원용하거나 다른 언어로의 번역을 포함할 수 있는 개작 과정을 통해서 창작된 새로운 라이브러리와 이와 관련된 저작물입니다. (이후로 다른 언어로의 번역은 별다른 제한없이 개작의 범위에 포함되는 것으로 간주합니다.) +저작물에 대한 ``원시 코드''란 해당 저작물을 개작하기에 적절한 형식을 의미합니다. 라이브러리에 대한 완전한 원시 코드란 라이브러리에 포함된 모든 모듈들의 원시 코드와 이와 관련된 인터페이스 정의 파일 모두, 그리고 라이브러리의 컴파일과 설치를 제어하는데 사용된 스크립트 전부를 의미합니다. +본 허가서는 복제와 개작 및 배포 행위에 대해서만 적용됩니다. 따라서 라이브러리를 사용하는 프로그램을 실행시키는 행위에 대한 제한은 없습니다. 이러한 프로그램의 결과물에는, 결과물을 생성하기 위한 도구로 라이브러리가 사용되었는지 아닌지의 여부에 관계없이 결과물이 라이브러리에 기반한 2차적 저작물을 구성했을 때에 한해서 본 허가서의 규정들이 적용됩니다. 2차적 저작물의 구성 여부는 2차적 저작물 안에서의 라이브러리의 역할과 라이브러리를 사용한 프로그램의 역할을 토대로 판단합니다. +제 1 조. 적절한 저작권 표시와 라이브러리에 대한 보증이 제공되지 않는다는 사실을 각각의 복제물에 명시하는 한, 피양도자는 라이브러리의 원시 코드를 자신이 양도받은 상태 그대로 어떠한 매체를 통해서도 복제하고 배포할 수 있습니다. 복제와 배포가 이루어 질 때는 본 허가서와 라이브러리에 대한 보증이 제공되지 않는다는 사실에 대해서 언급되었던 모든 내용들을 그대로 유지시켜야 하며, 영문판 LGPL을 함께 제공해야 합니다. +배포자는 복제물을 물리적으로 인도하는데 소요된 비용을 청구할 수 있으며, 선택 사항으로 독자적인 유료 보증을 설정할 수 있습니다. +제 2 조. 피양도자는 자신이 양도받은 라이브러리의 전부나 일부를 개작할 수 있으며, 이를 통해 라이브러리에 기반한 2차적 저작물을 창작할 수 있습니다. 개작된 라이브러리나 창작된 2차적 저작물은 다음의 사항들을 모두 만족시키는 조건에 한해서, 제1조의 규정에 따라 또다시 복제되고 배포될 수 있습니다. +제 1 항. 개작된 저작물은 반드시 소프트웨어 라이브러리여야 합니다. +제 2 항. 파일을 개작할 때는 파일을 개작한 사실과 그 날짜를 파일 안에 명시해야 합니다. +제 3 항. 저작물 전체에 대한 사용 권리를 본 허가서의 규정에 따라 공중에게 무상으로 허용해야 합니다. +제 4 항. 개작된 라이브러리에 포함된 기능이 그 기능을 사용하는 응용 프로그램으로부터 제공되는 함수나 데이터 테이블을 참조하는 경우에는, 이러한 기능이 호출되었을 때 매개 인수를 전달하는 경우를 제외하고는 응용 프로그램이 그러한 함수나 테이블을 제공하지 않는 경우에도 기능이 독립적으로 수행되고 목적하는 모든 부분이 확실하게 유효할 수 있도록 최대의 노력을 기울여야만 합니다 + +(예를 들면, 라이브러리에 포함된 제곱근 연산 함수는 응용 프로그램으로부터 명확하고 완전하게 독립적인 형태로 만들어져야 합니다. 따라서 제2조 4항은 제곱근 연산 함수가 어떠한 응용 프로그램이 제공하는 함수나 테이블도 필수적으로 사용되는 않는 형태로 만들어져야 한다는 것을 규정합니다. 즉, 응용 프로그램이 제공하는 기능 없이도 제곱근 연산 함수가 제곱근을 구할 수 있어야 합니다.) +위의 조항들은 개작된 라이브러리 전체에 적용됩니다. 만약, 개작된 라이브러리에 포함된 특정 부분이 라이브러리부터 파생된 것이 아닌 별도의 독립 저작물로 인정될 만한 상당한 이유가 있을 경우에는 해당 저작물의 개별적인 배포에는 본 허가서의 규정들이 적용되지 않습니다. 그러나 이러한 저작물이 라이브러리에 기반한 2차적 저작물의 일부로서 함께 배포된다면 개별적인 저작권과 배포 기준에 상관없이 저작물 모두가 본 허가서에 의해서 관리되어야 하며, 전체 저작물에 대한 사용 권리는 공중에게 무상으로 양도됩니다. +이러한 규정은 개별적인 저작물에 대한 저작자들의 권리를 침해하거나 인정하지 않으려는 것이 아니라, 라이브러리로부터 파생된 2차적 저작물이나 수집 저작물의 배포를 일관적으로 규제할 수 있는 권리를 행사하기 위한 것입니다. +라이브러리나 라이브러리로부터 파생된 2차적 저작물을 이들로부터 파생되지 않은 다른 저작물과 함께 단순히 저장하거나 배포하기 위한 목적으로 동일한 매체에 모아 놓은 집합물의 경우에는, 라이브러리로부터 파생되지 않은 다른 저작물에는 본 허가서의 규정들이 적용되지 않습니다. +제 3 조. 피양도자는 자신이 양도받은 라이브러리의 복제물에 LGPL 대신 GPL의 규정을 적용할 수 있습니다. 이것이 가능하기 위해서는 LGPL에 대해서 언급되었던 모든 사항을 GPL 2판으로 대체시켜야 합니다. (GPL 2판보다 신판이 공표되었을 경우에는 원한다면 신판의 판번호를 사용할 수 있습니다.) 그 이외에 다른 사항들은 변경할 수 없습니다. + +복제물에 대해서 이러한 수정이 이루어 졌을 경우에는 GPL로 변경된 사용권 허가를 다시 변경할 수 없으며, 이에 따라서 해당 복제물을 기반으로 만들어진 모든 저작물과 복제물에는 GPL이 적용되어야만 합니다. + +이러한 선택 사항은 라이브러리의 코드 일부분을 라이브러리가 아닌 일반 프로그램에 포함시키고자 할 경우에 유용합니다. +제 4 조. 피양도자는 제1조와 제2조의 규정에 따라 라이브러리(또는 제2조에 의한 라이브러리의 일부나 라이브러리에 기반한 2차적 저작물)를 목적 코드나 실행물의 형태로 복제하고 배포할 수 있습니다. 이 때 목적 코드나 실행물에 상응하는 컴퓨터가 인식할 수 있는 완전한 원시 코드를 제1조와 제2조의 규정에 따라 소프트웨어의 교환을 위해서 일반적으로 사용되는 매체를 통해 함께 제공해야 합니다. + +목적 코드를 지정한 장소로부터 복제해 갈 수 있게 하는 방식으로 배포할 경우, 동일한 장소로부터 원시 코드를 복제할 수 있는 동등한 접근 방법을 제공한다면 이는 원시 코드가 목적 코드와 함께 복제되도록 설정되지 않았다 하더라도 원시 코드를 배포하는 것으로 간주됩니다. +제 5 조. 라이브러리의 어떠한 부분으로부터의 파생물도 포함하지 않지만, 컴파일 또는 링크를 통해서 라이브러리와 함께 작동하도록 설계된 프로그램은 ``라이브러리를 사용하는 저작물''이 됩니다. 이러한 저작물이 별도로 분리되어 있을 때는 라이브러리에 대한 파생물이 아니므로 본 사용 허가서가 적용되지 않습니다. +그러나 ``라이브러리를 사용하는 저작물''이 라이브러리와 링크된 결과로 생성된 실행물은, 실행물 안에 라이브러리의 일부를 포함하고 있기 때문에 라이브러리에 기반한 2차적 저작물을 구성하게 됩니다. 따라서 이러한 방식으로 생성된 실행물은 본 사용 허가서의 적용을 받습니다. 제6조는 이러한 종류의 실행물의 배포를 위한 규정을 담고 있습니다. +``라이브러리를 사용하는 저작물''이 라이브러리의 일부인 헤더 파일의 자료를 사용한 경우에는 그러한 저작물의 원시 코드가 라이브러리에 기반한 2차적 저작물이 아니었다 하더라도 목적 코드는 라이브러리에 기반한 2차적 저작물이 될 수 있습니다. 이러한 구분이 성립될 수 있는지의 여부는 그러한 저작물 자체가 라이브러리이거나 저작물에 사용된 라이브러리 없이도 링크될 수 있는 경우에 있어서 매우 중요한 차이를 갖습니다. 그러나 이러한 구분이 성립될 수 있는 명확한 판단 기준은 법률적으로 정의되어 있지 않습니다. +만약 이와같은 형태의 목적 파일이 단지 숫자 매개 변수와 자료 구조의 설계 형태 및 이에 대한 접근 도구 그리고 10행 미만으로 이루어진 작은 인라인 함수와 매크로만을 사용하는 것이라면 법적 기준에 의한 2차적 저작물의 성립 여부에 관계없이 그 사용이 제한되지 않습니다. (그러나 이러한 목적 코드와 라이브러리의 일부가 함께 포함된 실행물은 여전히 제6조의 적용을 받습니다.) +저작물이 라이브러리에 기반한 2차적 저작물이라면 해당 저작물에 대한 목적 코드는 제6조에 따라 배포될 수 있습니다. 또한 그러한 저작물을 포함한 실행물들은 기반이 된 라이브러리에 직접 링크되는지 아닌지의 여부에 관계없이 모두 제6조의 적용을 받습니다. +제 6 조. 위의 조항들에 대한 예외의 하나로, 라이브러리와 ``라이브러리를 사용하는 저작물''을 함께 결합하거나 링크시켜서 라이브러리의 일부분이 포함된 저작물을 만들었다면, 이를 자신이 선택한 규정에 따라 배포할 수 있습니다. 이 경우 배포 규정에는 피양도자들이 자신의 필요에 따라 저작물을 개작할 수 있으며 개작에 따른 디버깅을 위해 코드역분석(reverse regineering)을 허용한다는 사항이 포함되어야 합니다. +라이브러리와 라이브러리의 사용에는 본 사용 허가서가 적용된다는 것과 저작물 안에 이러한 라이브러리가 사용되고 있다는 사실을 담고 있는 안내 문구를 모든 복제물에 분명하게 명시해야 합니다. 또한 영문판 LGLP 사본을 함께 제공해야 합니다. 저작물이 실행될 때 저작권 사항이 표시되는 형태를 취하고 있다면 라이브러리에 대한 저작권 사항도 함께 포함시켜야 하며 LGPL 사본을 참고할 수 있는 방법을 명시해야 합니다. 또한 다음 중 하나의 사항을 반드시 만족시켜야 합니다. +제 1 항. 저작물에 포함된 라이브러리에 어떠한 수정이 가해졌다 하더라도 해당 라이브러리에 대한 컴퓨터가 인식할 수 있는 완전한 형태의 원시 코드를 저작물과 함께 제공해야 합니다. 이 원시 코드는 제1조와 제2조의 규정에 따라 배포될 수 있어야 합니다. 만약 저작물이 라이브러리와 링크되는 실행물이었을 경우에는 피양도자가 실행물과 링크되는 라이브러리를 개작한 뒤에도 링크를 통해 새로운 실행물을 만들 수 있도록 하기 위해서 ``라이브러리를 사용한 저작물''로서 배포된 저작물에 해당하는 컴퓨터가 인식할 수 있는 완전한 형태의 원시 코드와 목적 코드 중 하나 또는 둘 모두를 제공해야 합니다. (라이브러리에 포함된 정의 파일의 내용을 수정한 경우에는 변경된 정의 부분을 사용하기 위해서 응용 프로그램을 반드시 다시 컴파일할 필요는 없다는 점은 인정됩니다.) +제 2 항. 라이브러리는 적절한 공유 라이브러리 방식을 사용해서 링크되어야 합니다. 적절한 방식이란, (1) 라이브러리의 함수를 실행물 속으로 직접 복제하는 것이 아니라 실행 시점에서 볼 때 이미 사용자의 컴퓨터 시스템 상에 존재하고 있는 라이브러리의 복제물이 사용되는 것입니다. 또한 (2) 사용자가 개작된 라이브러리를 설치한 경우에도 개작된 라이브러리가 저작물을 만들 때 사용된 라이브러리의 버전과 인터페이스상으로 호환되는 한, 적절하게 동작할 수 있어야 합니다. +제 3 항. 배포에 필요한 최소한의 비용만을 받고 피양도자에게 제6조 1항에 규정된 자료를 배포하겠다는, 최소한 3년간 유효한 약정서를 저작물과 함께 제공해야 합니다. +제 4 항. 저작물을 지정한 장소로부터 복제해 갈 수 있게 하는 방식으로 배포하는 경우, 동일한 장소로부터 제6조 1항에 규정된 자료를 복제할 수 있는 동등한 접근 방법을 제공하는 것은 저작물에 대한 배포 조건을 충족하는 것으로 간주됩니다. +제 5 항. 피양도자가 제6조 1항에 규정된 자료의 복제물을 이미 수령했는지를 확인하거나 자신이 피양도자에게 그러한 자료를 이미 송부했는지를 확인해야 합니다. +실행물이 ``라이브러리를 사용하는 저작물''의 형태로 배포된다면 여기에는 실행물을 재생산하기 위해서 필요한 유틸리티 프로그램과 데이터들이 모두 포함되어야 합니다. 그러나 특별한 예외의 하나로서, 실행물이 실행될 운영체제의 주요 부분(컴파일러나 커널 등)과 함께 (원시 코드나 바이너리의 형태로) 일반적으로 배포되는 구성 요소들은 이러한 구성 요소 자체가 실행물에 수반되지 않는한 배포 대상에서 제외되어도 무방합니다. +이러한 규정이 일반적으로 운영체제에 함께 수반되지 않는 독점 라이브러리들의 사용 허가서와 충돌하게 될 경우에는 배포하고자 하는 실행물 안에 본 사용 허가서가 적용되는 라이브러리와 독점 라이브러리를 함께 사용할 수 없습니다. +제 7 조. 라이브러리에 기반한 저작물로서의 라이브러리의 일부를 본 사용 허가서가 적용되지 않는 다른 라이브러리의 일부와 하나의 라이브러리 안에 병존시킬 수 있습니다. 이러한 결합 라이브러리를 배포할 경우에는 라이브러리에 기반한 저작물과 그렇지 않은 라이브러리가 별도로 배포될 수 있음을 명시해야 하며 다음의 두가지 사항을 준수해야 합니다. +제 1 항. 결합 라이브러리를 구성하고 있는 ``라이브러리에 기반한 저작물''의 복제물을 결합되지 않은 독립된 상태로 함께 제공해야 합니다. 이 복제물의 배포에는 위의 조항들이 적용됩니다. +제 2 항. 라이브러리에 기반한 저작물의 일부가 결합 라이브러리 안에 포함하고 있다는 사실을 명시해야 하며, 제7조 1항에 의해서 제공된 결합되지 않은 상태의 ``라이브러리에 기반한 저작물''의 위치 정보를 명기해야 합니다. +제 8 조. 본 허가서에 의해서 명시적으로 이루어 지지 않는 한 라이브러리에 대한 복제와 개작, 하위 허가권 설정과 링크 및 배포가 이루어 질 수 없습니다. 이와 관련된 어떠한 행위도 무효이며 본 허가서가 보장한 권리는 자동으로 소멸됩니다. 그러나 본 허가서의 규정에 따라 라이브러리의 복제물이나 권리를 양도받았던 제3자는 본 허가서의 규정들을 준수하는 한, 배포자의 권리 소멸에 관계없이 사용상의 권리를 계속해서 유지할 수 있습니다. +제 9 조. 본 허가서는 서명이나 날인이 수반되는 형식을 갖고 있지 않기 때문에 피양도자가 본 허가서의 내용을 반드시 받아들여야 할 필요는 없습니다. 그러나 라이브러리나 라이브러리에 기반한 2차적 저작물에 대한 개작 및 배포를 허용하는 것은 본 허가서에 의해서만 가능합니다. 만약 본 허가서에 동의하지 않을 경우에는 이러한 행위들이 법률적으로 금지됩니다. 따라서 라이브러리(또는 라이브러리에 기반한 2차적 저작물)을 개작하거나 배포하는 행위는 이에 따른 본 허가서의 내용에 동의한다는 것을 의미하며, 복제와 개작 및 배포에 관한 본 허가서의 조건과 규정들을 모두 받아들이겠다는 의미로 간주됩니다. +제 10 조. 피양도자에 의해서 라이브러리(또는 라이브러리에 기반한 2차적 저작물)이 반복적으로 재배포될 경우, 각 단계에서의 피양도자는 본 허가서의 규정에 따른 라이브러리의 복제와 개작, 링크, 배포에 대한 권리를 최초의 양도자로부터 양도받은 것으로 자동적으로 간주됩니다. 라이브러리(또는 라이브러리에 기반한 2차적 저작물)을 배포할 때는 피양도자의 권리의 행사를 제한할 수 있는 어떠한 사항도 추가할 수 없습니다. 그러나 피양도자에게 재배포가 일어날 시점에서의 제3의 피양도자에게 본 허가서를 준수하도록 강제할 책임은 부과되지 않습니다. +제 11 조. 법원의 판결이나 특허권 침해에 대한 주장 또는 특허 문제에 국한되지 않은 그밖의 이유들로 인해서 본 허가서의 규정에 배치되는 사항이 발생한다 하더라도 그러한 사항이 선행하거나 본 허가서의 조건과 규정들이 면제되는 것은 아닙니다. 따라서 법원의 명령이나 합의 등에 의해서 본 허가서에 위배되는 사항들이 발생한 상황이라도 양측 모두를 만족시킬 수 없다면 라이브러리는 배포될 수 없습니다. 예를 들면, 특정한 특허 관련 허가가 라이브러리의 복제물을 직접 또는 간접적인 방법으로 양도받은 임의의 제3자에게 해당 라이브러리를 무상으로 재배포할 수 있게 허용하지 않는다면, 그러한 허가와 본 사용 허가를 동시에 만족시키면서 라이브러리를 배포할 수 있는 방법은 없습니다. +본 조항은 특정한 상황에서 본 조항의 일부가 유효하지 않거나 적용될 수 없을 경우에도 본 조항의 나머지 부분들을 적용하기 위한 의도로 만들어 졌습니다. 따라서 그 이외의 상황에서는 본 조항을 전체적으로 적용하면 됩니다. +본 조항의 목적은 특허나 저작권 침해 등의 행위를 조장하거나 해당 권리를 인정하지 않으려는 것이 아니라, 공중 사용 허가서들을 통해서 구현되어 있는 자유 소프트웨어의 배포 체계를 통합적으로 보호하기 위한 것입니다. 많은 사람들이 배포 체계에 대한 신뢰있는 지원을 계속해 줌으로써 소프트웨어의 다양한 분야에 많은 공헌을 해 주었습니다. 소프트웨어를 어떠한 배포 체계를 통해 배포할 것인가를 결정하는 것은 전적으로 저작자와 기증자들의 의지에 달려있는 것이지, 일반 사용자들이 강요할 수 있는 문제는 아닙니다. +본 조항은 본 허가서의 다른 조항들에서 무엇이 중요하게 고려되어야 하는 지를 명확하게 설명하기 위한 목적으로 만들어진 것입니다 +제 12 조. 특허나 저작권이 설정된 인터페이스로 인해서 특정 국가에서 라이브러리의 배포와 사용이 함께 또는 개별적으로 제한되어 있는 경우, 본 사용 허가서를 라이브러리에 적용한 최초의 저작권자는 문제가 발생하지 않는 국가에 한해서 라이브러리를 배포한다는 배포상의 지역적 제한 조건을 명시적으로 설정할 수 있으며, 이러한 사항은 본 허가서의 일부로 간주됩니다. +제 13 조. 자유 소프트웨어 재단은 때때로 본 사용 허가서의 개정판이나 신판을 공표할 수 있습니다. 새롭게 공표될 판은 당면한 문제나 현안을 처리하기 위해서 세부적인 내용에 차이가 발생할 수 있지만, 그 근본 정신에는 변함이 없을 것입니다. +각각의 판들은 판번호를 사용해서 구별됩니다. 특정한 판번호와 그 이후 판을 따른다는 사항이 명시된 라이브러리에는 해당 판이나 그 이후에 발행된 어떠한 판을 선택해서 적용해도 무방하고, 판번호를 명시하고 있지 않은 경우에는 자유 소프트웨어 재단이 공표한 어떠한 판번호의 판을 적용해도 무방합니다. +제 14 조. 라이브러리의 일부를 본 허가서와 배포 기준이 다른 자유 프로그램과 함께 결합하고자 할 경우에는 해당 프로그램의 저작자로부터 서면 승인을 받아야 합니다. 자유 소프트웨어 재단이 저작권을 갖고 있는 소프트웨어의 경우에는 자유 소프트웨어 재단의 승인을 얻어야 합니다. 우리는 이러한 요청을 수락하기 위해서 때때로 예외 기준을 만들기도 합니다. 자유 소프트웨어 재단은 일반적으로 자유 소프트웨어의 2차적 저작물들을 모두 자유로운 상태로 유지시키려는 목적과 소프트웨어의 공유와 재활용을 증진시키려는 두가지 목적을 기준으로 승인 여부를 결정할 것입니다. +보증의 결여 (제15조, 제16조) + +제 15 조. 본 허가서를 따르는 라이브러리는 무상으로 양도되기 때문에 관련 법률이 허용하는 한도 내에서 어떠한 형태의 보증도 제공되지 않습니다. 라이브러리의 저작권자와 배포자가 공동 또는 개별적으로 별도의 보증을 서면으로 제공할 때를 제외하면, 특정한 목적에 대한 라이브러리의 적합성이나 상업성 여부에 대한 보증을 포함한 어떠한 형태의 보증도 명시적이나 묵시적으로 설정되지 않은 ``있는 그대로의'' 상태로 이 라이브러리를 배포합니다. 라이브러리와 라이브러리의 실행에 따라 발생할 수 있는 모든 위험은 피양도자에게 인수되며 이에 따른 보수 및 복구를 위한 제반 경비 또한 피양도자가 모두 부담해야 합니다. +제 16 조. 저작권자나 배포자가 라이브러리의 손상 가능성을 사전에 알고 있었다 하더라도 발생된 손실이 관련 법규에 의해 보호되고 있거나 이에 대한 별도의 서면 보증이 설정된 경우가 아니라면, 저작권자나 라이브러리를 원래의 상태 또는 개작한 상태로 제공한 배포자는 라이브러리의 사용이나 비작동으로 인해 발생된 손실이나 라이브러리 자체의 손실에 대해 책임지지 않습니다. 이러한 면책 조건은 사용자나 제3자가 라이브러리를 조작함으로써 발생된 손실이나 다른 소프트웨어와 라이브러리를 함께 동작시키는 것으로 인해서 발생된 데이터의 상실 및 부정확한 산출 결과에만 국한되는 것이 아닙니다. 발생된 손실의 일반성이나 특수성 뿐 아니라 원인의 우발성 및 필연성도 전혀 고려되지 않습니다. +복제와 개작 및 배포에 관한 조건과 규정의 끝. +새로운 라이브러리에 LGPL을 적용하는 방법 + +새로운 라이브러리를 개발하고 그 라이브러리가 보다 많은 사람들에게 최대한 유용하게 사용되기를 원한다면, 본 허가서나 GNU 일반 공중 사용 허가서를 선택적으로 적용해서 누구나 자유롭게 개작하고 재배포할 수 있는 자유 소프트웨어로 만드는 것이 최선의 방법입니다. +라이브러리를 자유 소프트웨어로 만들기 위해서는 다음과 같은 사항을 라이브러리에 추가하면 됩니다. 라이브러리에 대한 보증이 제공되지 않는다는 사실을 가장 효과적으로 전달할 수 있는 방법은 원시 코드 파일의 시작 부분에 이러한 사항을 추가하는 것입니다. 각각의 파일에는 최소한 저작권을 명시한 행과 본 사용 허가서의 전체 내용을 참고할 수 있는 위치 정보를 명시해야 합니다. +라이브러리의 이름과 용도를 한 줄 정도로 설명합니다. +Copyright (C) 20yy년 <프로그램 저작자의 이름> +이 라이브러리는 자유 소프트웨어입니다. 소프트웨어의 피양도자는 자유 소프트웨어 재단이 공표한 GNU 약소 일반 공중 사용 허가서 2.1판 또는 그 이후 판을 임의로 선택해서, 그 규정에 따라 라이브러리를 개작하거나 재배포할 수 있습니다. +이 라이브러리는 유용하게 사용될 수 있으리라는 희망에서 배포되고 있지만, 특정한 목적에 맞는 적합성 여부나 판매용으로 사용할 수 있으리라는 묵시적인 보증을 포함한 어떠한 형태의 보증도 제공하지 않습니다. 보다 자세한 사항에 대해서는 GNU 약소 일반 공중 사용 허가서를 참고하시기 바랍니다. +GNU 약소 일반 공중 사용 허가서는 이 라이브러리와 함께 제공됩니다. 만약, 이 문서가 누락되어 있다면 자유 소프트웨어 재단으로 문의하시기 바랍니다. (자유 소프트웨어 재단: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA) +또한, 사용자들이 라이브러리를 배포한 사람에게 전자 메일과 서면으로 연락할 수 있는 정보를 추가해야 합니다. +만약, 라이브러리의 저작자가 학교나 기업과 같은 단체나 기관에 프로그래머로 고용되어 있다면 라이브러리의 자유로운 배포를 위해서 고용주나 해당 기관장으로부터 라이브러리에 대한 저작권 포기 각서를 받아야 합니다. 예를 들면 다음과 같은 형식이 될 수 있다. (아래의 문구를 실제로 사용할 경우에는 예로 사용된 이름들을 실제 이름으로 대체하면 됩니다.) +본사는 제임스 해커가 만든 (설정 옵션을 조정하기 위한) `Frob' 라이브러리에 관련된 모든 저작권을 포기합니다. +1990년 4월 1일 +Yoyodye, Inc., 부사장: Ty Coon +서명: Ty Coon의 서명 + + + +----- LGPL 원문 -------------------------------------------------------- + +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 +Copyright (C) 1991, 1999 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. +This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. +When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. +To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. +For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. +We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. +To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. +Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. +Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. +When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. +We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. +For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. +In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. +Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. +The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". +A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. +The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) +"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. +1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. +2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: +a) The modified work must itself be a software library. +b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. +c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. +d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. +(For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. +In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. +3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. +Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. +This option is useful when you wish to copy part of the code of the Library into a program that is not a library. +4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. +If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. +5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. +However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. +When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. +If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) +Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. +6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. +You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: +a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) +b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. +c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. +d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. +e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. +For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. +It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. +7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: +a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. +b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. +8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. +9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. +10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. +11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. +12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. +13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. +Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. +14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. +NO WARRANTY +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). +To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. +one line to give the library's name and an idea of what it does. +Copyright (C) year name of author + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +Also add information on how to contact you by electronic and paper mail. +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: +Yoyodyne, Inc., hereby disclaims all copyright interest in +the library `Frob' (a library for tweaking knobs) written +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 +Ty Coon, President of Vice +That's all there is to it! + +----- 끝 -------------------------------------------------------- diff --git a/AvocadoEdition/install/gnuboard5.sql b/AvocadoEdition/install/gnuboard5.sql new file mode 100644 index 0000000..cc0e36e --- /dev/null +++ b/AvocadoEdition/install/gnuboard5.sql @@ -0,0 +1,1386 @@ +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_auth` +-- + +DROP TABLE IF EXISTS `avo_auth`; +CREATE TABLE IF NOT EXISTS `avo_auth` ( + `mb_id` varchar(20) NOT NULL default '', + `au_menu` varchar(20) NOT NULL default '', + `au_auth` set('r','w','d') NOT NULL default '', + PRIMARY KEY (`mb_id`,`au_menu`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- +-- +-- Table structure for table `avo_backup` +-- + +DROP TABLE IF EXISTS `avo_backup`; +CREATE TABLE IF NOT EXISTS `avo_backup` ( + `ba_id` int(11) NOT NULL auto_increment, + `ba_cate` varchar(255) NOT NULL DEFAULT '', + `ba_title` varchar(255) NOT NULL DEFAULT '', + `ba_path` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`ba_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + +-- -------------------------------------------------------- +-- +-- Table structure for table `avo_board` +-- + +DROP TABLE IF EXISTS `avo_board`; +CREATE TABLE IF NOT EXISTS `avo_board` ( + `bo_table` varchar(20) NOT NULL DEFAULT '', + `bo_type` varchar(20) NOT NULL DEFAULT '', + `gr_id` varchar(255) NOT NULL DEFAULT '', + `bo_subject` varchar(255) NOT NULL DEFAULT '', + `bo_mobile_subject` varchar(255) NOT NULL DEFAULT '', + `bo_device` enum('both','pc','mobile') NOT NULL DEFAULT 'both', + `bo_admin` varchar(255) NOT NULL DEFAULT '', + `bo_list_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_read_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_write_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_reply_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_comment_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_upload_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_download_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_html_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_link_level` tinyint(4) NOT NULL DEFAULT '0', + `bo_count_delete` tinyint(4) NOT NULL DEFAULT '0', + `bo_count_modify` tinyint(4) NOT NULL DEFAULT '0', + `bo_read_point` int(11) NOT NULL DEFAULT '0', + `bo_write_point` int(11) NOT NULL DEFAULT '0', + `bo_comment_point` int(11) NOT NULL DEFAULT '0', + `bo_download_point` int(11) NOT NULL DEFAULT '0', + `bo_use_category` tinyint(4) NOT NULL DEFAULT '0', + `bo_category_list` text NOT NULL, + `bo_use_sideview` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_file_content` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_secret` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_dhtml_editor` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_rss_view` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_good` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_nogood` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_name` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_signature` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_ip_view` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_list_view` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_list_file` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_list_content` tinyint(4) NOT NULL DEFAULT '0', + `bo_table_width` int(11) NOT NULL DEFAULT '0', + `bo_subject_len` int(11) NOT NULL DEFAULT '0', + `bo_mobile_subject_len` int(11) NOT NULL DEFAULT '0', + `bo_page_rows` int(11) NOT NULL DEFAULT '0', + `bo_mobile_page_rows` int(11) NOT NULL DEFAULT '0', + `bo_new` int(11) NOT NULL DEFAULT '0', + `bo_hot` int(11) NOT NULL DEFAULT '0', + `bo_image_width` int(11) NOT NULL DEFAULT '0', + `bo_skin` varchar(255) NOT NULL DEFAULT '', + `bo_mobile_skin` varchar(255) NOT NULL DEFAULT '', + `bo_include_head` varchar(255) NOT NULL DEFAULT '', + `bo_include_tail` varchar(255) NOT NULL DEFAULT '', + `bo_content_head` text NOT NULL, + `bo_mobile_content_head` text NOT NULL, + `bo_content_tail` text NOT NULL, + `bo_mobile_content_tail` text NOT NULL, + `bo_insert_content` text NOT NULL, + `bo_gallery_cols` int(11) NOT NULL DEFAULT '0', + `bo_gallery_width` int(11) NOT NULL DEFAULT '0', + `bo_gallery_height` int(11) NOT NULL DEFAULT '0', + `bo_mobile_gallery_width` int(11) NOT NULL DEFAULT '0', + `bo_mobile_gallery_height` int(11) NOT NULL DEFAULT '0', + `bo_upload_size` int(11) NOT NULL DEFAULT '0', + `bo_reply_order` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_search` tinyint(4) NOT NULL DEFAULT '0', + `bo_order` int(11) NOT NULL DEFAULT '0', + `bo_count_write` int(11) NOT NULL DEFAULT '0', + `bo_count_comment` int(11) NOT NULL DEFAULT '0', + `bo_write_min` int(11) NOT NULL DEFAULT '0', + `bo_write_max` int(11) NOT NULL DEFAULT '0', + `bo_comment_min` int(11) NOT NULL DEFAULT '0', + `bo_comment_max` int(11) NOT NULL DEFAULT '0', + `bo_notice` text NOT NULL, + `bo_upload_count` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_email` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_cert` enum('','cert','adult','hp-cert','hp-adult') NOT NULL DEFAULT '', + `bo_use_sns` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_chick` tinyint(4) NOT NULL DEFAULT '0', + `bo_use_noname` tinyint(4) NOT NULL DEFAULT '0', + `bo_sort_field` varchar(255) NOT NULL DEFAULT '', + `bo_1_subj` varchar(255) NOT NULL DEFAULT '', + `bo_2_subj` varchar(255) NOT NULL DEFAULT '', + `bo_3_subj` varchar(255) NOT NULL DEFAULT '', + `bo_4_subj` varchar(255) NOT NULL DEFAULT '', + `bo_5_subj` varchar(255) NOT NULL DEFAULT '', + `bo_6_subj` varchar(255) NOT NULL DEFAULT '', + `bo_7_subj` varchar(255) NOT NULL DEFAULT '', + `bo_8_subj` varchar(255) NOT NULL DEFAULT '', + `bo_9_subj` varchar(255) NOT NULL DEFAULT '', + `bo_10_subj` varchar(255) NOT NULL DEFAULT '', + `bo_1` varchar(255) NOT NULL DEFAULT '', + `bo_2` varchar(255) NOT NULL DEFAULT '', + `bo_3` varchar(255) NOT NULL DEFAULT '', + `bo_4` varchar(255) NOT NULL DEFAULT '', + `bo_5` varchar(255) NOT NULL DEFAULT '', + `bo_6` varchar(255) NOT NULL DEFAULT '', + `bo_7` varchar(255) NOT NULL DEFAULT '', + `bo_8` varchar(255) NOT NULL DEFAULT '', + `bo_9` varchar(255) NOT NULL DEFAULT '', + `bo_10` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`bo_table`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_board_file` +-- + +DROP TABLE IF EXISTS `avo_board_file`; +CREATE TABLE IF NOT EXISTS `avo_board_file` ( + `bo_table` varchar(20) NOT NULL default '', + `wr_id` int(11) NOT NULL default '0', + `bf_no` int(11) NOT NULL default '0', + `bf_source` varchar(255) NOT NULL default '', + `bf_file` varchar(255) NOT NULL default '', + `bf_download` int(11) NOT NULL DEFAULT '0', + `bf_content` text NOT NULL, + `bf_filesize` int(11) NOT NULL default '0', + `bf_width` int(11) NOT NULL default '0', + `bf_height` smallint(6) NOT NULL default '0', + `bf_type` tinyint(4) NOT NULL default '0', + `bf_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (`bo_table`,`wr_id`,`bf_no`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_board_good` +-- + +DROP TABLE IF EXISTS `avo_board_good`; +CREATE TABLE IF NOT EXISTS `avo_board_good` ( + `bg_id` int(11) NOT NULL auto_increment, + `bo_table` varchar(20) NOT NULL default '', + `wr_id` int(11) NOT NULL default '0', + `mb_id` varchar(20) NOT NULL default '', + `bg_flag` varchar(255) NOT NULL default '', + `bg_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (`bg_id`), + UNIQUE KEY `fkey1` (`bo_table`,`wr_id`,`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_board_new` +-- + +DROP TABLE IF EXISTS `avo_board_new`; +CREATE TABLE IF NOT EXISTS `avo_board_new` ( + `bn_id` int(11) NOT NULL auto_increment, + `bo_table` varchar(20) NOT NULL default '', + `wr_id` int(11) NOT NULL default '0', + `ca_name` varchar(255) NOT NULL default '', + `wr_parent` int(11) NOT NULL default '0', + `bn_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `mb_id` varchar(20) NOT NULL default '', + PRIMARY KEY (`bn_id`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_config` +-- + +DROP TABLE IF EXISTS `avo_config`; +CREATE TABLE IF NOT EXISTS `avo_config` ( + `cf_title` varchar(255) NOT NULL DEFAULT '', + `cf_theme` varchar(255) NOT NULL DEFAULT '', + `cf_admin` varchar(255) NOT NULL DEFAULT '', + `cf_admin_email` varchar(255) NOT NULL DEFAULT '', + `cf_admin_email_name` varchar(255) NOT NULL DEFAULT '', + `cf_add_script` text NOT NULL, + `cf_use_point` tinyint(4) NOT NULL DEFAULT '0', + `cf_point_term` int(11) NOT NULL DEFAULT '0', + `cf_use_copy_log` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_email_certify` tinyint(4) NOT NULL DEFAULT '0', + `cf_login_point` int(11) NOT NULL DEFAULT '0', + `cf_cut_name` tinyint(4) NOT NULL DEFAULT '0', + `cf_nick_modify` int(11) NOT NULL DEFAULT '0', + `cf_new_skin` varchar(255) NOT NULL DEFAULT '', + `cf_new_rows` int(11) NOT NULL DEFAULT '0', + `cf_search_skin` varchar(255) NOT NULL DEFAULT '', + `cf_connect_skin` varchar(255) NOT NULL DEFAULT '', + `cf_faq_skin` varchar(255) NOT NULL DEFAULT '', + `cf_read_point` int(11) NOT NULL DEFAULT '0', + `cf_write_point` int(11) NOT NULL DEFAULT '0', + `cf_comment_point` int(11) NOT NULL DEFAULT '0', + `cf_download_point` int(11) NOT NULL DEFAULT '0', + `cf_write_pages` int(11) NOT NULL DEFAULT '0', + `cf_mobile_pages` int(11) NOT NULL DEFAULT '0', + `cf_link_target` varchar(255) NOT NULL DEFAULT '', + `cf_delay_sec` int(11) NOT NULL DEFAULT '0', + `cf_filter` text NOT NULL, + `cf_possible_ip` text NOT NULL, + `cf_intercept_ip` text NOT NULL, + `cf_analytics` text NOT NULL, + `cf_add_meta` text NOT NULL, + `cf_member_skin` varchar(255) NOT NULL DEFAULT '', + `cf_use_homepage` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_homepage` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_tel` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_tel` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_hp` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_hp` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_addr` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_addr` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_signature` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_signature` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_profile` tinyint(4) NOT NULL DEFAULT '0', + `cf_req_profile` tinyint(4) NOT NULL DEFAULT '0', + `cf_register_level` tinyint(4) NOT NULL DEFAULT '0', + `cf_register_point` int(11) NOT NULL DEFAULT '0', + `cf_icon_level` tinyint(4) NOT NULL DEFAULT '0', + `cf_use_recommend` tinyint(4) NOT NULL DEFAULT '0', + `cf_recommend_point` int(11) NOT NULL DEFAULT '0', + `cf_leave_day` int(11) NOT NULL DEFAULT '0', + `cf_search_part` int(11) NOT NULL DEFAULT '0', + `cf_email_use` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_wr_super_admin` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_wr_group_admin` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_wr_board_admin` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_wr_write` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_wr_comment_all` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_mb_super_admin` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_mb_member` tinyint(4) NOT NULL DEFAULT '0', + `cf_email_po_super_admin` tinyint(4) NOT NULL DEFAULT '0', + `cf_prohibit_id` text NOT NULL, + `cf_prohibit_email` text NOT NULL, + `cf_new_del` int(11) NOT NULL DEFAULT '0', + `cf_memo_del` int(11) NOT NULL DEFAULT '0', + `cf_visit_del` int(11) NOT NULL DEFAULT '0', + `cf_popular_del` int(11) NOT NULL DEFAULT '0', + `cf_optimize_date` date NOT NULL default '0000-00-00', + `cf_use_member_icon` tinyint(4) NOT NULL DEFAULT '0', + `cf_member_icon_size` int(11) NOT NULL DEFAULT '0', + `cf_member_icon_width` int(11) NOT NULL DEFAULT '0', + `cf_member_icon_height` int(11) NOT NULL DEFAULT '0', + `cf_login_minutes` int(11) NOT NULL DEFAULT '0', + `cf_image_extension` varchar(255) NOT NULL DEFAULT '', + `cf_flash_extension` varchar(255) NOT NULL DEFAULT '', + `cf_movie_extension` varchar(255) NOT NULL DEFAULT '', + `cf_formmail_is_member` tinyint(4) NOT NULL DEFAULT '0', + `cf_page_rows` int(11) NOT NULL DEFAULT '0', + `cf_mobile_page_rows` int(11) NOT NULL DEFAULT '0', + `cf_visit` varchar(255) NOT NULL DEFAULT '', + `cf_max_po_id` int(11) NOT NULL DEFAULT '0', + `cf_stipulation` text NOT NULL, + `cf_privacy` text NOT NULL, + `cf_open_modify` int(11) NOT NULL DEFAULT '0', + `cf_memo_send_point` int(11) NOT NULL DEFAULT '0', + `cf_mobile_new_skin` varchar(255) NOT NULL DEFAULT '', + `cf_mobile_search_skin` varchar(255) NOT NULL DEFAULT '', + `cf_mobile_connect_skin` varchar(255) NOT NULL DEFAULT '', + `cf_mobile_faq_skin` varchar(255) NOT NULL DEFAULT '', + `cf_mobile_member_skin` varchar(255) NOT NULL DEFAULT '', + `cf_captcha_mp3` varchar(255) NOT NULL DEFAULT '', + `cf_editor` varchar(255) NOT NULL DEFAULT '', + `cf_cert_use` tinyint(4) NOT NULL DEFAULT '0', + `cf_cert_ipin` varchar(255) NOT NULL DEFAULT '', + `cf_cert_hp` varchar(255) NOT NULL DEFAULT '', + `cf_cert_kcb_cd` varchar(255) NOT NULL DEFAULT '', + `cf_cert_kcp_cd` varchar(255) NOT NULL DEFAULT '', + `cf_lg_mid` varchar(255) NOT NULL DEFAULT '', + `cf_lg_mert_key` varchar(255) NOT NULL DEFAULT '', + `cf_cert_limit` int(11) NOT NULL DEFAULT '0', + `cf_cert_req` tinyint(4) NOT NULL DEFAULT '0', + `cf_sms_use` varchar(255) NOT NULL DEFAULT '', + `cf_sms_type` varchar(10) NOT NULL DEFAULT '', + `cf_icode_id` varchar(255) NOT NULL DEFAULT '', + `cf_icode_pw` varchar(255) NOT NULL DEFAULT '', + `cf_icode_server_ip` varchar(255) NOT NULL DEFAULT '', + `cf_icode_server_port` varchar(255) NOT NULL DEFAULT '', + `cf_googl_shorturl_apikey` varchar(255) NOT NULL DEFAULT '', + `cf_facebook_appid` varchar(255) NOT NULL DEFAULT '', + `cf_facebook_secret` varchar(255) NOT NULL DEFAULT '', + `cf_twitter_key` varchar(255) NOT NULL DEFAULT '', + `cf_twitter_secret` varchar(255) NOT NULL DEFAULT '', + `cf_kakao_js_apikey` varchar(255) NOT NULL DEFAULT '', + `cf_bgm` varchar(255) NOT NULL DEFAULT '', + `cf_open` tinyint(4) NOT NULL DEFAULT '0', + `cf_twitter` varchar(255) NOT NULL DEFAULT '', + `cf_side_title` varchar(255) NOT NULL DEFAULT '', + `cf_class_title` varchar(255) NOT NULL DEFAULT '', + `cf_shop_category` varchar(255) NOT NULL DEFAULT '', + `cf_item_category` varchar(255) NOT NULL DEFAULT '', + `cf_site_descript` varchar(255) NOT NULL DEFAULT '', + `cf_site_img` varchar(255) NOT NULL DEFAULT '', + `cf_favicon` varchar(255) NOT NULL DEFAULT '', + `cf_character_count` int(11) NOT NULL DEFAULT '0', + `cf_search_count` int(11) NOT NULL DEFAULT '0', + `cf_status_point` int(11) NOT NULL DEFAULT '0', + `cf_money` varchar(255) NOT NULL DEFAULT '', + `cf_money_pice` varchar(255) NOT NULL DEFAULT '', + `cf_exp_name` varchar(255) NOT NULL DEFAULT '', + `cf_exp_pice` varchar(255) NOT NULL DEFAULT '', + `cf_rank_name` varchar(255) NOT NULL DEFAULT '', + `cf_1` varchar(255) NOT NULL DEFAULT '', + `cf_2` varchar(255) NOT NULL DEFAULT '', + `cf_3` varchar(255) NOT NULL DEFAULT '', + `cf_4` varchar(255) NOT NULL DEFAULT '', + `cf_5` varchar(255) NOT NULL DEFAULT '', + `cf_6` varchar(255) NOT NULL DEFAULT '', + `cf_7` varchar(255) NOT NULL DEFAULT '', + `cf_8` varchar(255) NOT NULL DEFAULT '', + `cf_9` varchar(255) NOT NULL DEFAULT '', + `cf_10` varchar(255) NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_cert_history` +-- + +DROP TABLE IF EXISTS `avo_cert_history`; +CREATE TABLE IF NOT EXISTS `avo_cert_history` ( + `cr_id` int(11) NOT NULL auto_increment, + `mb_id` varchar(20) NOT NULL DEFAULT '', + `cr_company` varchar(255) NOT NULL DEFAULT '', + `cr_method` varchar(255) NOT NULL DEFAULT '', + `cr_ip` varchar(255) NOT NULL DEFAULT '', + `cr_date` date NOT NULL DEFAULT '0000-00-00', + `cr_time` time NOT NULL DEFAULT '00:00:00', + PRIMARY KEY (`cr_id`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_group` +-- + +DROP TABLE IF EXISTS `avo_group`; +CREATE TABLE IF NOT EXISTS `avo_group` ( + `gr_id` varchar(10) NOT NULL default '', + `gr_subject` varchar(255) NOT NULL default '', + `gr_device` ENUM('both','pc','mobile') NOT NULL DEFAULT 'both', + `gr_admin` varchar(255) NOT NULL default '', + `gr_use_access` tinyint(4) NOT NULL default '0', + `gr_order` int(11) NOT NULL default '0', + `gr_1_subj` varchar(255) NOT NULL default '', + `gr_2_subj` varchar(255) NOT NULL default '', + `gr_3_subj` varchar(255) NOT NULL default '', + `gr_4_subj` varchar(255) NOT NULL default '', + `gr_5_subj` varchar(255) NOT NULL default '', + `gr_6_subj` varchar(255) NOT NULL default '', + `gr_7_subj` varchar(255) NOT NULL default '', + `gr_8_subj` varchar(255) NOT NULL default '', + `gr_9_subj` varchar(255) NOT NULL default '', + `gr_10_subj` varchar(255) NOT NULL default '', + `gr_1` varchar(255) NOT NULL default '', + `gr_2` varchar(255) NOT NULL default '', + `gr_3` varchar(255) NOT NULL default '', + `gr_4` varchar(255) NOT NULL default '', + `gr_5` varchar(255) NOT NULL default '', + `gr_6` varchar(255) NOT NULL default '', + `gr_7` varchar(255) NOT NULL default '', + `gr_8` varchar(255) NOT NULL default '', + `gr_9` varchar(255) NOT NULL default '', + `gr_10` varchar(255) NOT NULL default '', + PRIMARY KEY (`gr_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_group_member` +-- + +DROP TABLE IF EXISTS `avo_group_member`; +CREATE TABLE IF NOT EXISTS `avo_group_member` ( + `gm_id` int(11) NOT NULL auto_increment, + `gr_id` varchar(255) NOT NULL default '', + `mb_id` varchar(20) NOT NULL default '', + `gm_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (`gm_id`), + KEY `gr_id` (`gr_id`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_login` +-- + +DROP TABLE IF EXISTS `avo_login`; +CREATE TABLE IF NOT EXISTS `avo_login` ( + `lo_ip` varchar(255) NOT NULL default '', + `mb_id` varchar(20) NOT NULL default '', + `lo_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `lo_location` text NOT NULL, + `lo_url` text NOT NULL, + PRIMARY KEY (`lo_ip`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_mail` +-- + +DROP TABLE IF EXISTS `avo_mail`; +CREATE TABLE IF NOT EXISTS `avo_mail` ( + `ma_id` int(11) NOT NULL auto_increment, + `ma_subject` varchar(255) NOT NULL default '', + `ma_content` mediumtext NOT NULL, + `ma_time` datetime NOT NULL default '0000-00-00 00:00:00', + `ma_ip` varchar(255) NOT NULL default '', + `ma_last_option` text NOT NULL, + PRIMARY KEY (`ma_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_member` +-- + +DROP TABLE IF EXISTS `avo_member`; +CREATE TABLE IF NOT EXISTS `avo_member` ( + `mb_no` int(11) NOT NULL auto_increment, + `mb_id` varchar(20) NOT NULL default '', + `ch_id` int(11) NOT NULL default '0', + `mb_password` varchar(255) NOT NULL default '', + `mb_name` varchar(255) NOT NULL default '', + `mb_nick` varchar(255) NOT NULL default '', + `mb_nick_date` date NOT NULL default '0000-00-00', + `mb_email` varchar(255) NOT NULL default '', + `mb_homepage` varchar(255) NOT NULL default '', + `mb_level` tinyint(4) NOT NULL default '0', + `mb_sex` char(1) NOT NULL default '', + `mb_birth` varchar(255) NOT NULL default '', + `mb_tel` varchar(255) NOT NULL default '', + `mb_hp` varchar(255) NOT NULL default '', + `mb_certify` varchar(20) NOT NULL default '', + `mb_adult` tinyint(4) NOT NULL default '0', + `mb_dupinfo` varchar(255) NOT NULL default '', + `mb_zip1` char(3) NOT NULL default '', + `mb_zip2` char(3) NOT NULL default '', + `mb_addr1` varchar(255) NOT NULL default '', + `mb_addr2` varchar(255) NOT NULL default '', + `mb_addr3` varchar(255) NOT NULL default '', + `mb_addr_jibeon` varchar(255) NOT NULL default '', + `mb_signature` text NOT NULL, + `mb_recommend` varchar(255) NOT NULL default '', + `mb_point` int(11) NOT NULL default '0', + `mb_today_login` datetime NOT NULL default '0000-00-00 00:00:00', + `mb_login_ip` varchar(255) NOT NULL default '', + `mb_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `mb_ip` varchar(255) NOT NULL default '', + `mb_leave_date` varchar(8) NOT NULL default '', + `mb_intercept_date` varchar(8) NOT NULL default '', + `mb_email_certify` datetime NOT NULL default '0000-00-00 00:00:00', + `mb_email_certify2` varchar(255) NOT NULL default '', + `mb_memo` text NOT NULL, + `mb_lost_certify` varchar(255) NOT NULL DEFAULT '', + `mb_mailling` tinyint(4) NOT NULL default '0', + `mb_sms` tinyint(4) NOT NULL default '0', + `mb_open` tinyint(4) NOT NULL default '0', + `mb_open_date` date NOT NULL default '0000-00-00', + `mb_profile` text NOT NULL, + `mb_memo_call` varchar(255) NOT NULL default '', + `mb_board_call` varchar(255) NOT NULL default '', + `mb_board_link` varchar(255) NOT NULL default '', + `mb_1` varchar(255) NOT NULL default '', + `mb_2` varchar(255) NOT NULL default '', + `mb_3` varchar(255) NOT NULL default '', + `mb_4` varchar(255) NOT NULL default '', + `mb_5` varchar(255) NOT NULL default '', + `mb_6` varchar(255) NOT NULL default '', + `mb_7` varchar(255) NOT NULL default '', + `mb_8` varchar(255) NOT NULL default '', + `mb_9` varchar(255) NOT NULL default '', + `mb_10` varchar(255) NOT NULL default '', + PRIMARY KEY (`mb_no`), + UNIQUE KEY `mb_id` (`mb_id`), + KEY `mb_today_login` (`mb_today_login`), + KEY `mb_datetime` (`mb_datetime`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_memo` +-- + +DROP TABLE IF EXISTS `avo_memo`; +CREATE TABLE IF NOT EXISTS `avo_memo` ( + `me_id` int(11) NOT NULL default '0', + `me_recv_mb_id` varchar(20) NOT NULL default '', + `me_send_mb_id` varchar(20) NOT NULL default '', + `me_send_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `me_read_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `me_memo` text NOT NULL, + PRIMARY KEY (`me_id`), + KEY `me_recv_mb_id` (`me_recv_mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_point` +-- + +DROP TABLE IF EXISTS `avo_point`; +CREATE TABLE IF NOT EXISTS `avo_point` ( + `po_id` int(11) NOT NULL auto_increment, + `mb_id` varchar(20) NOT NULL default '', + `po_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + `po_content` varchar(255) NOT NULL default '', + `po_point` int(11) NOT NULL default '0', + `po_use_point` int(11) NOT NULL default '0', + `po_expired` tinyint(4) NOT NULL default '0', + `po_expire_date` date NOT NULL default '0000-00-00', + `po_mb_point` int(11) NOT NULL default '0', + `po_rel_table` varchar(20) NOT NULL default '', + `po_rel_id` varchar(20) NOT NULL default '', + `po_rel_action` varchar(255) NOT NULL default '', + PRIMARY KEY (`po_id`), + KEY `index1` (`mb_id`,`po_rel_table`,`po_rel_id`,`po_rel_action`), + KEY `index2` (`po_expire_date`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_poll` +-- + +DROP TABLE IF EXISTS `avo_poll`; +CREATE TABLE IF NOT EXISTS `avo_poll` ( + `po_id` int(11) NOT NULL auto_increment, + `po_subject` varchar(255) NOT NULL default '', + `po_poll1` varchar(255) NOT NULL default '', + `po_poll2` varchar(255) NOT NULL default '', + `po_poll3` varchar(255) NOT NULL default '', + `po_poll4` varchar(255) NOT NULL default '', + `po_poll5` varchar(255) NOT NULL default '', + `po_poll6` varchar(255) NOT NULL default '', + `po_poll7` varchar(255) NOT NULL default '', + `po_poll8` varchar(255) NOT NULL default '', + `po_poll9` varchar(255) NOT NULL default '', + `po_cnt1` int(11) NOT NULL default '0', + `po_cnt2` int(11) NOT NULL default '0', + `po_cnt3` int(11) NOT NULL default '0', + `po_cnt4` int(11) NOT NULL default '0', + `po_cnt5` int(11) NOT NULL default '0', + `po_cnt6` int(11) NOT NULL default '0', + `po_cnt7` int(11) NOT NULL default '0', + `po_cnt8` int(11) NOT NULL default '0', + `po_cnt9` int(11) NOT NULL default '0', + `po_etc` varchar(255) NOT NULL default '', + `po_level` tinyint(4) NOT NULL default '0', + `po_point` int(11) NOT NULL default '0', + `po_date` date NOT NULL default '0000-00-00', + `po_ips` mediumtext NOT NULL, + `mb_ids` text NOT NULL, + PRIMARY KEY (`po_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_poll_etc` +-- + +DROP TABLE IF EXISTS `avo_poll_etc`; +CREATE TABLE IF NOT EXISTS `avo_poll_etc` ( + `pc_id` int(11) NOT NULL default '0', + `po_id` int(11) NOT NULL default '0', + `mb_id` varchar(20) NOT NULL default '', + `pc_name` varchar(255) NOT NULL default '', + `pc_idea` varchar(255) NOT NULL default '', + `pc_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (`pc_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_popular` +-- + +DROP TABLE IF EXISTS `avo_popular`; +CREATE TABLE IF NOT EXISTS `avo_popular` ( + `pp_id` int(11) NOT NULL auto_increment, + `pp_word` varchar(50) NOT NULL default '', + `pp_date` date NOT NULL default '0000-00-00', + `pp_ip` varchar(50) NOT NULL default '', + PRIMARY KEY (`pp_id`), + UNIQUE KEY `index1` (`pp_date`,`pp_word`,`pp_ip`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_scrap` +-- + +DROP TABLE IF EXISTS `avo_scrap`; +CREATE TABLE IF NOT EXISTS `avo_scrap` ( + `ms_id` int(11) NOT NULL auto_increment, + `mb_id` varchar(20) NOT NULL default '', + `bo_table` varchar(20) NOT NULL default '', + `wr_id` varchar(15) NOT NULL default '', + `ms_datetime` datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (`ms_id`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_visit` +-- + +DROP TABLE IF EXISTS `avo_visit`; +CREATE TABLE IF NOT EXISTS `avo_visit` ( + `vi_id` int(11) NOT NULL default '0', + `vi_ip` varchar(255) NOT NULL default '', + `vi_date` date NOT NULL default '0000-00-00', + `vi_time` time NOT NULL default '00:00:00', + `vi_referer` text NOT NULL, + `vi_agent` varchar(255) NOT NULL default '', + PRIMARY KEY (`vi_id`), + UNIQUE KEY `index1` (`vi_ip`,`vi_date`), + KEY `index2` (`vi_date`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_visit_sum` +-- + +DROP TABLE IF EXISTS `avo_visit_sum`; +CREATE TABLE IF NOT EXISTS `avo_visit_sum` ( + `vs_date` date NOT NULL default '0000-00-00', + `vs_count` int(11) NOT NULL default '0', + PRIMARY KEY (`vs_date`), + KEY `index1` (`vs_count`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_unique` +-- + +DROP TABLE IF EXISTS `avo_uniqid`; +CREATE TABLE IF NOT EXISTS `avo_uniqid` ( + `uq_id` bigint(20) unsigned NOT NULL, + `uq_ip` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`uq_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_autosave` +-- + +DROP TABLE IF EXISTS `avo_autosave`; +CREATE TABLE IF NOT EXISTS `avo_autosave` ( + `as_id` int(11) NOT NULL AUTO_INCREMENT, + `mb_id` varchar(20) NOT NULL, + `as_uid` bigint(20) unsigned NOT NULL, + `as_subject` varchar(255) NOT NULL DEFAULT '', + `as_content` text NOT NULL, + `as_datetime` datetime NOT NULL, + PRIMARY KEY (`as_id`), + UNIQUE KEY `as_uid` (`as_uid`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_qa_config` +-- + +DROP TABLE IF EXISTS `avo_qa_config`; +CREATE TABLE IF NOT EXISTS `avo_qa_config` ( + `qa_title` varchar(255) NOT NULL DEFAULT'', + `qa_category` varchar(255) NOT NULL DEFAULT'', + `qa_skin` varchar(255) NOT NULL DEFAULT '', + `qa_mobile_skin` varchar(255) NOT NULL DEFAULT '', + `qa_use_email` tinyint(4) NOT NULL DEFAULT '0', + `qa_req_email` tinyint(4) NOT NULL DEFAULT '0', + `qa_use_hp` tinyint(4) NOT NULL DEFAULT '0', + `qa_req_hp` tinyint(4) NOT NULL DEFAULT '0', + `qa_use_sms` tinyint(4) NOT NULL DEFAULT '0', + `qa_send_number` varchar(255) NOT NULL DEFAULT '0', + `qa_admin_hp` varchar(255) NOT NULL DEFAULT '', + `qa_admin_email` varchar(255) NOT NULL DEFAULT '', + `qa_use_editor` tinyint(4) NOT NULL DEFAULT '0', + `qa_subject_len` int(11) NOT NULL DEFAULT '0', + `qa_mobile_subject_len` int(11) NOT NULL DEFAULT '0', + `qa_page_rows` int(11) NOT NULL DEFAULT '0', + `qa_mobile_page_rows` int(11) NOT NULL DEFAULT '0', + `qa_image_width` int(11) NOT NULL DEFAULT '0', + `qa_upload_size` int(11) NOT NULL DEFAULT '0', + `qa_insert_content` text NOT NULL, + `qa_include_head` varchar(255) NOT NULL DEFAULT '', + `qa_include_tail` varchar(255) NOT NULL DEFAULT '', + `qa_content_head` text NOT NULL, + `qa_content_tail` text NOT NULL, + `qa_mobile_content_head` text NOT NULL, + `qa_mobile_content_tail` text NOT NULL, + `qa_1_subj` varchar(255) NOT NULL DEFAULT '', + `qa_2_subj` varchar(255) NOT NULL DEFAULT '', + `qa_3_subj` varchar(255) NOT NULL DEFAULT '', + `qa_4_subj` varchar(255) NOT NULL DEFAULT '', + `qa_5_subj` varchar(255) NOT NULL DEFAULT '', + `qa_1` varchar(255) NOT NULL DEFAULT '', + `qa_2` varchar(255) NOT NULL DEFAULT '', + `qa_3` varchar(255) NOT NULL DEFAULT '', + `qa_4` varchar(255) NOT NULL DEFAULT '', + `qa_5` varchar(255) NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_qa_content` +-- + +DROP TABLE IF EXISTS `avo_qa_content`; +CREATE TABLE IF NOT EXISTS `avo_qa_content` ( + `qa_id` int(11) NOT NULL AUTO_INCREMENT, + `qa_num` int(11) NOT NULL DEFAULT '0', + `qa_parent` int(11) NOT NULL DEFAULT '0', + `qa_related` int(11) NOT NULL DEFAULT '0', + `mb_id` varchar(20) NOT NULL DEFAULT '', + `qa_name` varchar(255) NOT NULL DEFAULT '', + `qa_email` varchar(255) NOT NULL DEFAULT '', + `qa_hp` varchar(255) NOT NULL DEFAULT '', + `qa_type` tinyint(4) NOT NULL DEFAULT '0', + `qa_category` varchar(255) NOT NULL DEFAULT '', + `qa_email_recv` tinyint(4) NOT NULL DEFAULT '0', + `qa_sms_recv` tinyint(4) NOT NULL DEFAULT '0', + `qa_html` tinyint(4) NOT NULL DEFAULT '0', + `qa_subject` varchar(255) NOT NULL DEFAULT '', + `qa_content` text NOT NULL, + `qa_status` tinyint(4) NOT NULL DEFAULT '0', + `qa_file1` varchar(255) NOT NULL DEFAULT '', + `qa_source1` varchar(255) NOT NULL DEFAULT '', + `qa_file2` varchar(255) NOT NULL DEFAULT '', + `qa_source2` varchar(255) NOT NULL DEFAULT '', + `qa_ip` varchar(255) NOT NULL DEFAULT '', + `qa_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `qa_1` varchar(255) NOT NULL DEFAULT '', + `qa_2` varchar(255) NOT NULL DEFAULT '', + `qa_3` varchar(255) NOT NULL DEFAULT '', + `qa_4` varchar(255) NOT NULL DEFAULT '', + `qa_5` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`qa_id`), + KEY `qa_num_parent` (`qa_num`,`qa_parent`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_content` +-- + +DROP TABLE IF EXISTS `avo_content`; +CREATE TABLE IF NOT EXISTS `avo_content` ( + `co_id` varchar(20) NOT NULL DEFAULT '', + `co_html` tinyint(4) NOT NULL DEFAULT '0', + `co_subject` varchar(255) NOT NULL DEFAULT '', + `co_content` longtext NOT NULL, + `co_mobile_content` longtext NOT NULL, + `co_skin` varchar(255) NOT NULL DEFAULT '', + `co_mobile_skin` varchar(255) NOT NULL DEFAULT '', + `co_tag_filter_use` tinyint(4) NOT NULL DEFAULT '0', + `co_hit` int(11) NOT NULL DEFAULT '0', + `co_include_head` varchar(255) NOT NULL DEFAULT '', + `co_include_tail` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`co_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_faq` +-- + +DROP TABLE IF EXISTS `avo_faq`; +CREATE TABLE IF NOT EXISTS `avo_faq` ( + `fa_id` int(11) NOT NULL AUTO_INCREMENT, + `fm_id` int(11) NOT NULL DEFAULT '0', + `fa_subject` text NOT NULL, + `fa_content` text NOT NULL, + `fa_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`fa_id`), + KEY `fm_id` (`fm_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_faq_master` +-- + +DROP TABLE IF EXISTS `avo_faq_master`; +CREATE TABLE IF NOT EXISTS `avo_faq_master` ( + `fm_id` int(11) NOT NULL AUTO_INCREMENT, + `fm_subject` varchar(255) NOT NULL DEFAULT '', + `fm_head_html` text NOT NULL, + `fm_tail_html` text NOT NULL, + `fm_mobile_head_html` text NOT NULL, + `fm_mobile_tail_html` text NOT NULL, + `fm_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`fm_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_new_win` +-- + +DROP TABLE IF EXISTS `avo_new_win`; +CREATE TABLE IF NOT EXISTS `avo_new_win` ( + `nw_id` int(11) NOT NULL AUTO_INCREMENT, + `nw_device` varchar(10) NOT NULL DEFAULT 'both', + `nw_begin_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `nw_end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `nw_disable_hours` int(11) NOT NULL DEFAULT '0', + `nw_left` int(11) NOT NULL DEFAULT '0', + `nw_top` int(11) NOT NULL DEFAULT '0', + `nw_height` int(11) NOT NULL DEFAULT '0', + `nw_width` int(11) NOT NULL DEFAULT '0', + `nw_subject` text NOT NULL, + `nw_content` text NOT NULL, + `nw_content_html` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`nw_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_menu` +-- + +DROP TABLE IF EXISTS `avo_menu`; +CREATE TABLE IF NOT EXISTS `avo_menu` ( + `me_id` int(11) NOT NULL AUTO_INCREMENT, + `me_code` varchar(255) NOT NULL DEFAULT '', + `me_name` varchar(255) NOT NULL DEFAULT '', + `me_link` varchar(255) NOT NULL DEFAULT '', + `me_target` varchar(255) NOT NULL DEFAULT '', + `me_order` int(11) NOT NULL DEFAULT '0', + `me_use` tinyint(4) NOT NULL DEFAULT '0', + `me_mobile_use` tinyint(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`me_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + + +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_exp` +-- +DROP TABLE IF EXISTS `avo_exp`; +CREATE TABLE IF NOT EXISTS `avo_exp` ( + `ex_id` int(11) NOT NULL AUTO_INCREMENT, + `ch_id` varchar(20) NOT NULL DEFAULT '', + `ch_name` varchar(255) NOT NULL DEFAULT '', + `ex_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `ex_content` varchar(255) NOT NULL DEFAULT '', + `ex_point` int(11) NOT NULL DEFAULT '0', + `ex_ch_exp` int(11) NOT NULL DEFAULT '0', + `ex_rel_action` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`ex_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_character` +-- +DROP TABLE IF EXISTS `avo_character`; +CREATE TABLE IF NOT EXISTS `avo_character` ( + `ch_id` int(11) NOT NULL AUTO_INCREMENT, + `ch_name` varchar(255) NOT NULL DEFAULT '', + `ch_thumb` varchar(255) NOT NULL DEFAULT '', + `ch_head` varchar(255) NOT NULL DEFAULT '', + `ch_body` varchar(255) NOT NULL DEFAULT '', + `ch_title` varchar(255) NOT NULL DEFAULT '', + `mb_id` varchar(255) NOT NULL DEFAULT '', + `ch_side` varchar(255) NOT NULL DEFAULT '0', + `ch_class` varchar(255) NOT NULL DEFAULT '0', + `ch_rank` char(4) NOT NULL DEFAULT '', + `ch_exp` int(11) NOT NULL DEFAULT '0', + `ch_point` int(11) NOT NULL DEFAULT '0', + `ch_type` varchar(255) NOT NULL DEFAULT '', + `ch_search_date` varchar(255) NOT NULL DEFAULT '', + `ch_search` int(11) NOT NULL DEFAULT '0', + `ch_state` varchar(255) NOT NULL DEFAULT '', + `ma_id` int(11) NOT NULL DEFAULT '0', + `ch_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ch_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- Table structure for table `avo_character_class` +-- +DROP TABLE IF EXISTS `avo_character_class`; +CREATE TABLE IF NOT EXISTS `avo_character_class` ( + `cl_id` int(11) NOT NULL AUTO_INCREMENT, + `cl_name` varchar(255) NOT NULL DEFAULT '', + `cl_img` varchar(255) NOT NULL DEFAULT '', + `cl_auth` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`cl_id`), + KEY `cl_id` (`cl_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_character_side` +-- +DROP TABLE IF EXISTS `avo_character_side`; +CREATE TABLE IF NOT EXISTS `avo_character_side` ( + `si_id` int(11) NOT NULL AUTO_INCREMENT, + `si_name` varchar(255) NOT NULL DEFAULT '', + `si_img` varchar(255) NOT NULL DEFAULT '', + `si_auth` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`si_id`), + KEY `si_id` (`si_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_character_closthes` +-- +DROP TABLE IF EXISTS `avo_character_closthes`; +CREATE TABLE IF NOT EXISTS `avo_character_closthes` ( + `cl_id` int(11) NOT NULL AUTO_INCREMENT, + `ch_id` int(11) NOT NULL DEFAULT '0', + `cl_subject` varchar(255) NOT NULL DEFAULT '', + `cl_path` varchar(255) NOT NULL DEFAULT '', + `cl_use` int(4) NOT NULL DEFAULT '0', + `cl_type` varchar(10) NOT NULL DEFAULT '', + PRIMARY KEY (`cl_id`), + KEY `cl_id` (`cl_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_couple` +-- +DROP TABLE IF EXISTS `avo_couple`; +CREATE TABLE IF NOT EXISTS `avo_couple` ( + `co_id` int(11) NOT NULL AUTO_INCREMENT, + `co_left` int(11) NOT NULL DEFAULT '0', + `co_right` int(11) NOT NULL DEFAULT '0', + `co_order` int(11) NOT NULL DEFAULT '0', + `co_date` date NOT NULL DEFAULT '0000-00-00', + PRIMARY KEY (`co_id`), + KEY `co_id` (`co_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_emoticon` +-- +DROP TABLE IF EXISTS `avo_emoticon`; +CREATE TABLE IF NOT EXISTS `avo_emoticon` ( + `me_id` int(11) NOT NULL AUTO_INCREMENT, + `me_text` varchar(255) NOT NULL DEFAULT '', + `me_img` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`me_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_inventory` +-- +DROP TABLE IF EXISTS `avo_inventory`; +CREATE TABLE IF NOT EXISTS `avo_inventory` ( + `in_id` int(11) NOT NULL AUTO_INCREMENT, + `it_id` varchar(255) NOT NULL DEFAULT '', + `it_name` varchar(255) NOT NULL DEFAULT '', + `it_rel` varchar(255) NOT NULL DEFAULT '', + `ch_id` varchar(255) NOT NULL DEFAULT '', + `ch_name` varchar(255) NOT NULL DEFAULT '', + `se_ch_id` varchar(255) NOT NULL DEFAULT '', + `se_ch_name` varchar(255) NOT NULL DEFAULT '', + `re_ch_id` varchar(255) NOT NULL DEFAULT '', + `re_ch_name` varchar(255) NOT NULL DEFAULT '', + `in_sdatetime` datetime NOT NULL DEFAULT '0000-00-00', + `in_edatetime` datetime NOT NULL DEFAULT '0000-00-00', + `in_memo` varchar(255) NOT NULL DEFAULT '', + `in_use` varchar(255) NOT NULL DEFAULT '', + `in_1` varchar(255) NOT NULL DEFAULT '', + `in_2` varchar(255) NOT NULL DEFAULT '', + `in_3` varchar(255) NOT NULL DEFAULT '', + `in_4` varchar(255) NOT NULL DEFAULT '', + `in_5` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`in_id`), + KEY `in_id` (`in_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_item` +-- +DROP TABLE IF EXISTS `avo_item`; +CREATE TABLE IF NOT EXISTS `avo_item` ( + `it_id` int(11) NOT NULL DEFAULT '0', + `it_name` varchar(255) NOT NULL DEFAULT '', + `it_category` varchar(255) NOT NULL DEFAULT '', + `it_content` varchar(255) NOT NULL DEFAULT '', + `it_content2` text NOT NULL, + `it_use_class` varchar(255) NOT NULL DEFAULT '', + `it_use_side` varchar(255) NOT NULL DEFAULT '', + `it_use_able` varchar(255) NOT NULL DEFAULT '', + `it_use_mmb_able` int(4) NOT NULL DEFAULT '0', + `it_img` varchar(255) NOT NULL DEFAULT '', + `it_has` int(11) NOT NULL DEFAULT '0', + `it_sell` int(11) NOT NULL DEFAULT '0', + `it_use_sell` int(11) NOT NULL DEFAULT '0', + `it_use_ever` int(11) NOT NULL DEFAULT '0', + `it_use` char(4) NOT NULL DEFAULT '', + `it_type` varchar(255) NOT NULL DEFAULT '', + `it_value` varchar(255) NOT NULL DEFAULT '', + `it_use_recepi` int(11) NOT NULL DEFAULT '0', + `it_seeker` int(4) NOT NULL DEFAULT '0', + `it_seeker_per_s` int(11) NOT NULL DEFAULT '0', + `it_seeker_per_e` int(11) NOT NULL DEFAULT '0', + `st_id` int(11) NOT NULL DEFAULT '0', + `it_1` varchar(255) NOT NULL DEFAULT '', + `it_2` varchar(255) NOT NULL DEFAULT '', + `it_3` varchar(255) NOT NULL DEFAULT '', + `it_4` varchar(255) NOT NULL DEFAULT '', + `it_5` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`it_id`), + KEY `it_id` (`it_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_item_recepi` +-- +DROP TABLE IF EXISTS `avo_item_recepi`; +CREATE TABLE IF NOT EXISTS `avo_item_recepi` ( + `re_id` int(11) NOT NULL AUTO_INCREMENT, + `re_item_order` varchar(255) NOT NULL DEFAULT '', + `it_id` int(11) NOT NULL DEFAULT '0', + `re_use` int(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`re_id`), + KEY `re_id` (`re_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + + +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_order` +-- +DROP TABLE IF EXISTS `avo_order`; +CREATE TABLE IF NOT EXISTS `avo_order` ( + `or_id` int(11) NOT NULL AUTO_INCREMENT, + `ch_id` varchar(255) NOT NULL DEFAULT '', + `it_id` varchar(255) NOT NULL DEFAULT '', + `or_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `mb_id` varchar(255) NOT NULL DEFAULT '', + `or_use` varchar(11) NOT NULL DEFAULT '', + `add_state` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`or_id`), + KEY `or_id` (`or_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_relation_character` +-- +DROP TABLE IF EXISTS `avo_relation_character`; +CREATE TABLE IF NOT EXISTS `avo_relation_character` ( + `rm_id` int(11) NOT NULL AUTO_INCREMENT, + `ch_id` int(11) NOT NULL DEFAULT '0', + `re_ch_id` int(11) NOT NULL DEFAULT '0', + `rm_memo` text NOT NULL, + `rm_like` int(11) NOT NULL DEFAULT '0', + `rm_link` text NOT NULL, + `rm_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`rm_id`), + KEY `rm_id` (`rm_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_banner` +-- +DROP TABLE IF EXISTS `avo_banner`; +CREATE TABLE IF NOT EXISTS `avo_banner` ( + `bn_id` int(11) NOT NULL AUTO_INCREMENT, + `bn_img` varchar(255) NOT NULL DEFAULT '', + `bn_m_img` varchar(255) NOT NULL DEFAULT '', + `bn_alt` varchar(255) NOT NULL DEFAULT '', + `bn_url` varchar(255) NOT NULL DEFAULT '', + `bn_new_win` tinyint(4) NOT NULL DEFAULT '0', + `bn_begin_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `bn_end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `bn_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`bn_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- -------------------------------------------------------- + +-- +-- 테이블 구조 `avo_intro` +-- +DROP TABLE IF EXISTS `avo_intro`; +CREATE TABLE IF NOT EXISTS `avo_intro` ( + `bn_id` int(11) NOT NULL AUTO_INCREMENT, + `bn_img` varchar(255) NOT NULL DEFAULT '', + `bn_m_img` varchar(255) NOT NULL DEFAULT '', + `bn_alt` varchar(255) NOT NULL DEFAULT '', + `bn_url` varchar(255) NOT NULL DEFAULT '', + `bn_new_win` tinyint(4) NOT NULL DEFAULT '0', + `bn_begin_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `bn_end_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `bn_order` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`bn_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +-- +-- 테이블 구조 `avo_call_board` +-- +DROP TABLE IF EXISTS `avo_call_board`; +CREATE TABLE IF NOT EXISTS `avo_call_board` ( + `bc_id` int(11) NOT NULL AUTO_INCREMENT, + `bo_table` varchar(255) NOT NULL DEFAULT '', + `wr_id` varchar(255) NOT NULL DEFAULT '', + `wr_num` varchar(255) NOT NULL DEFAULT '', + `mb_id` varchar(255) NOT NULL DEFAULT '', + `mb_name` varchar(255) NOT NULL DEFAULT '', + `ch_side` int(11) NOT NULL DEFAULT '0', + `re_mb_id` varchar(255) NOT NULL DEFAULT '', + `re_mb_name` varchar(255) NOT NULL DEFAULT '', + `memo` text NOT NULL, + `bc_datetime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', + `bc_check` int(4) NOT NULL DEFAULT '0', + PRIMARY KEY (`bc_id`), + KEY `bc_id` (`bc_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + + +DROP TABLE IF EXISTS `avo_character_title`; +CREATE TABLE IF NOT EXISTS `avo_character_title` ( + `ti_id` int(11) NOT NULL AUTO_INCREMENT, + `ti_title` varchar(255) NOT NULL DEFAULT '', + `ti_img` varchar(255) NOT NULL DEFAULT '', + `ti_use` char(4) NOT NULL DEFAULT '', + `ti_value` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ti_id`), + KEY `ti_id` (`ti_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_has_title`; +CREATE TABLE IF NOT EXISTS `avo_has_title` ( + `hi_id` int(11) NOT NULL AUTO_INCREMENT, + `ti_id` int(11) NOT NULL DEFAULT '0', + `ch_id` int(11) NOT NULL DEFAULT '0', + `ch_name` varchar(255) NOT NULL DEFAULT '', + `hi_use` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`hi_id`), + KEY `hi_id` (`hi_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_css_config`; +CREATE TABLE IF NOT EXISTS `avo_css_config` ( + `cs_id` int(11) NOT NULL AUTO_INCREMENT, + `cs_name` varchar(255) NOT NULL DEFAULT '', + `cs_value` varchar(255) NOT NULL DEFAULT '', + `cs_descript` varchar(255) NOT NULL DEFAULT '', + `cs_etc_1` varchar(255) NOT NULL DEFAULT '', + `cs_etc_2` varchar(255) NOT NULL DEFAULT '', + `cs_etc_3` varchar(255) NOT NULL DEFAULT '', + `cs_etc_4` varchar(255) NOT NULL DEFAULT '', + `cs_etc_5` varchar(255) NOT NULL DEFAULT '', + `cs_etc_6` varchar(255) NOT NULL DEFAULT '', + `cs_etc_7` varchar(255) NOT NULL DEFAULT '', + `cs_etc_8` varchar(255) NOT NULL DEFAULT '', + `cs_etc_9` varchar(255) NOT NULL DEFAULT '', + `cs_etc_10` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`cs_id`), + KEY `cs_id` (`cs_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_article`; +CREATE TABLE IF NOT EXISTS `avo_article` ( + `ar_id` INT(11) NOT NULL AUTO_INCREMENT, + `ar_theme` VARCHAR(255) NOT NULL DEFAULT '', + `ar_code` VARCHAR(255) NOT NULL DEFAULT '', + `ar_name` VARCHAR(255) NOT NULL DEFAULT '', + `ar_type` VARCHAR(255) NOT NULL DEFAULT '', + `ar_size` INT(11) NOT NULL DEFAULT '0', + `ar_text` VARCHAR(255) NOT NULL DEFAULT '', + `ar_help` VARCHAR(255) NOT NULL DEFAULT '', + `ar_order` INT(11) NOT NULL DEFAULT '0', + `ar_secret` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`ar_id`), + KEY `ar_id` (`ar_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_article_default`; +CREATE TABLE IF NOT EXISTS `avo_article_default` ( + `ad_id` INT(11) NOT NULL AUTO_INCREMENT , + `ad_use_thumb` INT(11) NOT NULL DEFAULT '0', + `ad_use_head` INT(11) NOT NULL DEFAULT '0', + `ad_use_body` INT(11) NOT NULL DEFAULT '0', + `ad_use_name` INT(11) NOT NULL DEFAULT '0', + `ad_text_thumb` VARCHAR(255) NOT NULL DEFAULT '', + `ad_text_head` VARCHAR(255) NOT NULL DEFAULT '', + `ad_text_body` VARCHAR(255) NOT NULL DEFAULT '', + `ad_text_name` VARCHAR(255) NOT NULL DEFAULT '', + `ad_help_thumb` VARCHAR(255) NOT NULL DEFAULT '', + `ad_help_head` VARCHAR(255) NOT NULL DEFAULT '', + `ad_help_body` VARCHAR(255) NOT NULL DEFAULT '', + `ad_help_name` VARCHAR(255) NOT NULL DEFAULT '', + `ad_url_thumb` INT(11) NOT NULL DEFAULT '0', + `ad_url_head` INT(11) NOT NULL DEFAULT '0', + `ad_url_body` INT(11) NOT NULL DEFAULT '0', + `ad_use_title` INT(11) NOT NULL DEFAULT '0', + `ad_use_closet` INT(11) NOT NULL DEFAULT '0', + `ad_use_inven` INT(11) NOT NULL DEFAULT '0', + `ad_use_money` INT(11) NOT NULL DEFAULT '0', + `ad_use_rank` INT(11) NOT NULL DEFAULT '0', + `ad_use_exp` INT(11) NOT NULL DEFAULT '0', + `ad_use_status` INT(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ad_id`), + KEY `ad_id` (`ad_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_article_value`; +CREATE TABLE IF NOT EXISTS `avo_article_value` ( + `av_id` INT(11) NOT NULL AUTO_INCREMENT , + `ch_id` INT(11) NOT NULL DEFAULT '0', + `ar_theme` VARCHAR(255) NOT NULL DEFAULT '', + `ar_code` VARCHAR(255) NOT NULL DEFAULT '', + `av_value` TEXT NOT NULL , + `av_1` VARCHAR(255) NOT NULL DEFAULT '', + `av_2` VARCHAR(255) NOT NULL DEFAULT '', + `av_3` VARCHAR(255) NOT NULL DEFAULT '', + `av_4` VARCHAR(255) NOT NULL DEFAULT '', + `av_5` VARCHAR(255) NOT NULL DEFAULT '', + PRIMARY KEY (`av_id`), + KEY `av_id` (`av_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_level_setting`; +CREATE TABLE IF NOT EXISTS `avo_level_setting` ( + `lv_id` INT(11) NOT NULL AUTO_INCREMENT , + `lv_name` VARCHAR(255) NOT NULL DEFAULT '', + `lv_exp` INT(11) NOT NULL DEFAULT '0', + `lv_add_state` INT(11) NOT NULL DEFAULT '0', + `lv_1` VARCHAR(255) NOT NULL DEFAULT '', + `lv_2` VARCHAR(255) NOT NULL DEFAULT '', + `lv_3` VARCHAR(255) NOT NULL DEFAULT '', + `lv_4` VARCHAR(255) NOT NULL DEFAULT '', + `lv_5` VARCHAR(255) NOT NULL DEFAULT '', + PRIMARY KEY (`lv_id`), + KEY `lv_id` (`lv_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_shop`; +CREATE TABLE IF NOT EXISTS `avo_shop` ( + `sh_id` int(11) NOT NULL AUTO_INCREMENT , + `it_id` int(11) NOT NULL DEFAULT '0', + `ca_name` varchar(255) NOT NULL DEFAULT '', + `sh_limit` int(11) NOT NULL DEFAULT '0', + `sh_qty` int(11) NOT NULL DEFAULT '0', + `sh_money` int(11) NOT NULL DEFAULT '0', + `sh_use_money` int(11) NOT NULL DEFAULT '0', + `sh_exp` int(11) NOT NULL DEFAULT '0', + `sh_use_exp` int(11) NOT NULL DEFAULT '0', + `sh_content` varchar(255) NOT NULL DEFAULT '', + `sh_side` varchar(255) NOT NULL DEFAULT '', + `sh_use_side` int(11) NOT NULL DEFAULT '0', + `sh_class` varchar(255) NOT NULL DEFAULT '', + `sh_use_class` int(11) NOT NULL DEFAULT '0', + `sh_rank` varchar(255) NOT NULL DEFAULT '', + `sh_use_rank` int(11) NOT NULL DEFAULT '0', + `sh_has_item` int(11) NOT NULL DEFAULT '0', + `sh_use_has_item` int(11) NOT NULL DEFAULT '0', + `sh_has_title` int(11) NOT NULL DEFAULT '0', + `sh_use_has_title` int(11) NOT NULL DEFAULT '0', + `sh_date_s` varchar(255) NOT NULL DEFAULT '', + `sh_date_e` varchar(255) NOT NULL DEFAULT '', + `sh_time_s` int(11) NOT NULL DEFAULT '0', + `sh_time_e` int(11) NOT NULL DEFAULT '0', + `sh_week` varchar(255) NOT NULL DEFAULT '', + `sh_order` int(11) NOT NULL DEFAULT '0', + `sh_use` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`sh_id`), + KEY `lv_id` (`sh_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_item_explorer`; +CREATE TABLE IF NOT EXISTS `avo_item_explorer` ( + `ie_id` int(11) NOT NULL AUTO_INCREMENT, + `it_id` int(11) NOT NULL DEFAULT '0', + `re_it_id` int(11) NOT NULL DEFAULT '0', + `ie_per_s` int(11) NOT NULL DEFAULT '0', + `ie_per_e` int(11) NOT NULL DEFAULT '0', + `ma_id` int(11) NOT NULL DEFAULT '0', + `ie_1` int(11) NOT NULL DEFAULT '0', + `ie_2` int(11) NOT NULL DEFAULT '0', + `ie_3` int(11) NOT NULL DEFAULT '0', + `ie_4` int(11) NOT NULL DEFAULT '0', + `ie_5` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ie_id`), + KEY `lv_id` (`ie_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_status`; +CREATE TABLE IF NOT EXISTS `avo_status` ( + `st_id` int(11) NOT NULL AUTO_INCREMENT, + `st_name` varchar(255) NOT NULL DEFAULT '', + `st_max` int(11) NOT NULL DEFAULT '0', + `st_min` int(11) NOT NULL DEFAULT '0', + `st_use_max` int(11) NOT NULL DEFAULT '0', + `st_order` int(11) NOT NULL DEFAULT '0', + `st_help` varchar(255) NOT NULL DEFAULT '', + PRIMARY KEY (`st_id`), + KEY `lv_id` (`st_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `avo_status_character`; +CREATE TABLE IF NOT EXISTS `avo_status_character` ( + `sc_id` int(11) NOT NULL AUTO_INCREMENT, + `st_id` int(11) NOT NULL DEFAULT '0', + `ch_id` int(11) NOT NULL DEFAULT '0', + `sc_max` int(11) NOT NULL DEFAULT '0', + `sc_value` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`sc_id`), + KEY `sc_id` (`sc_id`) +) ENGINE = MyISAM DEFAULT CHARSET=utf8; diff --git a/AvocadoEdition/install/img/mooning.png b/AvocadoEdition/install/img/mooning.png new file mode 100644 index 0000000000000000000000000000000000000000..da898fc3cbb782f98bc8d56899ac1c7326c5c7f0 GIT binary patch literal 63654 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 z zNN~9ueA6$HfGSV?Rg(m@xpw}HfM5Tj0b}cD!ci@D-b=3I8phHQk-Hih4@@_x!}Du~ z#u6KoZ1JBYD5(fmmLHadXPzvjh*w`zh#(hd|GKUV4BMb_ZxlDtW@dksl+crgUvl8a z2E^sB7H@dR=M)5uME!P7*Rj$=TAan|2_*# z#{2Tga=>O=*IY3c3Y%-mfGvRNHHm7}@!UL3j*Bys2xaolmUAlz*?@QGEy=HMdJEcv z9JVtI<_LKc881`uTKRgJjkZN$2$!MsKbn?46G%&JHA*_*k>$Zxp`>OU`UI>Zg+{^> z#)bDe;HZvt5mEW@rLLi5HF}B)GrIkZ7|lSJZ?*Zx^?G0T_pT40pjs+HA+Ek~hd5@{ zCDHg`JPLMu4Q`6Bk!|1qBDg51Y~xZhXz7XH@4koBr4dyDz_ z#JCkH#q&MSBG9FEw5k3W8FdpvmiR0U8E-VX7l@C+j>n=@trrAd$S^G8&!v=>0iS6| zq)J;0S?P1=P~gntphWtGtf?o}+4Zk4L38A9AeODM*zboW`ef~#iz>$Tk!?j z<_BXx=H;)#W4B5HESNVjME`DJ!B+xlr7kti^gYG4>G3>#{r!t|0Wx5Wl`&V){Ht{l zL0&{}9fUOI4Tn6*@4AT}a6QQK7ZWD)6fi|@=%gDk3zt=R04K6?8ya=w>N;z#6s}iZ z=o8RJL7PR~95+|_uW$Q$1)yw-+kKQ7{ssd06)-$yL@zWnb~s7{^aLH9CPEmFh%Nu# zp9<;`oQ>|<*^7m*8j+0vb4Vikjw6=(kYr6nLO{@V3uU^!7q0%7X+ZL@?8BYEkMc#; zS(^$fcdqC)nI)h4)*n4ucV`Qb?wh$1{#Nqw!t-!a}tNE(vy^048y7JuZQIJmq%jVi1;0CtAAUn#ivv+QD+u66F?|)Ur2Q-R-<}U zm6GizddB0GHL<1AMXiM&v6&-E@dh2g#BW1wlIRS+$MCWF$M0zmB$hg>#8X36#IL&`K3mX?xA@Hj);`vKx zwaSfeVf0v-!XlFu!bY*suwgsa9irX4z$^&e4*tZ z-tP*SWGVY5PED9^`HT)0Kt?#Gf3W>3U8hRMS;F~T2zb{F<2>;ZEx!*AlP}uVB=x}A z7gY)wwEX-n32%Taed!+)ei$_-DzYf?zlI;6TWD(*A3=TR9~$*4aKH`HZYV^}%c(l5 z9m!UXbadWm&9k;&Vmi6EURCDjTXeAAewC~t{LmiBsua)+6Hx;^JEfW)0<1YB#WhKw zfz0l*&K^#LOgH|$$(!!NG)@SE=|oePKg%BmEWS{LAPtZox>EhDc96sfZUJ`07YzOM z=LM=?6_m^IgWvN5pR4;~;w#%flwp7V{n|QZgb`hVJS_bF!L8Zvm#cecm5eE%tox;nDKGh8n%Z#IwYN!Ik@FM4)>@sCkq8KM^tuO$Vr)2gxDMT^o}YN$+8NQm0C9fQ}_dBl9@64TLpm1DY%QOV1E zjeCV=4NN%?_NtA%!oaXY9fjX}8D}Y?gHxoZiT9WM-P2Q-iKjh68ekLZ!?BtfZ(UtF z7^E&!bs$wcnFVSVRv9WTC^;Q~P4-PnB|BeUU9Sov}OnzZC zeqRC~vwh|5uFCPhWF+byRAx9T&-$hi9o;U~t!dp{nx@hR4ED7HJUj0y*9kakX^4&C zh^0yJM|Rd~`KZ2rtu|h_>ft`?x~H|mnA>L9dTa6gl4d>*xr(y%whFsmf#_0o z&h2;SEwo;u$A8kSF}|y#ax44#wYw11yrJxo*aWa2w>}k!$6@mfHmr;% zf9yWoojg$C5prjO#uD+JA4nK-A39QzjK?v+e^*ixM_kUayGsZs)mbV06Q~BHI&=M- z3(s)|8c%_ieMT7w`xCdg4yvvYJDyg)4DK5z*>?}OcFYS-ZaTd+rk@n3ileNj(-%X3 zS&x0xqP;Y=c!n$);g_XdZXEw~{qlG};8O;5fYx+=>kBVYz&_|?EhE)Hlj+;($CA4H z`+LdnpW`Lxie2G#GAx-_P=!OwK80n4YI_C}@=nVY=k9Bv-q}5}+|9s$Sxlm+FsZGj zR`;x;`0J=6Ev)$iHSRRWq(+lqB|2w%U2HU!?R;8Es!m2DhVY^DQ}8|Dy8I_FN-aO? zX;Yb-GtrQ#_U0CCe{t(Ykq&%a_4SB$GI%`ERL=yrI8iL4?g+(WX97pFTr!n*+-7L`It5hQluz+jMh|Chm1v#3 zb_j$?_1wyxFn=F#tv%c8_*eh`76hxUX&A%lBW1&7$mahM+7L@|NC;}mO&WFhTta_@ z*;i47k|vvJ@Xi^jT^m2huS5)K zG~9Q%rdCxmUnl)i`queW=9VMj`uxR97pvyV-tUbE^QDMh#Vuw&deG2YP$O=fwSjmh zIlw@9DoXXfD`ppW?{)X*uFP;4_Lf-@_T9{%n9a*lh`qxntFtMGce}A4)c8^+fY4%k zqG-n-u7SH(gE+23bM-S4HC`+vwE8Iurb)?+a~6ur2T_+nR=lsib(I?yDSg>}7wkc} zX7dhW^>Aq#p>4w0nKjFy7qq9hY*6ae!8KcQmHgmc=exYcrG;^64~@)5@!}~OZEOb8 zZl`}|W9nq*$B7Mo&rSLEEO6(?^lq?)fApp?X<~T^UAX9vVTG>d^30!Uq4unJLV$=f zSiyHkV|KcMM+VDdO6Q-%3(kA(k4jzZUeHjy+LQed7&3OtvLZ?U^;5{9U+JsD3JcV= zKi8m{_b;_9!Cy0?Wy-LX6v0NdpB>%q>iuJF`gdnNWg6qbKbU1xeZ>teR%kAlK5ovE z1gEo+5|hxee@-<|VD1w-^T2z_C$ec~MfJDyLtvC}YDB&L%;FrLf;y0#V^fQPXpDhN zA~;!ocKUYe-qEl0CvXM>z)Bm-nO+hLv99NC$MV!svon1;5XVUI*7eclBhtC{swjkj zzMvMa_b0^{+O?d%%kdZiWZR`h`-om^aP7J|+0ZZFyw%}%eNAN($G=v@EAm*rxjgPf zZ~|TfV%QEtXFlUk9~iZ0l}@D6$#YX=2A;>MGW-^rj<;uRA;vA8**^8Jr?KZ!2Etw& zbpF|+j`6XW00+?Aku67a(lM07i7p7LlkVT9BA5Jx%?s<3QZq>?ttWPHEgf~cl4kMm z+P;$(?fwpKT8lu3qD|Mwm)jKwk9+rW+HZrYW;B8N?=fX30a< zQgYb0m_zJuP2Z6)FBsi~PdXT|h@1*PMyS5?!bm`MFCKFV!>Ft+HgN5ZD4jw5ii54} zS&~mz@KNzeK*Ny4gHYBUt(w1V{OdC;94`eR3QGO%VVJV(ys4jWUOtS*R56$~t?mYf zrLGa=rh@g)RuxEcg~@?Bi@{fWDG+s=Ca=$o*sMQ5W=MWLjElb&T`7Px)Gxi-qa2pj zMsw1NY$}lMueHDN$Gi4X@hiwlB1oWcOt|MN0Y!`EyHcIqdzvk=RLDDog&r6kTNc#J zim>YD=30x*J+>%%RX3)|ug_!BA!A_|baVw5h9tcGg*1Kc7DRh_TCr9bvewektoC!J z^QHFQgXT+7&Z1cJ6zBd(App6R-6HBRAOv3pBTw*@Jcb*@Ni|+*Z2k}|cN)Sf+sFXR z&JwH5++AC6t&sbGQqD<;c&|Kt3K0_3Ij;+NXJ36~c)c6_>W{kp0|Uq8ctRta# zSsSGEatWvC<8+M44C}m~-go}wJL=-v$7S7;J>36#W_RjSfoU!NWkkZ7q_?#k`p0R`;Kpxf=gc|C#NO>rO_(^t{(UJ+~T$%PmU}>pqdY+wlgk z!>|WDMkfKDHnYRFh6YfTEDapr+moiXxVWeD-v3B!)ojH>=bORq!M}5W;*ZB>d(Ag1 zZBIku8`}Kl6O`tPIEJ$hPHR>qS{#dit4FHR#BkM^ZE|&p=$in$|FyE#VI4+7Hw1+7 zk+|_La;D-oO_uipCD53RRDj2BQ7#SIKTM zCE$mfr`O|J(;0Hg+lJVPIWQsg#fSeR* z5T|ehj0{kS<(tMa#%)l84cjV=$jy3vog>~42=U3f1oc?#rEF`H*Uf_ zM&+S)OZZrY_vPfoMsjbjd=~tWD@lb%hKrT-%f-{>lk$4nwUGtFDaXfN?r*;=d{KMp zylMiI*j+xLUR$%Jt_kbBVbPIy`sy2`^R5;8rS*HAV9CW;%H=nqnH+I0{0j;ZsKQt^ zO(3}=firS4qj8uwCB^H8xGV$v&Jy^n0YYv9DV$mGH6Lqk;!T;cpRGx!`G&x|Nlc!| zzJgL-Uu_!ZJO+bL9|d#XChcFU-n{)A{`lQzP2EdAw&5FD(cXCedDu$F`}?faAL@m! z=N>P=m2&-QaucXsG1nVboqco2JM8*Ry#2r`SA6QSw!=||y?uN6VthfwikOzRl{b`# zbrg9D&84-(^9flGG$iQblHgHLq#GTpX$pvufAghl(4b^$i~vz9Tts&WHwEqAczn~hp2A~)tLX z%l??zak5srRBw0IVBE4^@MJ8%cQ6;bhFYv&u9*Ayd#Fx}J;l752wvgpzJRa4zj2o0 z%u9YFsFYyL;~$=tK;a~dvMf>IdG;|fIo58(Pw4*vfk1x0BnHM)NV=?qFbfG-%sMfEVn8_H!_-&^8Oq28!w?C;yFsyA z3D>m|fRF$vqYTKx-Xx#TX4bX)p%w-PYliWImaUT@^SefPK!5W2Bt27KdTmSGP^l(u z2=-mMs?@BvNKzFk-q41e^#==^CU@@o+K*fN za!p$E&IH?b>y{#hdK)4mq?Q)y{YmAV6Bm4aJH+Q&7pK5BV%=U_Qm)0mmTx-{y&&#j7ufJEGjhE z!2~>-kCNY3?>^Ee^D<9%g|u4BZ$aI%8O=ZN^E@Qa??}?dML(3LX4Lt^>wM&rcc747 z&v0(zYwD7ouX%%8Y9^+Lk5fVt+E|=_iGwn;$j>dSHxKQyS$S?w|Zn#nOaz2M&JN=gB=7q97BrG^oOSX7HM!X zpw}r$9J?2LKMNQGVK)q7>?mSmX|_pgyRX7l%xhFH5}0VlbciP){b>@?;?l-DNl?jw zY1=fixo>E%ZS~Wth|YwXqtG!N3Wf%!36ATgZBx*>+%=c^H_OSKUEgAZ~w1v?7=F*{! zuQ)V2A)~$HN$akNr9iKbpx@W#)2pVrByE)TTTd-SFD54R8VZ4Q6>YnG+O~PvIzU6G zQnAhE^ApP^=j8hPO>AP^8sy*-f*66=BxnZLc0#j}3L;V(hXmlI<8#Aw!59fUDb#Tj zoRP44GEa~P@=W#_ZSG^SqgM{L673K~9S_(!8lnf3)jPu<4xdsRl8Uxh?$RUewV6(@ z*EX)jrtRTcK=)UUD%N&!{oaq-+iA9_5M1Jz0xoXq;zlIq{5j(W{Ff>}M_cReTf~(# zI@et9>cNT|4SZP2Xc^5!N zv+o;|I;B<6!C?2f4_Eh?dnp}BvmQ(d}k=(|mx^Ms9M>&71#9XdN-}>dKEh_bTPzvO(=eXpY z^ky^1*MA$Df9uq=9BMEAA@%eV)t5Sd0Z0GObmcUVyn|eS27PSZIMRs^Ov;|tD3gKfHwI^ zMc}%qRYRNvMrB2XU^JMhL?EvwJb%xh0+AM$_km|dGlJ@!yt^W3NvyY#u+y3k)7_3- z_)~Jtapz9H*K5B`ddDTLFTLc_YYTV(opY`a0;ObHb83?-5mHdXz?+9127R;l5Vd~O82xoCoK|+Y`-!2y2(*{bbL1tDSNqY5J38P&;pu7 zBw@`-|?>de>fiJ?_2{cX8ADdgGY1TpRC^_U^ve zYH&U-T+N+{sp-~VpN8$p5|heJjq%Q>{k z;vlcww8diruoM@PM8Ys52UcLj69~JJ;s{VkEQ~VNY6AdUK9OX9q%Qmx@gaclkKdV( zW;OrYeVfe|Gzt>xDtby&(t17=mv;YL;2J_}-+$lwNK3!9<22-wws+rFckH+1TV5kI z7wT)(@EslLw_L8xh=Q_iQ+Eib@WipL@KS?wX-g9`rDXf2=|5-sy+ZFUj$_BP3ayA0 z8t4pLO0c4T8*`wH^X@D0wo0RQT=WsdV3g90af~r8c-^2MeWa13c?MT2z;SV|8eZ38 zHlREj;blPzQ+Pxw8dX{ZAht37*7ge##pRDF>hw~@_uqf{e%rQp$x}AHgG*0o?z0no$&~$F{9|7csHxI2uUqU&J*IEQ;MmX7hYjb5HxSLEnpd)HZKJ zN$rv8)pAf+ITcDf{guk}ziVmMNC368#I**-j`1pDU*ST)GJ#qcqK=?vy?70Lh>F_F z3{f4hWT72tMg_7X%?==gma(M7jwdR;d=%3bwMQIJ*!(aJ6Y(=N#-38P7gMMc4FkhVm&V{45Tn*~?J?)VxO z63bY?I|D=rN$Uiy0K2gOsAxuQIFmww^iOw{Yq5Len!7uZD>0L6uf1Lf*E=;#p;t$n zEU(&0JNODzF}<|u0oRsZ-M?4*zNoF$x@F`N($G*6mPFs9EqGAXs&Q#p*wzxQ z|M}{qm0C+#&+2ZTVdI}j|#M7Sdy8`b)KL4uyZad9*37%b++fjW#m6@@rUEz6LG zpm(YUSQd5l5ndukZ9@=dDQU1x>>Nn^361)xxpVKnN1ZfDQcURe$~C<@>{l|z#CK8h z*lCqM?$*xV?G}1%odfllY_D$GE2$cvuy1=NqUSa=fkbwx%QZb{TOd?pe~V>|7kfna zpMPlEY1?WgsgV-^8^kUW72r>uAOXmNSt~GM7~(hpv2sE0N1)XT5yWK?2$MKi;TL$| z1wu>IHG(;7QIj?;o?#pPB{gwlx5JndySJ&zFowQ(bFKK^4G%olu zGOn6x4^=+Y&XsrqW(%v-ci$^gn>)GJR$T9#9!;wh(>yNfnZKQ4>Ryy`V7HC3fJ!@` zM)6>knRXOQtB0ycXgAW%yqo$Jl!{6o{4O6MDiF+~QAivjBkcWvgmLM(1Qjeo(>B&S zGdS}h248>+3FNALlP2L+;LWvg6@}}c*1gMy-t}6yx;Nj>5Fd-qxoi857Q^R!@zwF= zu0wB{J9Z@N(xIf++?7Li`|aKR*PO2gIF#$uuA9~*j_>*y8sF6Z-qGIq*aL?^F9~^z z0Bt{|WI8GSx8PPK4tiR|AY}p2BR8?IK*m~E(nppcPFW8OPV883KVA`9z{zRAnlZuz z89DlBDGW*SC;9t#K<1%v?O(cNx{9XXV&k$#_)SV4fO z)q9b_@1{-n&9S|Cba3bPMtbVjwYqqQZDXY-LIej1=+N%VA=_aBVxtr zt~70O#cZn-fY^ZBWLHoYwWXyEBJv>8+6X}cDus^}vFeJpuBEY!muSrVeZy!e19~NR z6NsB?6GLQ5+d_KgcmX+-oPcn*{lnc)F9%GnJ(To%xmiWH^ zZLdn2-la`V+O};Pw}GBoJ8cQ|(mTn{<(!M#AQKF8femaM#kR?W*Z+$jRqRD5-0kUfeS*XY1ay z*R-i^r$KFd;6cszoLdZGW0` z4^FvUzxCIy2HI5qwoUJZJ%d`azX(knM2P~MTwG*V*SjPW(vtW-TR)o%^6i3LcVWAI^%bP=sM*3bsyV zimNl$7%hHyNAdu|!h)!V4cd?X(zHT0Bpxpb2D6mcc@wr!>@+xR!U`8m8^?e5L!-Oq z+P44u_U>{Q?(R~3+ZN6}wogzn7Qw!8J4_CQa4xNCH&SKXoG&#kj!)IlYt9#H;cJIf zGOmja+7_p=!A)CDlom;eJHm^s@|tU3LgP;0I->mB3}7TA8o&~o)V13-v~F7fk3Zx0 zQ{?ys;C+O5CG8*RozMj%y!%l6DFIG#Qtc`T?>@|~XQw1hec%F)$T>l=VhTy&N4RP0 zDruFXdSx5mMOQ@2@w8Rt!fre-ab>H8dhYINKE1a6HbliE@LZI*uq{nfySY0R;U;cd zrlcW2Nm|!3IHtDI7-4tFzfwXFwk7H}hKMayaepW_d+}b83WK=L3A?rb! z#URY^GHVE*-G4ESvuOcEU}Vvr3oAs^tfVku@rnSj!WacoH@43a*pw3S)8-ZQn6|(4 z=;1lkv~6=~`)L$H!N~f{_yc~N){P{7XVTJ=wAU)iwf4tN@a38-hHDb%uzfAcu|}ma zt!Ud`&0Y902&GO^Pvh1kjXbni@u-4%KVlYyc;&;n_L{t|L7EL{Vgy*o zh~F^_;0P#>Rx_k%gf>)(EKFXl(BCN4gQML+R+_|yMkJ{T0Et1kt@HY)b$YaLZcf}c z*R*YYe0yyhT~~I}ifIv|(&|*juV^bsam?oKz6jG?bNGmQD~Oi3j_pagT-)_&(6+HrpARsj6ynqm}nh%e{ z01(9zN}6ZlIPg3|9wdmQna|1cA@;?_Yhv1_SRhWMivzSxp#%ay`R1CEwr$naa@s`g zStOq_@ciDT@kjg(6v5J~N}cKnMs6={YG7^iGc4-l_gRlTB8-rI+WQ|O5 zZ6lb+nj($RfM_<4KkUb3gkl>T98sFPMx~lVPYhKMeoZex`q@b?Y54|L^QgfIIH4SKM!~*Oz=cb@Bu>Ll~^K4h07pRDcX!wsbMVC zNMmNDKEvPoO~gFidC>^6t^ga?cG_0hsiUFQeHH(z?Amq;95M zB-E6NR@-L52Kd9fjpBwnZ%SNA3?mTavnT@9z&I$lDR%f}=Ou`J!W&BntjBhP98xe2 z0A6bV?MHrmg*cM3%V-8f64Jy;dg|i<+OZQhO>(2??0ARFlIpSJb|8 z8%(!grwUc!-&>$3nwHj=wr(p_$8jMh2sHpon_{4swynXKmQC8=Hf^l-lPjTa_zWhE zi}z6gurwvM2_^B^Kqo;$tI=8j7OSRd-2}0XK^U-yePwlw2?k8zFesug0$K{d3jH-a z|G;E{SJ{Xp7H%Tl89`q$3WY1Pm6^AclGZl~GWg*P>Ocr8D?5TJ1YR%dlht4romiie%E{78{LV2_Jzz9kH3e z{fHW%N_|&SqN%}%hkOf?3W;J+ezuqPMB1*w<3a5_FE=q8A9tf{4<7D5S!e;a?V3GG_Fw(7-#s`(C2> z4uvdwGh4A4GgqtL6!GJea(ARIZfO8!Qc|}Zx!Y@;_EIIjy{2t1z7y-qU01Ye(zrdY zsT1rN)s@YK)e@XEt<*G29VQ2tCaH47*Y-k^rq?}=a(B%wTxPLELQvptYpXHP{1>+d zMN1A~WMYRD8tPq%3Fft>cd?7MgeWMzAX=n08p{X}MBo{oeD<{k3lq&mefmUz@}H*bpSLa z>n5)2h!SWZzb%g2%R*3+Tx$1vMBKT#v~648-9d@(2`aKYCM}K$5G;xLT|N6^fu`(Q ztZWE{_7W{#APK4_Y9)jbu8Z5~zx6__R}&4Whg(1+yfXfS{fGx^C4d+=q!+ zJAktT0=dMAyIFQ9h_HehkPTR`q=}7f1)(BFM)FGYZx<{7CYF}nEzx-I{Jr*?+89Z_ z??K%5-Tft21_WV7O!hCd=!r`+ZU|p{qS1*Fkn18(mrB%)Lt4Kh#C!E zNyW&7nk^rc%TF3&8l{xl;0RTe_#$7Aw7ui3^n7)o_r14G>q}c&oIJSU3@ea9zq^kh zf8lX)#kv(~p%XW_O>%A9Rj44n``-2bg_eW6#wm9(m^Q`1ZF6?jOSrdfvkYdHl@M@p zC<2YD!2!D$3nBpsW6HnJRx+;;08L|q1_3Ofnb#v(NYX!^S3%AcYwd@Ks-jD6ZzBD5 zb|jIzRLMh`{Sm2jPC3PQq>~I?5jW8GF87cx)Jkwu$2Y}X67HCT(l!_u2f3{*byuLK z7~DDt;xys^89}QJ^?Ri;hC*uYpuIF;<@Kg)PBqAl706La9YWMr7-sX1W~9eb_ah5R zTu4(U?X@)T1889-d3H?-@4k!bz625xp;-@r&`2335|83YAAx|jW@y``Aruq+tJIk# zO6#&p5kG(%T4&*MiLTog%BH@igizX2TGF;{Y1_7`0D73jmiPBf%O;E#3y?ZOxN!+i z>*{#alJuIOz%_0PSJV1loNL;WiqOVcH845T)M;G1jY&&GdV$pxG^}>bN>8F4Y>Wo4 zht-QfsiB{VS?Mm&j~ZTY;8ARo|Inr7Gau@WW()j{WdQ0I`K7eZw+%&3u2?cnM@1!( z9iTsH2qkI@ImpLB1=D2&7d2OUkorsF9mMQLJ7Y z*c$tq*3^W63U%6h+|t??H6iyq7>TwFwv>d@#BpM!xweh*cu07VLKkakq1*8ps^GO3{*3_r%)c_LgHbxbD z1Dj|T4KWx4vJ+tmxnco<_*BoJM|poA>B%68u^IwVE0dVout{Mx$U}Gi8VL=R zFm-orza7aVeG2ftu%cLh1*EaGn*&3Ez-1~pgP7taYSoRoA%CJ?UU0pgtWzNd)IJ1 zx5Y9RPBdvlvkGoh8Fv0pJV-{50c2FoP?p1MqKaz`J1(UrM9@BBWGD)H0ZE`sL4MHh zv=Sl$uf%>bpB3}_jLkrK91>7s93uu};Owi4gQ%#YA7HAMsI}PlGsP+LOAql2G#0yI zgK6oNqiv<`ySi(kVJQ*L#IVJl&w~;{npSR`(qJelhW4)Q(OkE83V>8Ng=>447OZ$a zwc9on41@Fkxgc8-``JN3i-|icN!W7oMy4c~EuVq0(7LFkbj1j$DqPhANThv7*3O`h z2=n)5y%Lp*KF**Str+2;Hi;V~i6R+@!elMQs<3`q_s-O9TJ$JTH&Va^A9MiWZ9-bu za=Bdb^v;cpT}vQ;U|4`sBRe1?CIfYGo*`9RSCG4gv=@+MV<+2lX|Gowbwb)quxZoS zt?j>H8GW*7pLaeQ^d!RYAko$6qun(q#-M8Kmo8P%;ssW$wAyiuK-j_n`|lA8|BPNh zGrs^rQvt1`Zu;7A;tI?iAQG_(inVY2UeP2iKTJziIX0DKvnr&I)JQ|<3bf0my3)hF zQrYP_1=}7ZQSvKpKazw=u?ccu!O46ilyYtF4w|;bchtIbl=4#Okvoc$R_2n7TgZ~M zPVlk>zwtyWTNjtXm*FnPq8vQ== z`vKJ$@1g;uIxJ1%1|-ie%}qh*UXk$QA_S#T{q3s-uDNDGN$(KCy>st!*Sia8+g8jq zqq-~FI9ZTB7!ikzgaRyRfYAltwcq5>e{+U;odD%p;7YwcHFtL{>3zRFw|d$njZ>^$ z#lxUq<|Ez&vuR}#_){rz_M z3-`y45xn%{4(rJAf*CDNWs_kxPCW_3kQTg39;n=R-;oJ)0yWKd%Z?w{BYC zTK8~+&q-^96aG-ZFtbF=e8j>ifL^TK^^hKSRcjhYv%B+{k&8>z_Da9$U9aD}Yc95* zl;(ol!=)bwBbbMe`Fu2>6@m97DNJ@Knix6Q(!4A5yn+rynk5uj+`bIbBWo(jpm#M| z_Wbfbs{>|`UlRlB0J*^O80IifEfi#5NFN!GyuDw1!z~NPTKbnv$NG7pUYAIxen{`zH4dZOOGx z476>jsjymakTpE|+nv9^7e@RWTYBIZ#*9AMA(|PeA*dgMdMxW8E1uGP{^m1$(i((P zIaK=3i}KOvPjy~(2W5`cN(gCZ!#+7V!8wUSAS3`9+!VDC`cq0>C!Swu=@XS0kef5} z?jEZ{igo8+uWAdrJL^Q4II+HNw|5&^q?MO49|1690XqxV5X92`CLg2EGDx_sMTm=6y(&ikL z?*89@Z5%C*9LHiO+I;kEULk&Ggg!yq_v2UI5d<`#+9w}bi6h4T$hxj7(ksIJ94#bO z1IyK}dkYxr{S=D@@61Enk|bcc>h?iJVZ{*RT?@bhR27 zm*od@Mnp@9&MBn9vocZwcMbBab5}R`Xd!LdyK7sDYBem2*X+baBBRF=+Trt=T_w?I zO2t&=wUm?+Qr-`Rw0FJMy{prH@2*X^qn2LX%5G>W*f7IK%xIbS&nWO*jSw{-IXL^~ zK3lA@21(kT8Qfe{7)F$u5Dma+EeY7i?4WU~k+p8#ztOz&LHjZSM#XDd>+V_%TsaWk zR@`-rGd~VZfi!tqIWmc_^xyvyq$)WQ6n4JfZ?C~EzH1LIzK?)j-L^*3C!>;O#RlF; z67TbVy7ix@`NLnq* z68VB?wwC3Fi8K|i-CDd}P8HdR9Os&)B>G0n%QR7>L(Gqxtt} zq}r6|pBNb0S=R5&GcTG! z02)9NET9wuEeK?MK(DQ~^-s(7S_jTCH1ztt&-SZ&`Px@$0RnAuNv|{#NAH@pO(CSQ z*&QJ?gP_ZJ1+e4d00pD@YlIOYMeBmEdgJ(X-%G#!w(e=&v`tZ+ltqd!txdo}up?>q z`Dn%L=XnHn-CzrV1+AFZ+O=j^8oiblteAj?-_=@pcEoO9Nqjyl$veD6GApw_W;DBx zpFwzK82J2-{0fpB*H!eYHm-3TT^;iibLo-bL&gQsK>6kZwAt{FByo!>@C8=r+{4Fn zbyZUnwC~CoiiZdSnlO`>{SK5pj(X$q>u5Yid zvvk!%AE+OFrfIu(?S1oYbhlGCyRYUSLel;{61$q;2d4SYSRdIkTt!HRs5i}>+1`cp zj{7G6```br|35)+fE!7&n>zfg&pkO`!grIxclYsFkJtx>fFNdy^`pZJpi}BX=^9B--140vpR7-|6?r zS8m;=_c!@{-5?Ge<^8;G=I5Mwc(p2T^Az7|Vum6~JB2pnx}W>`{@m+)?)LKe@6!0w zqxRl=eH)Y3Z44xJwr)*H_;zE+g0Rj*h6VTD%3&2?;X!kDN1Jz)5kK>cZE0XQXV;MJ zZvGW=kT8;%UsgJLa0?}fW&bzY*`qmVMJzBNS%7a?sR7G&OGR9*^A+yrl9W`j4<@7B*OxGi2Z@e^YJ-k0ZVtyskwf^sfs!RCWBC5Gel6KV_ zYMI-6@BMtFgf)B$_hTn*Z)`c-w#IFn0%?*e4v8EUw>E;PlH}Az7!+0m?~o0M=RrHL z@H=x>2x-JIbcOOrB7&b6cE4Bec(wA3(O|9i_e9C;(L7@zns^PwE@S~8ZY*=Jxwm!$ zU+&#r5kjocBu&aAP!abscc`{5vWC>%XB&qJzW3f6+TR%%B;BBwmEU=#RnVUQ{mX$B z^Ur&E+$exjN^iuCt6a6|=iYno_rT}V{MO~jb9buAjfirkAr?1j;+w>!_ukKkGMD?g{qNej zC2d=`DNPF3G_4gUE=tw31X@%;B5&Q~b$3ET24jq+k<@3Uif4E*BJs#w+mo&aVcRpy z&1m#IFMxH-oFfL@V?A`9?jWobz?Sx38Z^C1IuIa2P8#>N&KFiuaIceRneP!0`_Xxa zR{yBuYJP^DsoNWw&q;A-D!CUkw{eguR4ICQIZOXY+Py9UUw#k_NDIkL?-lM%ldAvS z>znqI%Kco^Hc1NC_vYdTS{j8hh9=-;6xXR1X@&JLNg0F`fuRU6^RARZTPn#1mz5BQF~RY)4FIpd(URe=}UTI;qg{h~y&xJ3cx zXhYh*4-Qq!`7P)7;Znr4%QfCc>p|yM_a+|A`IM)A0ATuF~-6+o?1`$3~t zGKi#BXxiZZ{5^xelefX{_64GeYiIu@ff!gR%eI)sW4y^B(Ns3 zd@H3*TlKbOKR4g_xNZjnX?w3z2-H@l2`k%L*U;-W+-uSzT-6)BTdhVTA$vj0m;tJh z=2#<&ICypy?+u#U)T1E5AT1CQpsYc&JQLUloi$?MCOC?;ddJfdJGBr_f?Hio>gD~? zsD-q`DC2MqZ#B`hzISWQtL{iYv${zQS8kx?Xm5+`5-5@~47Eg$%9tww-w4BOtT6Ppy8CI~4NujI5L?Y+hlP@#aCA|u`=J7eu5 z3rrE&vn$TbV7*3If?@fA-vjG5KaL)bqQJ4WuwY&Z^lp&!fQo1lk2r%~%jQ)uRYJ4` zH}1Xu`_<={1lL;eveO1g%fr>Kxo3CKjHbS~S(2-XRvBsJEW$S#QVH9SDDzQ=l)`OH=>N2T4^jS3z zBZOE9CSd@{ag5DG%&#lKdk;PGPiXlbl^N zzElVpbl8Ecb;Kt_qZKn$Vn?}k%1s0>{5U~?5z;)m4Wr0@L2{^=<2he|WwpZkteq1RT6=dwl|u?8qceNgLvl@<}#r zFa5jZyQ;7O6a$OAZUaf|3c-4o6{}P`1q(P8;@vh<>j6SELf*ldJJqfJ!+Df!OQfv|kOkEu>Y*w2W`l)EcA>=#pB3;L5c{R`;Tp5jQ8jqZEgv$j=N? z6ZLkgbirOMjkH3VTviI2iG+G_Nxa(Lt4VGpNieuL4b!%vOx@JjRT>e+Oe%`6WfHkR z2g6Hlr4jCRZHQ3m^(C#Ee?Mn9Vr5KqxXpUa3PJj;ycnX54iNL!GLxRx_Y7%C$* z`$tCAazf3WB5x)v%p|#igm=4Hgxq^)ed)cg8US1+F?vOD+iTjEP|Y?@NHT*K(&QS3 z2KF(!5z}RN)8Lk9bj0n*c2kzADA>f3@WH&av_lO<*LoSju_NYpU}lw#k#-ELr(88} zb)537p$kx2mo!e3xwwkGU%pLyjgjfh2yR)yw3J>(vXEx9vqLt*LPDttm|Rnn-r60C z(EiXvE0NsuuhQd&#IzdUGPoryrJ$R(;1SpDjKZYtHSG8IiGF(Jxy@~H>PCtI(6Tz* zpO)fTkoXKj$)S>DZavkUWG2BBfe7v zxC+g#9Lp0EfvRMHAiK>XmwSOhL$MuG3g4Lky=N7)ATGg;XsCViD{B zkqrn@kjTi_EvmVm77vA}w%h4-4bm`p_Gi$}usY)Jey1}Efei{P+c7XPu69N%*d1at zfV-2A6M0#r=y`vmt;UzKnBH4Am6ESpdfQ7cUDpa~6p5{7>fY{{IQ>}RrRc@-=Q851 z6M%MQ>jERBvBfQy)z0h;kaQz4iTQ0v@x@fJjDY4k!jICnplBZG$S?cud6$LU8c(~w z7A8uNaKCp~kOHk9N{Ui&xpr(&LfBQB1gA8T&;lCf?K9#zNs$}fTjmK{=ER`$^R0|D zyuZ$J#PE!4V7{N0l(AfmWf`tPYZSF@ZsS~+`TBft>pD#h1x(f;ccr8^y(NJdaiyW+ zwr>vYr5(AocNvxvnpptoOt@io5LDTjzZgj_atxBR*g)9SZd}t!3?*eI=g&Uxu6z^{ z(@yW)mRQtA$a^RiS6N>}YPY@6o#@2e4220Y#!d@Kn88y-hml`iGxK7{H=KQJu`);q zabBG>3WyzP%M!`9P_3*Uk5)q>={3l{2-TRR%H^wVuS##Bx2mq)cngwL)TDUjbSR%& z-wT$))~zO&!Ne3vSz0r+GC5|-m%DMaX4_bwzJLL=V-$q)$?Qr~7PWhk3_p{6bqqzDVC{Mvw&+X|YQ(KjOy z>_|t;Nc-3;MCTT1ke z+NL#i?;v+p`CRb7DkAYbN@n!Xd1-U2-X^k94nGi~0nJ&5g_YiYXNFzXB)B4)Kx6y& zAkPja8bLiNt}jlc&V?YkX_+ycm2Q%sR)1Q-GuOpxI05Zt(mX+h#V;rvRv zW*KQzv?JE7eT!vdFwhj*)X80}nzNmBGfgrD4d-bB#m&8f^yYQJAyeZ>8AzqQk?Tw^ zBRLej+I2OOG|R4DF^}c}vEx3|R%RQrYSXMN+I5?b7<*0wmWE8*X3}C&dF@fvd;}1+6U*fOsDaS)mldmK{uKT3l!(vfm@Akx8&M zJ78ovG_5VPMnPRi1UG3L2nI0l*7b0JP_^Mc7Cw!yG%@z+thIT9A}M^V3+*qoobfwlwIq zq!q%@ByIpXy~#sw6E}rKAe~|4KtL<;cbYdbCTpa&j}ChblPAwVT$dW>B)< zP`3g>s8z8Z@jF87{(-W~r?+)!ZaFwvyS;6>^ukT}vejuMJ^dDSYqvBB>UB%+t=m>9 z@$Vpk9*XX595rr;MP<X)6C`)w{PL==4w~mkM^FU5xdoL`5|iFf`spf~hU%+zQwMUD-ZZ_Ymo&Y`b<bxKM*t9s%>pj1(3mb~H1ZA3y=fkQmbfOCj+~$7ck^>juNo ztQXs9)4L*Q049LMF1x7>4ItsIzTE06P{OfG?NAZfo6U;xWWSCJ+4;JGVwc_vwHF33UQ?0 zAq+x7XaXn;!^~pni_e2|Nm8V#ug7GO&a=KDtw zYZh$AgARGcBbhic{0meBJ-G|7UF(We-)%`+^Tlnh238no+uB(-!Ei~_lD4*5_}yl} zwVKjgf~vse)|Od-d1Wqu)^!|ei6I*oaaLkPTMaSVh&V_MBMhuYtb~x56KE_D5+X>f zWlL=G#7&D8H^wFq5)A;%E8C*0BB&$Zl9twO6OG5%7>dJXiuq!~nagoQ>ou~NpDwtO*0h82yh*CBJP1{bhgaCm=9NE&C|jvErs4b}?v zB00oyd~aitl_gpWNBCOU001k3WdX9Z->qXTg3qG1;_V?ah(?3l*a)o@Gy^m!HxYqG zKtc@(Kp~-!ja;zoF~;U+E=07^FjjCO<8<9nD9E;zh9hZL#xt5qk~(4pqNKnN#L}5X z>}wfnfqgLjH8X>zZ8YRdi{Bz&dTk426DX0q3pgfDWlf4Txwv*+)^{$Hd22}sGk}t( zHSG>J!-ArSrC32kfP<+e0^gW4E;eBNP?lw6JcC9^S!>TRW+jmf?TrvLhc*UdjHE=B zCGi`N5do|pHKtM8Rxu&LG)!sfRl<5*b!}pyAVy{+?{P?-?#uhIV1tajBRM}SfPi#K zL>|GtI09(W4*3#7Vy73wt6c%aJBW;ew~;qxiH$5s>Ajak{y20Y62u18S_6_C3owR8 z1Sw4{Wrvgo6T}=lCS)TwQ=341E^8!d03;Cuh|L5S_pWN;5jahY9H`+hMM#Q>d|r&g z3di%Pp$(8UiCYheZ`#I)2)U6P5fGB4T{JeW7yrs=03rj@^CYa7o)M{946=4D z+!*G|%)5X{Q?zp=Ik6%Dxow9haZGw~`yp+LAQsgTsz+;z3r2dyvWZ4SI0+zu z6Gzw@p!%jt8<(LeW0UVx)95|;BqVUW5)Tn+4YF*TjU6Xro8__LuMD!CAgnQ9m86Zd z8nqxPi?0=gE!dQ}qEU)vg3`LyIz-BCqh^OV>U)~ZvVL2*8Xjuk>w*OkHY`Wz?M2qv6F2QwC(=*lQD&?!8N8}MgmGjAmrGk z#V&EuAlQ(AfMKo?CYV^oX>D(dgonDQi@vdxe9|DXwio~G?gsWDx5lJ0n$Dtu+k5XP zU#|+UT-~R z{q^iV;`|)n&wnXI?9V^`{5OfMF`^NGzyM=Fu#3_^*k$!dvpb^N$r9Qg07e?`i-krb zuh@Cd0|=>+^bC&}?c$7pfPY~iXnu|sKRc*7uXdlAGp|;2#NaJ5ZL-$Xn|e1y5(^AR zDB4|5*&*4rOq(VU*J5RYfK@DEDOy=kYKVl929OX-K?*uRL|`dmrG1`R0eG%^@BQ5C zUw9=L-D>u8SM&aUjb60R?~i&vpU<^Gul8OUnFTC}(UBfvEP*V+FH7B+U1?TYqj@4N z-PMrp4(iGc(lD975Ftymi!D}J0YW3oA!4*zEE5ABB4u+AQk!F#mD^w2MQj0Mf z)dL8vwBAFDh4jiEt|Ob<-rUMAtjJ12l7~u2$L#)L^sJm?-RlY&WF)9CFX)2MLIPmW z&I~no@SmNJ0`uzuK?aAEC3z_udKt=jY&72nkRDftW{LVPlPx41j~^**UB3 zyxL!a1Ee7FJ}iL99{^uKpuaY&l~8#l_G}PGVr&F+lqI$$fNA7s_jwmB)-pR@iFY&_ zFjftMw-&XZ!4iPjNbDeC+VQqdJtddKPE0QrM_C*qp@Ee|_rPR5=S#=kO1u~F{d>*+M}5r z!Mr%6!T6-SD1I?|awihbRC|=Eg1$3l$zRoO+-eCvX#zbd4Gd2jAJ;X-MAbZ3v27n_O zFnY|^qa7^4ioCj0V5I^6pCC9u5hFmBC8_%#Xc^v&L|0WNjz=W)Khm0Q^jr9!6J~i` zboWCMQH+Xyvj%n?czE%^pA3WM46gY4- z>;HpMS1IwZFaOO76Gz5$hj(VtDBkak>agFkFQQltW&sqeQVNZYNh1HeT zxItCqMcM(r|Gqw-*~hI~$tua*o!enOVy(4$uFTm*Ej|zh$z$~^#JmuR(qQW_= z{SWE4yW@G^ML)*9v#M%Y6Wg<=)UGJv68#5RW?@`%pFxxUo<&^L z)*8R{B%z-g22#jf-A2$;7j>s{TJVoCtQym(O&!y;_iHu|oXO1`TNpp>jIijp?$2Kt zoqgZ$`(SP#f989Y19ZOKk8fXhu5*4m&ijreI@=>IgO_Hfi)^WyBA7|lRbf#~NrbnH z8geTwUqICwL6pp_iQDS0HdnmVDV6DIWQ?Ij`7YHLJYG0wNWlf8)_8GnWeuXA!nwmC zXtKns>J`|HCZf^Q3*eu)f_B!<4?A!BMUGa)n(H(eDAOTPSsK*=Rt6sRnP(^dcbxga z>Ae4NMszkyX7Q`6?+l?xY=&J$W6;YA^e=;ssKK9+G@4ax=x5d!Jr(4OW^CfAXI*- z@81rikyw9!k?)5Bk0{8uc~Q+qqQ*yob1ABf+@y2Oy4sH7aN#r_nln|u#iH!w$`#UF z8RU|PB-ch&xz2)eN`fq`tfx`v!GHzh|4h^Y~Y1?HOe6hIih5#5w{Dnq+kT%5G9JlNmBU?;ybJ3syZvc)ka7NrdH`(L&MHiMpdL zxSMo0Hc?&m^a%>7F{-_YIvZeddhC~&_9xVWF-H^hPTL^f8Fyw@aScPX?7MH`LQqW* z&zYBStm#>L`{S*swx>A-pt?q$f68E1|4^P8*QxgGXRm8jr8Kyh5L@eR;yCGhsBoY9 z{Rf7@d3N5}RtaHJ{l?1<*;)D2Cj+hZ3(Qp^*slUccjp0%~)H3=QoOk$ZRFy1dKHQRY zkTgfY?61z`JO`#Q7sOA4s3IRaf7}$aXm#<;P44%4{GAsEH4N}U6f$Hl_MMF%<4&J=E-7lXq?kS@!ujjX{xxB0Tu2$Kf8G!P}7AF3i z=VRx4XXhnmednEb82!es`4!zn?KUQcNvN|5}g>e(fOHyNJtu)==Z!k!~C0> zFU-uagT6aMRzib6&bOD&IJil&A~SyH&FkjyTiutblSnScBdiJko;A^Uzcd%GG0ig) zh=bO0{muPbbLRSEh*h;G$%Y;wKa4T9rD38*NV~|$2pE|3Yvuc3aNZr{)BKGn;A}$o zb%OFF-@6t5tVr6LG|sG|tDh%&iLw2r@^Nw@7k|dfwV#WqM&sf$7Vuz|9Stz!?jC%g zJHUJkKC1qV0`iP1u11x3lycar>&$E*nJ;acQ^mF6d!PUN^iGYzWKxYi9C^aOnNMxh z>q`QHcis`nYU2GGH62EkK~<$n^istVfBHP5y1+v8Q)jgMqp>qj9a8IuPE@_RQpq2k zbg`Z`+VQh~YuvYqIsQM;%s9Nr;u4!ktr1;V@!?xFAb^bY6#o!t?_ z0Fw?rx$`AMZv7n>h;EFXif+n({_{6}=JYyOFIi^Q z-$u|8zejkKiYk7qj>v>K(5jBE&R0}L2LT3bvf*+YTwOtd2U#>!RsW>HHjSn%{q_Qi z;Uf0eh7$|>G0TahGiSz{=*k?<4lE1e=x*XGu&{)AXW1EjA+tLk^1=!*zdcR z3F3LFiBlu+&v~N0o1mFvYhskYYyGWUm{{&n=wlQ*|M?H*d}&)aRY67PG(^H)6m*Iv z52BbcV?bI61Vs=*?E#=eU=r>KZ6wCq)v;;65KY*2+r z7Y#t0o}dpO`YkKXEFi+pM?j&nF#DhoT-O`tFRSV>^WT5tt6_|4>{<%$fi8t(H>usD zQH|&L`9FGS#T66mUR%8@m-z|k<~GcmV_S)WVLh)6S=Dvm?+M+ zOH}XPrbd%TtBKZwnh|n0Xl47NF{lD)%JcoaLEuUGMHo6K#T{it4N8WVt((m553lpKti? zXKw_#NTI5_p&I$8(H&F;(f53$)^XuRQL<4%XUyp0Jny)uGMH(+ZId&chiU?;^L@{( zf6Qe};29Y&`+P0#$o$l0m}ne57zq2kLkFLciJGee!zx2Jtc&ukA#0W}FUecuvSDVH zpT9ruJPKRf8Fc6Ue4kJJP-WO1z8Wtm%Z%Qs=gAl#sWVB$l;~^HBubj1&CD; zudTZ3ugVUp=(|wYzxY?zzB`Z45n7`=K+*~40ukLA8PbKt@#u|FLGPAdwMphf_0J~h zDev?AUAQQPh^uAiAv5yHXbXpgJr=*EiGC{JQFNJ{FI-KSjV=}y5EzJ{8s#@S-}vdc z^8h)OmBFpA=_}RI4XZe$Zmy}eY7X9)&s?`XRjr_EJI1I93Miv%FTJSfa;v(U>?|DO z6dfRvWEW?RYp13W&0I51Ln2;QYn(NAs)1GGDye7nc6I*jp}jcHYckyP-;ejdsNrX4 zSJibl&bUiLvXOyiNN>gg%#7g`86u*p?4sE(Olo!A-Cf@OhqemK^X=wa$go;n{3p4L z{hK0C`uv{WIq`s=I->P*QdV-a=H?EBXjKiSj|MI2uvVK`(MClzCOR^Hdj|BK47<+G zmta0?v0nU?uea|P)X*Yo^jvj4skow7C**b!_Yc?ce#QObBfWQD99WfahGAEX!UW6- z6FdyntGaQJ7&l>1uc<<-iYy8)qJYA`C9BK;yX(I}|Lx2IvglyAPqT9y*9*E8p&R#8 z2c^w9j>&bjZQ$x*&X~iX@lm&q$tKl^_B>sJbK_ z<>S!wQLn-C-zItz?C*h@~NGO1=1m~M2pkNs6XyDVuM{V@X z-6d?ypR^%8T9S=3dD&;5Pg(iit@ga_txZ$O&%$GsL@gLhpfT04iHSxVliKjD^T9}W zXY;u_s1S#R363la@_vn}ZQVyyceK@Bo_v$ETvoAFnY6K@l1nbs2JcRFR!?nXbw3c- zySRE+t)51^t3p8Wg~CIEl!4ueIuCF&J^HaTyP$|FZJqgH468HWKR~*p=ZWyAGOqfq zah!{tu>Yrd2EJz=X2vwen%b+@lTxESQ!JRURZx>8X;x!n{5~+MZACS%z72rM=nOcz zX{P?{2+pv!Sa-}Nn)^KsYJOBrUCqUkCjGq{i()jyCUvVe+EjOR$jvIMig>7TIAzm? z6(>=Yg=`4%Q#hq}&lQ&X%^)Hw>bcL;tIXT+Br`6FlQaIYv^u#xrFQ1E8D78v77~M(+E4L=G;yB-;O+^{OZ1|1JQvqAgTd&>hsOY46ONJF@~h5Y|G5~ z!ZJpw3|k9Whn?wrCB{30DWiX`cq*a{$!4Q~F(NJ()h)KgNlxl;o-x2riyq~fw=K5x@&CkNhU2(#GZQ1nFyW4MzyMTN6)z!c|XGcP@=jns;V)VRV`5x z*=ox(JWB7=*@-D&g-~6F7Y0yO83ETd7v?0TA%Dp=n*KqHRo+1rXncj8)BPx|t4$In z;^bhgIz4mGq>1vIny<{NDk@(@*wJwOTg_%?ctl1~)%@scff39n_c|07)YxpH4%t;K z2Su&@9U1Q$bEPg`9IQrFRcDR)b=DVWP_+sUqT*RaEv#CNfh`TMSE$|!s&;!zQ)#mc ztL(rKa8_nkM{M|L>iueKtn=prF{8|;MKmt^4Di~XjEy=%%`YGjuStV8E=ez;Ip0C9 zVjjf|G)dK-uGNd`#T>FG*aiVo zb+q0xS}Mn=dg|_ch^k@>pMa2%M43;4H=8Y})Qg8bCnhV*4ui6B!Cf6$+6##4uam;X z%O84zf*J#=rdG<_oiQ4yaz|@VXB@AJt{RQoYc$K(Rq$ICNfqMx4)XLJM#gVg22}tV zcLhIw)EAp14!koOw9)FV($<*9np_A`5>-#toV^pFCQ=ShE57>QFsv|wWNe~TuXYv` z381R+7We5CP&dI7l$koW-~Jzt>Yyk$FvIgB9=W^IoInpDh0oDrl9 zs&|@AvN?B<7d{Y2bc9b<G1^#3ZV=Mb ze6iOtoE~T$K-R(|ky&GyKD@Yv6_*uR6YoSli^kv0aOxr$6>*1QL{~>r z*J^5NRMOdJT6Hdd2Og>tKW%&18lB`e9ZqA^EJjphPtC@jwh_nnt&QSCi4L zq9bRNY%aH|X)ZbP`|nltx7P0-x%Ng0m4;k4_lo+VY8EkLSQ~6}3eCv8f%!NPy~5ol z?-Uq#VO25docxU5h@48AR0m1^)Os-nw<;^ThMu)3)7DmOHPvIyK@+3byM{DIZs+MY zTZM}a`ISb+_+GuUxLWP;Wfbd9L6K;5*k(s-RE##t%O=DcPNM4wPr9h6N6&LuP40dj zS?kqmQ7**OP-CJ^jLxX|PvFC-0|~21jNk=8&;3s3+#Y1`WCdn@eBG-0x%-ISbm=Bu zXbna4C-|H}B4c8HdFP3HzP_yg>^1F$O~wD8AUHq~BS4lVsrw&j8QzRUS5+pCMqR&Ki2h=m^n1t3= z8**}T(Y9p|^?K&%wZHzRy=c7SeobvT#iQ4&{r%O^L?ym6>PE+aKjQ4VqMm!n*i+BS zQO8t&Yvc(tLUk6E1p^Q(G&Hn9+UTE*K^;`V)wr&-Nxx6#Dn^B|PSVQvc(pxi&pWS1 zXR8w|uN_HjTzDVjWVrs1R~FH)0}vGehXCpi`pt||9U3B3Tdl;@{JLkEy{e#gt%`TK zkL&N9o0Bo?nQD@HM3rA}?k+~AL6jF#&E6FbbXTP89Lz`@M#Y|!gzn$x(e&H_2NY=p z_Ce5bKt8QV)Yd;cvXz-JhT&i!D*a3bMK3uUBV%5A0h+%&7N{VR2PAOB zHzcM?ob2ad_^AI`Y|$`>r<8zMMKZ#RiJyJ_)ZJm+ozzP(k^R%C7HxC_^6}^pV}xoh z$yH7W0R5V&*_Rbq>DGG>hM16&ig3;TOpYSk=1!2x~e<4yt4Leb)*n- z_MK{DMP_i W8ObIOM_ss83p53dcpRL%9061Op8g7NxW;><(r>I|YTF^c-hEdEFG ziOv1c>N8>YerX{(t2+xSDhoQ1Wm#E9*MTQt|J*tLUYZVfF`nN(6RnyM)85t4i(`DT zmkN5h9&O@z_U>%Y(;5YlN?c~X#d*YhbXQb#8_^-yxEgOb-^g!NQ*3fDv*}vNo)55SAJF zYp;qYsFFJI3#vTq&Pa4$k0B`j@pAFfIx()ATD8@)cfV=9Bp0nFYjU5Zxf}KB(&jEL zzwM#cHE-tI8fX=T4`e^}mFZXsijO-cRuS8IoT;4Z608pzJHxK7x<4>n@|<5{&xOmH z1bGa#yleEG(M?WmZ}r!7Qq?twvF;k@Q&)|t$mj~d^5lN2W4oU0%rnU8*0gQJeMTo_ z7u|Q)Va8`bK5SX1QUB!Zubh`t%R1fO%_w*6?_F%J(V96vJKl9@wOraXE!$|XF?01j z3FXDjF4dX*DDt{s_*Pld9sdW);8e5XlhG(#<|({S)OFqrnZas7hCo$?JL7;cRfu?U zyrg1QAeI}=sWzI6S7nBK{t<;wm8YJ{x~wL|X8|-by3v^Z z`S-jXbuf+j-C+g_EJ-aN1Wc(gY?{s`L-d~Omk^-|5V>rL6D90 z+tGBTv>FNLQFB1LVl9V4Dq9`7_c>z%2)xSnc7 z#cXR`X)KwqtYHAmsCWO;H32_6$aL-aDV_ZoW*M+;AHe*4y1Q0;3c$KMtUFkKv*pbSyxzaK?V%CAZif> zqhXL`Q@+vpW?;w6B8=B(?f2PSdAOF`o$c`3{)YT6U`31=<5Jhn;jNf!y(H=vG3I-1 zQx#L&pT|Y`#)w}QiGz^q8z%Ta(T{4v05i<6tLwt*%nnS=Yt+%@QUA;sMI)JhGOPKN zymMW9)n3+f9q?Ppc^7(4t7jL-Q0c#2hmH}_9pKThE=`tAwme4sqGQx!Gm}r`QwAlh zc_Xm?aN@IvXkwnJvrAf=I}O*nN_;P$%_YWMu>KxSFXFI=l557q`>mSS8m7-ov@&Ky z8+>GRcL1!w6iFQyfc~v^mSraM8L_+@bX7{03=4jn?C|e<)IX>~#BcpKe7ZA>g#Ih^ z&R*j2t!Zi(;+E*J_L{2etT9W<1l`GrscHsBTO_YOsmSvwkQs!_1+YgEjq@chll zkEo);rj~Ot%q7$MwQ#QL+5DbKZF?7U(bjV>)%FaPGq$Q%=cj5XcS^)`CIcWD*g;nH z`PHfe>>$ssgk{1fR56zBU$JTaE9Elu^^tgAB9wpp{obS5e$^F=Wtcgmdu z{H*LMuwWKOA28YzT-KR+R$sLC0|C6?Sc$Y4yg8dcWwM9$Q<<3_9M0+FTDE zU_*L2C*$Q4>;L}ATOAk2^$K0ltfRt<ga>uAYHu8+# z+4gKMcNfw4z>vHCKJ8t%7k{$EFRA!*0YF!}^cxY`Nd#RtJdd z@_i}{Gg0xpvYRB-uHrJ!SBs6vI1YdE{DUQ0(#c|9)JaFz-*Bp}UQJl$$7kiZE@0>T zVosF)6SRlPtA!ylx+6Gr^mVq%H`*uys;f2nxND{^kLWuitG=&86v3(8^E1isT{QB6 z-rdb_H_>*!=I+`g9-uw7N0ZZ_O-!PRsJzt4kZpXrq|@Ed(NFBn2-x{*BUBT z)0ML=C$)}_*r=KR>4VufT+-jFs!K|P+I9X3sTwG0>d7M#c9fdxq?(*rO)b0Ljw>=K zr;Csu2|3j}b|hpZELLaXwL`Q4J`9?Zx};wV0Z=$vFwAoS(2+QDfTA zw9K0SQ{RA1Zl)E!jcqhnV^p(7`34zeMm^W;lE&XIz?^^znPnH#723A8C+?@DqH&qw zkw0qYf9E^y-+!)b&h<*#{PX|)<~N>au2ipk3^tguU2@62#*y&i47wq-W*$}T>}&Ux zf3wW^tYRRd>lmv^G;uTr=lR#=8RcchsIOIRFxPZ#b2i(INo;<5Qn9L!641Ld!GL)b zFCvaPQ=_DLn?$s2;-zX54eCy?rcmP-I<+F>h=v^#|2#48 zN>-=0lJxZY-X*!;-~V@2qfL{$N^LP0d&xF0$C+|wEcWWkO{ZO@5 z6L6wkO{1DOQPi3`>;#9Nh8D(EFLh=|o&{ZrV9t6ddlj0*mjb|ourD)zoSTQ&biP%V z)YsGA+28hly|8I~2h*HMV|z>6kb)6A`i?hdo>ym`na^Qo=7oI*2fzK^M?P0^7?l@v z7LpT{5oey~->YH1opng$z-!yIjh@^^RncPA<=#C5kYw`dI@+FP3jQo~8qyi2$@JC8sA)IV$S?}R#%t!awA zYrW?8et(mwJ)n1igvAW%?7IygcA_ltOWyZ+b$0=9C(djFDx>}f;tnx8CXQJF0>)j< z?($z0opXlW=S8vYq4uslzn(pF_xr2ozYE7+S&5%^<|bUQao7hI_McR<(JETPHA!uH zsv=kG3o!0H!=P}hZln9cAWMoeCHbW6UAV{viRoDTfBgF&brxOY^Z1AM->BDJqj$d{ z)n3*6y=$4kwk{;Ko;VO*K;0b+5# z*Tn~Dti3yNWPHe_^+elPGuYZ&HOFc`{SA+IIvL=cwqeuU?9N)*D5|dZE)x|KF*RV^ zvd-xDF^{sJM134^Rvi||;%3ls2%gDlehEqR(jgCv%&@qy>&zeQCqtQ&z2weg$BpOx zE^`FW+nd-l*vv#1G==LOkz~do&UU|@v6tERWQOT{%(L!3xX%aG74{!P`7jQFz1;{Yr{Kiu;O8Q!6K~H6EI8^+*PkcyM|Bk-pR~WXjYAR}`R(s-w0gRy z=of&-s2MU?YxMn=i7q(m#&v%DH~aVR&hpJ0R$kbBcmKWWey>Ku_(qil8B*+HLjTP_ zu(5YnO$pu^ZSz}OS_s`qih|#&;r^&}}1;ZzG~fRl1X9;NEqa zT@_^sW_|x}09YQ}QG8#zIXRav=Luo4q2SMID@nEpgu#^>|zE0&BDy+rv%;?GT+ZQ5FHJlcug*o zGghgWo6|Nd_S{;f%!~&YZ;SzPqd&!CKJ|SM#HiLD#b?r-alKRZy_$yT0^LCe6~9LZ z6|^qq1Q#@o z`2A!Ubl&+l{buzU-t~J9t;j0>Ts~AgIB0z4?>yLD=YI)m5TmkNPfhOB>Tfimcf%$4 zGb$s?j9ao#NA(%@eRg4Fa;dKNn~OXT8e4URLO^^7&g?g!D^0n7v+N*)Qafb%U89(e zy)*W_bT+fFGCuRkCnPrPA9v^J;Dj{0PFBBh+8+o!`hU!R*y`P(N@HlR-qvkE2Y0Mo zA7@4#`uzQVKC_RH`fpEO6yndPs>**Q$_s)rK6Z!63yKHs$YKhnIaRuQ8t+cu&-;xh z0&Y^$+aw!QlE+;}$2^aP4@6cxGtcw)VH;!g10Dj5;wa_$cGw-S>NCohe9Z06%$jr6 zxWKvNZR$B&{?boehKG+=`wr+I2AHrjbPm8FZ7f6nGK@9)c;T+st9I^o^ysH74h;Fb z_s{00!6K{=U48Wa`*-NQ>+%ui-+xwRSJJ4Xv(|Mry8tZUdeK4%s6Lm2cd^N#YAfl{ zOn3ZN-xmqa9hp&Oh=z7cQ9Bac(S(Qj@8fkAfYDXmsWYqO^56gc$UuypD64_4K4Q9e zY-%+|x`Ph*^D*P_&Zo1<^6UOX|Ge|}LaO)=!D`&>r#;8rXZc*c^SY{sSF9&z&dD9Z zcn$XpdohfTFz@>Oou$t6ek-d&&|PO1k}>BkS~zv+#Bsu$(3ds&O* z9CqJG9LMo%yPw1w(->Y;i9h90Z~!)Bsa9-$CVGJmpGsec5yi#%&wp%^iRerKUUkr( zj?PAmIv#Hm3Vh!?c9>lp$D!(4`BNT^O(!p1wZ`d-z)b!<)2?48#EfEA?_xr8=G30A zQD@)T$!%mFaC!gfOc62!?Q)>a+XpLGcW08~xShzadH4PorceCZnh{dRFg47GBI zu2xh_-<^3szdADi-!N5?$3MEhpqSZx#=wESDB)$FEBZ|~YSdht^z5~Ij7pg;<|uD| zpU-6I3&_vD8poZ%f6p#oj{V*l9t58XBF-R=-}3|VKldk(j(h`bM;%WiYmd8Pcgiye z9-QA_MjTt8F zCCtB1y$m`=rfKwRKWcgBttRHCR~OHh2Q1N@u+ashh4G7u8^-yD>1Rh|?!XdRMi-0@ zff5o><#Vi#?#}N2v0N>}Y35Hd4<(uvCq;Fd@YD0S~ zI3qgCoWsueFn-Ufwc&Y^K=(CK@mX{|c7E&%F!NWyG9BJgQ5XQ#(;XGyzHx?(dzZz(L(1R}7@!k+6V=QQllSV)nhvCELw<>7SmL{H~#AB4KthN0fE%&a1s_+H1{O z(Zg%oLkYV(5At0Zubj@1*TmNhMq@!`%s%Wlh{0Vl0Q1Z;2);U>GeJ@IUYqwPo|wJE zAu4}quHWu6Jm0`72U~}kota^|Y|TuJdR|T=(r5l6K7fK3jX9$RVla}lDluhqt$MP^ z2II+YvsO2J$hAb|U8PO?Yb_UPF8==n!2yaS0kSN~y8nTe$INt58R3qiW)As}v?AoZ zAIE^|R%;yAAngG*(%c!0b9eL4U`YeUeD$uDzts!0-*0pCgoG})6m%TRBnh30r*vQC z-4|eYR-O^-KchPTa&cc|bApWK5zUfZ&KDHn|Cr~-cXeiZbnlLv1aX{?%OVpT}lUytLyG?x6IvVt+6p?!jIbkUas`; zj8&-Wx}xHK>qUG1dbvxy(_GKvQ?F}%8ShMYS96-;{f?h`Nx<$a3(SkJx!U;Il^N!B z_R(=10S)8xiN?4=;2C5-nda18^8TX?A7{*m_YYsJD9plv!#U3M8U3IKuFgPycNnv* z{^Kwgz`!WdsBJ|lGiO7@ZN7&RjlusH?i(Ayus|XX-PX9pe#RUi+R>j_6R$>VnQVb- zx2+6orS;&=E>s^@lE_bIO8CU)HjP9^OVS_HL&cx7n$G`V8vkcEK zkK*d<;?fI&IEU9jpvyNAub}T|7H8*|^_^6uZ*XwyBKyk3JIBEo%)ezm4(?dh?z)n; zaBEs^8-tA-E?1Z7Q+3Yl`y>TlM zjTJ#Rs!gd$Acm?QJw=>a(HYm_BZzLoxZab!)X(yg{K$iDmv7H&u6^B!QLAh7F_NoZ zyep^43HE}QyZL_2(e7~Ndd6pv#~6Yus6;>8cZV4ofvRMq%tM^nVP=Pw#M0Z`)dhVs zGhvuJ=%NvQgy((N9@-g+%DO{B&XIq7-CNvovooAYR(Fme1s!5+gR>YRZRbf;Rf8s} zLp*)4iP&V)RP${~GZ<&z@m72_Dt(z4t*(`y88K2lodm>1vD(A)bzWy{ziqA_lNwUp z+#R;7Qw8LbuE^$Ur_D6l^?2#L`{&HeGdLvP-h<9NWD${Z(Z^RYO~#0U4ije9hja2M z4a2?QVuE}}+PmhhlEqa3sE$9hTbuH%65t{Sg*s=4KkQ)$Te&a!E} z9@mh5JLZ{pUp^y)8-@-~vsZziNH00s(>yjAQs3b^;siu=EThBbh(b(uSJ0bYBttmcw#u+eRoynHgQ`vA)##;a?U&~6 zR+D_e4Q&k_ zldhh^l5s`$3GOaD*5`fZRvt!_`4=}ay>X1HIfvv>8X=ik9j2$b%$u2e{hfIgX7-Um zvHlBD9fvLO$cqu)%xAiFTr|6CUc?}PZ%m0f(;Q<#P^o02UOk1>N_GcHcyetIWbnmj zg{o^arg^V~Puj5W51C*uHAMCtFLk)fS!4BbcdFBP*K4kKfM!_Nn9G^Fiz;bBBcAy- z`kJ9H?!qrMlr=kASM>eJ_wK%^YNJwriHVH-zEW7XescBW`kTYS&dOxf2JS44z6j~^Xi zjht_wnW#UX8hhqKvO$tI863?ux%;-w7uBYBcUepe7V71C!O(8AEXP=#>*1!N=MK79 zuik?*%<&S}ZFgqC?_IcHH1*sBVi^kPfS-3poq^sy`k93hvO2Gtc{1$&&Q15zd9xOG z{R~eQ$BA1h3F-y})@UxMHdlKIDKvRiS2=u%^7vJ~sGrF*9=#}cSXC0YhyyBWo(wrP zUw@4BsumB_Gq%lHs~c_bZZJL1oNd**)6>Kx8?5DANLHwmu{YX+-isv$`#Nc;?|8mG z6-=tQfYID*KzD_nN^o}Jf6IIx!f^EurHmnp;=~)bd|q)dJajiaJI|0oGD&s>)ZITB zL{lLqeMRpenz#VSv)fD3Zz!*#dTrRWS1&va-;bM9+UmLeDzkyNuX)Fw_Rm~ZH?KF` z2}(~uOtds7$v_ZSM&|ubmO$9L{~0C+c*DLL2Y@YkM!@%dR1V+?!-frmrp^Zu(>fs4 zyO_@z2lXlyZ5XhPBC0NmULR{Nn%DCZvE+CMaUK;1+;=@*8$8<|udKbhyY}jxHj>M~ z^m_GZ?=H5~qpzNd+>_stu0+Sr1lfqVnyJ72O!kT@KGZ&E1<<@#|an=>Sqf>)l=E_vQOhb5f1;4)L5zxT)+m=e1GgPW{BJS@m^T<=WUYHR$Vg zO&sR=7=|qYd?K?VF#GmBLG3cYSWaNXNtm_H>aGks03(dutRpHZ5qh^{%&TIe$p;6j zSe$W8kW=oy=aFPpuP||QgOzl-V^j!Hle-@$Z9J1pyU}~*?o5q)?Uz`;*W0q!ByE~| zTItCt@OU5g#KZgDiYGbM-WXOru2eNLPn%PSM$rF3{t{>CdF|O~^<7j&%kqcsf8X*^ zbw|u1%e(c_&tu|0%y<;WRZthpPBM(rS@tvYI%d{VL3dPl{UjR1e1bz$la>eLE*nqf zf!5@{*G$^)>ze+$mlVHAP+OCbI$V#fcll8Xw)S$T9@Ocjm+Kvt+kaiqqRO45O~FIF z`7&UydMjo>#V>gJJ#Q^n@!`V;Xgj}BX7%Jj?(hA~Oh50_*4Cp}j=yS>D4D?<{S5fP zn%Dd%+0W;#x`WJv>>MAzY1{c^L|@y!Q#_|EJTLsQBA@lyip=o>qoQ$)pt_?Kk2y2s zq=tHGWVyM|YTw>WM`x&lMlp_V&KfWF4mLk6G_g95*WQ`nZQE;ZN^BZX@1nVDQ|~Ui zlI>+LHrKn8*Yta}P0Y0>ezmUAT7Yame=1L0v|a4Kp8G5jJ-?S6SJ(}>5Gp>|L=4?GT- zvXA}plC6~S`FPJB9}E`V$BgUev%G+xI*3bN^dpM-h!(`y3w=i+o8(S&|Im_o=3M;Z z*~ogML{-0oqFe9YwJdPQl8|@$ps3S5xnjV?AT*9psfq0o7UE9{23tuCt3qXSQ$0 zOPFc)lV?C@*)dB7<*_@y&#c3{6&!3PANwBWA2WcT&w^`q#dCXUr2ocK#Dx77DG`%X#^{Tt}Nx&S4yPXHUt6^c_ZR$TjE0#AVppxXp_T&JbfVJB+(5`=X)- zkxlB#J3IKWDzLw=O@(LZun#ag>*7XE$o(Dhq21L0C?ty2YFlp@PMkOw(V1Z$9Y4-k zM)ZNzyUsg1s!=0O?T??_-QM-eD00`UnViR6=y5i8c=g!|6Rn2O0oq6{5 zlyPeA%$>b?MPHomBlP21J9c^(P<4{<)-%yHPIMuRgYL$+43wM~H+()b&!cqqR1|4# z>DKs6%>3^IfT|-qeCG3cVXL#6QlaCU^FPcDXpN>-(Xkejn^fvn1tp)+XgcO!o{q~+ z_EqXz{T^gaEZS#o_)$Ik&E55y?@deZE&+u$?%h?d?P+UnfL``i0nTvuNp05Ldh1yY zUrvkprpwt^sjPhz!qce?yF2l|< z0?r_H(D{3GyPs#(6z$7Aw&L+$RQyEmk|j4u(Kw#k3;IWhk^Riz$2HC>%*@W{7B?c( z@yg(GF>im`opze!t|qnlUJilxc3Qi4_dV}&;ld@uj&sKZU(~?sxhKz7-fH!3@BFsj z74Ji&l|RSSsP@*jZPGOKXi)5_Y`uBnQU2D2WrP@2W&oI(51+?%gTlCOj0|pF#_Fx7 zgS>X8(E)u})A+2wi&tiJli~4^y_`v0we!S?cZQnE8LRYaRji3on{sRL)hmO7pH*i; zn;*S3^v+8gd&;S7hIm-h+}*9T8eP_v_IpKl66c+V*>@p(7jI}c;bQy!o}7LH;&WJ8 zPklP+lN)uecp6}QHAzS!#`mMZXpYYV!x&iy9rSOV4I`ITd?dJLQh2whfZ$`|s;;xc z4yxw;ob26;CzMOY=(SGQVV0ab(>c3_Ogx^D>~|NTSL5Nz`|6IZ+URMakg0NqwzNSDKf} zjM3&!G*S?Au)C4kZZ6SWYi?qg9J~5A@j@heQa&2AcRlTC zVi`{3P*o2X|bs|~TDro?{F z2xK%6l7bPH9hC5 zedlrA88E}nI3rU{q711QM#Wr)XLlD^F04!d6&UuN6?J!~tw!4fHdfA3Rxz>8>)0SG z5<}k7nyvF<1N_`cThf)|RJFb|2l)sODJZ?T}ZS9ukN1(+fHda23J-AB2e#im80E1u{TJ`dlH73v~uXI@@*nXeweC^6nS z=UuOyCefvg%=6@h8W?Jn3{Gzt23??PG-lI9hqf^8Pr^i9w{#~ zf3F}cvqWAMViZvbk0Q^4!fO_2c^?;B=zV$l>`p-qj!i@~czW?AGKZ?Jd8G7vST$*S z!mx-C98&QoM03_FYp<^oov(L8goRnu-d&Q6#T{54f~V&lN1f}^dK*hpNOIo0$kU##fWCXa>eP<}Mj#=rg@kFv4eu>nn;PO5$ zJF38d$vQaTPNJ-LA+6p7_LZlx;0Gk}&Buu5E;U3;Vy&}b#i;cW(@-zTanZq1u+AEL z`s2xm+}(Yz)XckOv$xbs&GmZgX;ks|)6Nd>o;ny;oe*iSZkcP@qVnR|_%Xdvs|DEcY{$npm+E) zXS3$kaS-9Va9949c+O+jdy2bnmc>Rb?3J$F|unk zBFDS&;^VCJa8K*?x>O@MbvZOF?=G2%Zcjj-moqj{4S;17ki2E zsCZ*i^=6i7cv6k=XkNzBc)MrQYweZS^KRbu3^^f0%Xn(FK9^-xJ|$l?8u)C`SGA@W zHH%eF5_oki#FPH_n=IRvTVd3>Z*2s8FOejws9dwwR7ccxpsrrAg4XJJ=C5C;RX&e9kBm#>Pvc$nF4yFGjfTCQoHJS{ zbMZ+2Kh9-s=lyKhXR`LZ^U`z@Ft-RT_#AG~KHsaEHfg;)x8csy>rQus;nc(;F6kFc z-BTA;)kGfZ$cguj2DGPRuIjR_Oo`-FR$XP8LD|Bx4v6}?>^<{->~7PHy=WrV<(&zy z-(mcHxx9(bd(l~YCG`V~+J~x|i%Ic1cXzg$F!_A?-(m6E`^lm9n@gLPHqHILazl5E zgOuBWjV`k??qHhkczfpVs@1ym{@s4=C3~>E96BL99zDdt9kI;$}8 zuHxR+6x+Ms*PHD4)hqMPqPt!Qq*a)8teTurgg9YlVc30L*3m_{oi`Y`TG zsLCVSz3Zg*9Qk}`iuTZvc=Woi?6X$v-OSoD+y)ThIsV=SeZTQ|_ESe^@mqa;jc&_`%>$PeUX4wBq)~Kp+ zRh>~RU(W%P4S#6Vy6h}M@b;3VQtCd?7Ekg{}T%31i zjfuUU(Ysqyb*ti~e(&xir`2=xm09JV&q(IioH0MS>uK*Icg-~wtshb&JMfHp^7g=U z>ePf~nx?T0*X_ARdy0iFf*p=lEIHN&gNW}EX*k5n3vbkI zARX2JpCCBEkz-kQEZFuua>(G0Rks`v)%eoL_Gy; z8q1QB?mH~Z_?<%x(o#iY7C}%z9?)O{6nflQ7;!+t%&(As^^67Hf>X-ujYgoIv-257 z!tb1s^qmwM~~o zE$rg5KqwBeED)@wq@YC@;0zE10K=EqMl4U8&uv~K8PipP@@s5L7)rV}2QK9$|m{6RUR#8jMPyhi& z8g6W|KP@%%-rhnw3KO*;O4oS+h}}1Cd&-9ZBkdY%wrrY2u7W}^5<`p3w1ksN40>g@Z__Clm-J z4E^L5q5jmmF3@}Lg#iU(stFYGvQ0{@UJOO+lHs9rwRypAR?bC8b0mRa!8@xsVgZ3r z;-jyfz)7gV|Wv+APspCekZKnr8y`Af*)^tQ|2k zD%m+V6NMn!Nj_MF6af69>X*_s6#68i^T!Mc{^vr%^L6IhO#dvlYtrqWeoWnJX78>DnWz&eFh)EUc(>njS3*mXz|>B<2^ zGv*~WX$`~0o2No+2sJW7M=53-iQqEGGm}RDQ)a#AT}g{vBj`)PbE2UVnglF?NwEK0 zc6a8ZM@SUS8mteieOC-nw>9s`IQH%l5E)CeGy6O9yEE{eSQSE&gokifMUf;7VZre# z$=Ye0x<3Sk98uH0y(KOqkBoXrsx)c0POq@kHUY0tr5Jfd61xF|HyCP}R17C-^ML5GnhT@03_hB2=& z88H}1Av_R#H1jT*U8v(ojLHaUaO%gPaS$^*&+}(2?MAks0Zj3OAlf*{5xvM*$Y?lA z6l|z}tOQ?ZgGoBX))KYQT59V|JKMB0O)C&VeD)yEgj7z`O2IptZ4$r)x2a=E5P;SR zN!#SXPI|9)=8wU;^4%xifI%>nG{Q$E`+DSc1ZRIopU><&LIErKAXn5D<_lDscMroX zEwG^AX0hIPUh@AuLSlm#E3v(7>m5`ZZ;L%|+5cvqefB#8s}Zg#GI}W7kxMIqY~iop zS~5l&Mj0FGpQLUY-;0Q2V-}O7sbh)0)>6s#>K%D17@6< zRHBdQ%+B-154gUvmMY@&i&0t8&RJDN4)2?Sg1+OS_MLckRNme1yHhZbBO`8!p$`Dk z>RoHavRV;ko+Bw%BUU}b3VGIR2qr~h(Tuz^M)Io9``^ywbH48&fXcScFtcW~%)1LG zK(R%M-!Q!IvjpOMjeiKFbK9hV$RI%2Bu4GCZCIMt9)l4TGJw!S^pJ`Tv~>Y?X^bnR zod_*1sg`ml65y4oz%z06Dq(e0Uc<-0?PSLIN)Rs3MDk@0+%vm+W@bVg2KzGF9cE{Q zR|^*;&;r=0S!MOKvX*zHQNG*gsMTwm(HHxi^UO0tT_b@tde3a<=w1AQ{1X8rM(@l% zvyucFC=nWKvliL&{rvuMQ7DdnibJ)zYbOheaf1%3UnNmM0yQD2WhPRvsKI&BqIK1cDbl1CJi33iG!Z1?diP?e1PN&sJ13J7{L4 znP+9Z^~|gY%t$N!O0uA~7LDCG8z4cF(JLLj!*M# z`$jUx$c>bxH{IO0iQT}Lj9W;;`vfnFtiq;-#d&qUS$_YTS)0$9$%seIqls}xsL>W3 zIVA|z(k6%VNS$MLc81x}9GeX)i$FUXPj*>a49e-*JuXOg0!R6N{1^wc(&0NNo5kBA;usiKf9m=Zz@ZEW=9C^A_a{S zYbBV8Bw-QId^IzXs_%!9g7hNJj%}euex(B>cybwu*WTG@7-sapcmEbJPW59MJe#Dp zomvxWz=lB6K#6a_YHO`)hj)sxzir#rZC#;gF<3I7k(@j-FK<5z2Q4C?;rH~fs><^# zp?xkGfIeyqpctfi9sH2618p=!vs%#i-90mpx&s<%b_?SGjksDnGqnWK{vD%eBomEg zhBvGwpA);qtp)~-=E&h0kfniFomZJhd88#$G(bp4kZoWpjb2uffM@p|J!f8t1qeSD z2#n>5R;in$5j-jdww4b1sB%<~+0oRgyTI!>kT_hLg8|9LX`G<9sNrQY&&@!=?DssU zuRqm}3?3ao^s!cB!xmuU}))jMKzW`1|hcjSX)v4a4Rcrg~(!AOfVvtKb( zV>8}Af^j6Nig&mO*@X;7Gb2DNUe5E?GuCHjRx{}A`y83k~_UZGhKo=1p^W{;jxs&UW?Fwca=5=PHEgB1E`Ud}QrooA%cGc&(7KqES6P<^y0 zEb6;_M)P+xNx!`o@Dp56T4F722Dh_z>*4$zt;;?gnP4TdO9^r=awVG@+NW$=(xs*v z6cIfLsRJvS#TC6siZzvU@p~qsnl#_2jZr@sSkmHEN+nN9BZ#_1b!TXkO6c=4`^|ZEqQy8&Uk#wyevZ7@1}v@dMlIwc;pRfx z+d>Lui(p^t2)bYpcX9vH#?r&`{yhQmP@ch#&b37iMi?s=?<4)H{|!n@5V-f=;lfby zt|_=zAlYlMCShc)S^{g&E8%4|E8YQ#f^Dq)M06I{4vkfVkP~o?Ei`#F&oE;Hhg6i( zI1MsMA?@b2sauk`6g3ms!4R2ACHGq+O_#5l66Cg4D3FloS^;l6E_%)?_~O>Qn*t7y zGLp)3gaO7tB#Y5)*^w-vh#8OeH8Mu5n6+trT62V6#@34-ZJ83_d)}jc&a<<;$W<6? zCg*!}I6_+K$N(eBG?uVNI^)s+7e*i%qXEs&5U@lYD1rcH5Rpnav-3Ayxvijo!HJ+r z^0smf1q!`w8Ai9?im*=G+A?E&pg_B#=Bxg zHw*gA*?0JT(6L^;;=420RC}WFig^?DpJeZ$S%lCE2H8JqysrsNio zb{+e+Wdrn%O6`S{W^@pMj9_3vV;Q4mW~{+l8>hT-01CDV)&Yz`T48B^N9*kBdEn8A z|Lr`pvZNXOE=u_9&LX@cKs!hsrY6Xj2B)PBfmTiMB{cR84k3Z2nr9Fn#L}t;Ki24XmO}Jma@*qCB8`e~&otwG z7VV}L<{kq+1oDeV?t?5~GzVhwsK#IdyPCCO9v@k3pb-dI;Z3R$1dNTPInqQr;%LyW z=gXN9qnX)9O#O_sqXA_{nnAN5>j9mSHhjL%?Cg#fb`T;Kt4BX9(&8D87F72@kP#Ho z)kyjCM~`dFqmJ$Hv~`*`cCTyqa%3a5Pk!#j>T@Fe@kG1Xw^AB5-zg9J4R` zI!mEPQwBLEoXfzn~j`#e^(P~D1 z!{baHKJ|X()qf%1vyO}d%{-jRI|huV&OYz5wAe^);P6ec8?6p z@C6MRDcx5~Wyhls4c_sbS#?Gd>_W5EO481w^UOT^u-Y#j^bl(`yP7jIGt6p{C9N#Q zvPL?;A=10D1U0i#e#C-=UNnHLC7?kraXU}8aes-gUolB2jTm}c+V-Zs7tpv#3U&~6 zT(`OaP1s0o|Ni<6`_us@tfM6!61Q zj%Mit)(8+|o&n3H!02Z>7|>>hnL+3V1(Q|r!o;rsS%{RpSnjOkHjUEjgjObMOVl`3 zXqqu_lv_j#1sjHO{NC?g7U4tbgFaR*~?(Ux1Bc1OsXLRs8qZvuV&LA-! z=~vZyJb;8nSh4o7nC=MwfP^At0ofu>GFH&Y2j-EsC;{)#3m{TNZhBLK$xWPyffko# z-@uHYCwi1Gj_j7Cl%a10e6%xgXF$Ncg%XM=Ze3H%;HGVf7^vwb3kvT_UcO^S7^^Pf zD)zu+gl(BY(hN{7t0QBFcClbegx*>0%t*3`1RNpsj6It76|*y%8O{WEQyIAX)TYq~k#UycM)?gUFV_Gxdiq_h_q55cO|@zP$@5F|zrrqZGB z0w>ib9UE&ATvi|~YYHG)if}CngNej~u(G@xq&dqYVLOSy3_H)CBj(l2(K4e4UJ3p; z)}pYF)*8=P^PaCHky-m$v@|G?NW+h4r;6g`7cDYUF%pX`rT<#twToH|QYdL@18&oj zXwnn|bg56v#c5joK7}@+CCcTl|8D)!A^Cpvdn@WBOzuLAw2A2j8|oO66nE7&3$s{K zNML|bgdM8kPQl2Lg|Ly)h^K}~Gq6ChibMrPDZ*gjJu?D<2(r#IpXYqev*(D}N6RqM z41>OZS4QxRhXv?Z`+Y~BeT8;O@H@u=IX{-1nb8Kx7LxaYErVcpKUiKWlpv&UmZ-H` z-QcD%Gz~`d8cLfaMz@1#+k2h1hIlm#M2_nUA6DlmdfT$j~6+{q>i<|swuT!W& zX$67Hr1Z9SNESFFVS^hiA(0di@+%11Mj||;qwZk zS4f)K9bPI~LITe`6Fmx(HUf#DoxDGP_3kXfMV`+vlEBIg0EuO#NWlg+$zVrqlMp-D z7#k!8IL47vxpR}4=_~#f+^eM49uy4Xx3SkL0o}MseedNd(lcue_%;%4uj{&PTRD|} zt-&ETLXH(&Us`Js#4CeWXa#t+qeBKuQm|%akZ@{@nj|0qDF!L9-&`oCyKh`b;R849*Erm27?W>D-1Il{)Z z(;%afpvkV>mPyL5ueVKa zVRStULApk4v<|e_IK`=DNg;%piLGi!Ga|7=Xi`}L;z$HhB!LzhTGm33THuj>Ye`1G zl1AA-2hFgS3IJef7=aA6A{^{$wYwzxfxnvhMPtqfMT#Pjach=O5!k6z4ba9(X|Q

    rl5%ZX>1f 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/install/img/pat01.png b/AvocadoEdition/install/img/pat01.png new file mode 100644 index 0000000000000000000000000000000000000000..238c054d2adb3be29f9158d762eb5b58174fa986 GIT binary patch literal 32481 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�M{u|4~~Podqw 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 O0000 + + +

    +

    + 라이센스(License) 내용을 반드시 확인하십시오.
    + 라이센스에 동의하시는 경우에만 설치가 진행됩니다. +

    + +
    + +
    + +

    + 그누보드 라이센스
    + 라이센스에 동의하시는 경우에만 설치가 진행됩니다. +

    + +
    + +
    +
    +
    + + +
    + +
    + +
    +
    +
    + + + + + + + diff --git a/AvocadoEdition/install/install.css b/AvocadoEdition/install/install.css new file mode 100644 index 0000000..720e613 --- /dev/null +++ b/AvocadoEdition/install/install.css @@ -0,0 +1,39 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 공통 */ +body {margin:0;padding:0;background:url('img/pat01.png') #edf0f4;font-size:0.75em;font-family:dotum,helvetica} +input, img, select, button {font-size:1em;vertical-align:middle} +label {vertical-align:middle} + +#ins_bar {margin:0 0 50px;padding:20px 30px;background:#383838;color:#a1a4a7;font-family:tahoma,helvetica;font-size:1.500em;zoom:1} +#ins_bar:after {display:block;visibility:hidden;clear:both;content:""} +#ins_bar #bar_img {float:left} +#ins_bar #bar_txt {float:right} + +h1 {margin:0 0 30px;text-align:center; font-size: 20px !important;} + +.ins_inner {margin:0 30px 50px;padding:20px 30px;border-right:1px solid #dde4e9;border-bottom:1px solid #dde4e9;background:#fff} +.ins_inner ul {margin:20px 0;padding:0 0 0 13px} +.ins_inner ol {margin:20px 0;padding:0 0 0 18px} +.ins_inner ol li {margin:0 0 5px} +.ins_inner p strong {color:red} +.ins_inner .inner_btn {margin:30px 0 0;text-align:right} +.ins_inner .inner_btn a, .ins_inner .inner_btn input {display:inline-block;padding:10px 20px;background:#29c7c9;color:#fff;text-decoration:none} +.ins_inner .inner_btn input {border:0;cursor:pointer} + +.ins_frm {margin:0 0 30px;width:100%;border:0;border-collapse:collapse} +.ins_frm caption {padding:10px 0;font-weight:bold;text-align:left} +.ins_frm th, .ins_frm td {padding:5px 3px;border-top:1px solid #dde4e9;border-bottom:1px solid #dde4e9} +.ins_frm th {width:25%;background:#f2f5f9} +.ins_frm td span {display:block;margin:5px 0 0;font-size:0.917em;letter-spacing:-0.1em} + +.ins_ta {padding:5px 0;border:1px solid #dde4e9;text-align:center} +.ins_ta textarea {border:0;padding:0;width:99%;height:250px;background:transparent} +.ins_license {background:#f2f5f9} + +#ins_ft {color:#a1a4a7;font-family:tahoma,helvetica;text-align:center} +#ins_ft strong {font-size:1.500em;font-weight:normal} + +/* 라이센스 확인 1/3 */ +#ins_agree {padding:10px 0 0;text-align:right} \ No newline at end of file diff --git a/AvocadoEdition/install/install.inc.php b/AvocadoEdition/install/install.inc.php new file mode 100644 index 0000000..3867f34 --- /dev/null +++ b/AvocadoEdition/install/install.inc.php @@ -0,0 +1,96 @@ + + + + + +<?php echo $title; ?> + + + + +
    + AVOCADO EDITION + INSTALLATION +
    + + +

    프로그램이 이미 설치되어 있습니다.

    + +
    +

    프로그램이 이미 설치되어 있습니다.
    새로 설치하시려면 다음 파일을 삭제 하신 후 새로고침 하십시오.

    +
      +
    • +
    +
    + + + +

    설치를 위해 아래 내용을 확인해 주십시오.

    + +
    +

    + 루트 디렉토리에 아래로 디렉토리를 생성하여 주십시오.
    + (common.php 파일이 있는곳이 루트 디렉토리 입니다.)

    + $> mkdir

    + 윈도우의 경우 data 폴더를 하나 생성해 주시기 바랍니다.

    + 위 명령 실행후 브라우저를 새로고침 하십시오. +

    +
    + + + +
    +

    + 디렉토리의 퍼미션을 705로 변경하여 주십시오.

    + $> chmod 705 또는 chmod uo+rx

    + 위 명령 실행후 브라우저를 새로고침 하십시오. +

    +
    + +
    +

    + 디렉토리의 퍼미션을 707로 변경하여 주십시오.

    + $> chmod 707 또는 chmod uo+rwx

    + 위 명령 실행후 브라우저를 새로고침 하십시오. +

    +
    + \ No newline at end of file diff --git a/AvocadoEdition/install/install.inc2.php b/AvocadoEdition/install/install.inc2.php new file mode 100644 index 0000000..46bed03 --- /dev/null +++ b/AvocadoEdition/install/install.inc2.php @@ -0,0 +1,7 @@ +
    + AVOCADO EDITION +

    GPL! OPEN SOURCE GNUBOARD

    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/install/install_config.php b/AvocadoEdition/install/install_config.php new file mode 100644 index 0000000..415a78d --- /dev/null +++ b/AvocadoEdition/install/install_config.php @@ -0,0 +1,162 @@ +

    라이센스(License) 내용에 동의하셔야 설치를 계속하실 수 있습니다.

    ".PHP_EOL; + echo "".PHP_EOL; + exit; +} +?> + + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MySQL 정보입력
    + +
    + +
    + +
    + +
    + + 가능한 변경하지 마십시오. +
    + + 호스팅 업체에서 제공하는 WEB MYSQL 관리자 주소를 입력하세요. +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    최고관리자 정보입력
    + +
    + +
    + +
    + +
    + +

    + 주의! 이미 이 존재한다면 DB 자료가 망실되므로 주의하십시오.
    + 주의사항을 이해했으며, 아보카도 에디션 설치를 계속 진행하시려면 다음을 누르십시오. +

    + +
    + +
    +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/install/install_db.php b/AvocadoEdition/install/install_db.php new file mode 100644 index 0000000..938c81a --- /dev/null +++ b/AvocadoEdition/install/install_db.php @@ -0,0 +1,459 @@ + + +
    +

    MySQL Host, User, Password 를 확인해 주십시오.

    + +
    + + + +
    +

    MySQL DB 를 확인해 주십시오.

    + +
    + + + +
    +

    설치가 시작되었습니다.

    + +
      + + +
    1. 전체 테이블 생성 완료
    2. + +\'\"\\\'\\\"\%\=\(\)\/\^\*]/", '', $host); + $result['url'] = $http.$host.$port.$user.$root; + $result['url'] = str_replace("/install", "", $result['url']); + return $result; +} +$g5_path = g5_path_temp(); +$sql = " INSERT INTO `{$table_prefix}css_config` (`cs_id`, `cs_name`, `cs_value`, `cs_descript`, `cs_etc_1`, `cs_etc_2`, `cs_etc_3`, `cs_etc_4`, `cs_etc_5`, `cs_etc_6`, `cs_etc_7`, `cs_etc_8`, `cs_etc_9`, `cs_etc_10`) VALUES + (1, 'logo', '".$g5_path['url']."/adm/img/logo.png', '', '', '', '', '', '', '', '', '', '', ''), + (2, 'm_logo', '".$g5_path['url']."/adm/img/logo.png', '', '', '', '', '', '', '', '', '', '', ''), + (3, 'background', '".$g5_path['url']."/skin/member/basic/img/bak_admin_login_top_pattern.png', '', '', '', '', '', '', '', '', '', '', ''), + (4, 'm_background', '".$g5_path['url']."/skin/member/basic/img/bak_admin_login_top_pattern.png', '', '', '', '', '', '', '', '', '', '', ''), + (5, 'menu_pos', 'left', '', '', '', '', '', '', '', '', '', '', ''), + (6, 'menu_width', '200', '', '', '', '', '', '', '', '', '', '', ''), + (7, 'menu_height', '50', '', '', '', '', '', '', '', '', '', '', ''), + (8, 'menu_background', '', '', '', '', '', '', '', '', '', '', '', ''), + (9, 'm_menu_background', '', 'rgba(0, 0, 0, .5)', '', '', '', '', '', '', '', '', '', ''), + (10, 'btn_default', '#ffffff', '', '#000000', '#000000', '#ffffff', '#222222', '#000000', '', '', '', '', ''), + (11, 'btn_point', '#ffffff', '', '#29c7c9', '#29c7c9', '#ffffff', '#29c7c9', '#29c7c9', '', '', '', '', ''), + (12, 'btn_etc', '#ffffff', '', '#555555', '#333333', '#ffffff', '#555555', '#333333', '', '', '', '', ''), + (13, 'mmb_contain_bak', '', '', '', '', '', '', '', '', '', '', '', ''), + (14, 'mmb_notice', 'rgba(0, 0, 0, .5)', '', '#ffffff', '', '', '', '', '', '', '', '', ''), + (15, 'mmb_list', '', '', '', '', '', '', '', '', '', '', '', ''), + (16, 'mmb_list_item', '', '', '', '', '', '', '', '', '', '', '', ''), + (17, 'mmb_log', '', '', '', '', '', '', '', '', '', '', '', ''), + (18, 'mmb_reply', '', '', '', '', '', '', '', '', '', '', '', ''), + (19, 'mmb_reply_item', 'rgba(0, 0, 0, .5)', '', '#eaeaea', '', '', '', '', '10', '', '', '', ''), + (20, 'mmb_name', '#eeeeee', '', '12', '', '', '', '', '', '', '', '', ''), + (21, 'mmb_owner_name', '#29c7c9', '', '12', '▶', '◀', '', '', '', '', '', '', ''), + (22, 'mmb_datetime', '#bbbbbb', '', '11', '', '', '', '', '', '', '', '', ''), + (23, 'mmb_link', '#29c7c9', '', '', '', '', '', '', '', '', '', '', ''), + (24, 'mmb_call', '#29c7c9', '', '', '', '', '', '', '', '', '', '', ''), + (25, 'mmb_log_ank', '#29c7c9', '', '', '', '', '', '', '', '', '', '', ''), + (26, 'mmb_hash', '#29c7c9', '', '', '', '', '', '', '', '', '', '', ''), + (27, 'color_default', '#ffffff', '', '', '', '', '', '', '', '', '', '', ''), + (28, 'color_bak', '#333333', '', '', '', '', '', '', '', '', '', '', ''), + (29, 'color_point', '#29c7c9', '', '', '', '', '', '', '', '', '', '', ''), + (30, 'input_bak', '#000000', '', '#eeeeee', '#222222', '', '', '', '', '', '', '', ''), + (31, 'box_style', 'rgba(0, 0, 0, .5)', '', '#eeeeee', '', '', '', '', '', '', '', '', ''), + (32, 'menu_text', '#ffffff', '', '14', '#29c7c9', '14', '', '', '', '', '', '', ''), + (33, 'use_header', '', '', '', '', '', '', '', '', '', '', '', ''), + (34, 'm_header_background', '', '', 'rgba(0, 0, 0, .5)', '', '', '', '', '', '', '', '', ''), + (35, 'header_background', '', '', 'rgba(0, 0, 0, .5)', '', '', '', '', '', '', '', '', ''), + (36, 'equalizer', '#29c7c9', '', '#000000', '', '', '', '', '', '', '', '', ''), + (37, 'board_table', '', '', '', '', '', '', '', '', '', '', '', ''), + (38, 'list_header', '#000000', '', '#ffffff', '#333333', 'double', '1', '||top||bottom||', '', '', '', '', ''), + (39, 'list_body', '', '', '#ffffff', '', '', '', '', '', '', '', '', ''), + (40, 'form_header', '#000000', '', '#ffffff', '', '', '', '', '', '', '', '', ''), + (41, 'form_body', 'rgba(255, 255, 255, .1)', '', '#ffffff', '#333333', 'solid', '1', '||top||bottom||', '', '', '', '', ''), + (42, 'sub_menu', 'rgba(0, 0, 0, .5)', '', '#eeeeee', '#555555', 'dashed', '1', '||top||bottom||', '#29c7c9', '', '', '', ''), + (43, 'mmb_counter', '', '', '', '', '', '', '', '', '', '', '', '')"; +sql_query($sql, true, $dblink); + + + +?> + +
    3. DB설정 완료
    4. + + + +
    5. 데이터 디렉토리 생성 완료
    6. + +"); + +fclose($f); +@chmod($file, G5_FILE_PERMISSION); +?> + +
    7. DB설정 파일 생성 완료 ()
    8. + + +Order allow,deny +Deny from all + +EOD; +fwrite($f, $str); +fclose($f); +//------------------------------------------------------------------------------------------------- + + +// CSS 설정 파일 생성 +$css_data_path = $g5_path['path']."/css"; +$css_data_url = $g5_path['url']."/css"; + +@mkdir($css_data_path, G5_DIR_PERMISSION); +@chmod($css_data_path, G5_DIR_PERMISSION); + +$file = '../'.G5_CSS_DIR.'/_design.config.css'; +$file_path = $css_data_path.'/_design.config.css'; +@unlink($file_path); +$f = @fopen($file, 'a'); +?> +
    9. + +
    10. +
    + +

    축하합니다. 설치가 완료되었습니다.

    + +
    + +
    + +

    환경설정 변경은 다음의 과정을 따르십시오.

    + +
      +
    1. 메인화면으로 이동
    2. +
    3. 관리자 로그인
    4. +
    5. 관리자 모드 접속
    6. +
    7. 환경설정 메뉴의 기본환경설정 페이지로 이동
    8. +
    + + + +
    + + \ No newline at end of file diff --git a/AvocadoEdition/install/library.check.php b/AvocadoEdition/install/library.check.php new file mode 100644 index 0000000..c01d964 --- /dev/null +++ b/AvocadoEdition/install/library.check.php @@ -0,0 +1,9 @@ +'.PHP_EOL; + echo 'alert("'.G5_VERSION.'의 정상적인 사용을 위해서는 GD 라이브러리가 필요합니다.\nGD 라이브러리가 없을 경우 자동등록방지 문자와 썸네일 기능이 작동하지 않습니다.");'.PHP_EOL; + echo ''.PHP_EOL; +} +?> \ No newline at end of file diff --git a/AvocadoEdition/intro.php b/AvocadoEdition/intro.php new file mode 100644 index 0000000..f62f510 --- /dev/null +++ b/AvocadoEdition/intro.php @@ -0,0 +1,45 @@ + 0) { + add_stylesheet('', 0); + ?> +
    + ".$intro[$i][ +
    + + + +
    + +
    + + diff --git a/AvocadoEdition/inventory/_common.php b/AvocadoEdition/inventory/_common.php new file mode 100644 index 0000000..b556cc9 --- /dev/null +++ b/AvocadoEdition/inventory/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/_head.php b/AvocadoEdition/inventory/_head.php new file mode 100644 index 0000000..c9bf5a4 --- /dev/null +++ b/AvocadoEdition/inventory/_head.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/_head.sub.php b/AvocadoEdition/inventory/_head.sub.php new file mode 100644 index 0000000..0067cf7 --- /dev/null +++ b/AvocadoEdition/inventory/_head.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/_tail.php b/AvocadoEdition/inventory/_tail.php new file mode 100644 index 0000000..ab638fe --- /dev/null +++ b/AvocadoEdition/inventory/_tail.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/_tail.sub.php b/AvocadoEdition/inventory/_tail.sub.php new file mode 100644 index 0000000..392cf17 --- /dev/null +++ b/AvocadoEdition/inventory/_tail.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/detail_item.php b/AvocadoEdition/inventory/detail_item.php new file mode 100644 index 0000000..9041420 --- /dev/null +++ b/AvocadoEdition/inventory/detail_item.php @@ -0,0 +1,19 @@ +아이템 보유 정보를 확인할 수 없습니다.

    "; +} else { + + if(defined('G5_THEME_PATH') && is_file(G5_THEME_PATH."/inventory/item.skin.php")) { + include(G5_THEME_PATH."/inventory/item.skin.php"); + } else { + include(G5_PATH."/inventory/skin/item.skin.php"); + } + +} ?> \ No newline at end of file diff --git a/AvocadoEdition/inventory/extend/_sample.config.php b/AvocadoEdition/inventory/extend/_sample.config.php new file mode 100644 index 0000000..f9725bd --- /dev/null +++ b/AvocadoEdition/inventory/extend/_sample.config.php @@ -0,0 +1,29 @@ + \ No newline at end of file diff --git a/AvocadoEdition/inventory/inc/add_item_form.php b/AvocadoEdition/inventory/inc/add_item_form.php new file mode 100644 index 0000000..fef2c25 --- /dev/null +++ b/AvocadoEdition/inventory/inc/add_item_form.php @@ -0,0 +1,38 @@ + + +
    +
    + +
    +
    +
    +

    + + +

    +
    +

    +
    +
    + + + + + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/inventory/inc/send_item_form.php b/AvocadoEdition/inventory/inc/send_item_form.php new file mode 100644 index 0000000..734d5d8 --- /dev/null +++ b/AvocadoEdition/inventory/inc/send_item_form.php @@ -0,0 +1,36 @@ + + +
    +
    + +
    +
    +
    +

    + + +

    +
    +
    + + + +
    +
    + + + +
    + +
    +
    + +
    + +
    +
    + +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/inventory/inventory_update.php b/AvocadoEdition/inventory/inventory_update.php new file mode 100644 index 0000000..d7c63ef --- /dev/null +++ b/AvocadoEdition/inventory/inventory_update.php @@ -0,0 +1,54 @@ + diff --git a/AvocadoEdition/inventory/item_form_update.php b/AvocadoEdition/inventory/item_form_update.php new file mode 100644 index 0000000..0e37334 --- /dev/null +++ b/AvocadoEdition/inventory/item_form_update.php @@ -0,0 +1,67 @@ + diff --git a/AvocadoEdition/inventory/list.inc.php b/AvocadoEdition/inventory/list.inc.php new file mode 100644 index 0000000..7fdfac0 --- /dev/null +++ b/AvocadoEdition/inventory/list.inc.php @@ -0,0 +1,31 @@ + diff --git a/AvocadoEdition/inventory/sell_item.php b/AvocadoEdition/inventory/sell_item.php new file mode 100644 index 0000000..ef796a1 --- /dev/null +++ b/AvocadoEdition/inventory/sell_item.php @@ -0,0 +1,18 @@ +아이템 보유 정보를 확인할 수 없습니다.

    "; +} else { + $money = $in['it_sell']; + insert_point($member['mb_id'], $money, '아이템 : '.$in['it_name'].' 판매보상 ( '.$money.$config['cf_money_pice'].' 획득 )', 'item', time(), '판매'); + delete_inventory($in['in_id']); + echo "LOCATIONURL||||".$return_url; +} ?> \ No newline at end of file diff --git a/AvocadoEdition/inventory/send_item.php b/AvocadoEdition/inventory/send_item.php new file mode 100644 index 0000000..1c8c7ad --- /dev/null +++ b/AvocadoEdition/inventory/send_item.php @@ -0,0 +1,15 @@ +아이템 보유 정보를 확인할 수 없습니다.

    "; +} else { + if($in['ch_id'] == $character['ch_id']) { + $ch = $character; + } else { + $ch = get_character($in['ch_id']); + } + + include('./inc/send_item_form.php'); +} ?> \ No newline at end of file diff --git a/AvocadoEdition/inventory/skin/item.skin.php b/AvocadoEdition/inventory/skin/item.skin.php new file mode 100644 index 0000000..81d04fd --- /dev/null +++ b/AvocadoEdition/inventory/skin/item.skin.php @@ -0,0 +1,47 @@ + + + +
    +
    + +
    +
    +
    +

    + + +

    +
    +
    + +
    + +
    + +
    + + +
    +

    +

    By.

    +
    + +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/AvocadoEdition/inventory/skin/list.skin.php b/AvocadoEdition/inventory/skin/list.skin.php new file mode 100644 index 0000000..329ee94 --- /dev/null +++ b/AvocadoEdition/inventory/skin/list.skin.php @@ -0,0 +1,30 @@ + + + + diff --git a/AvocadoEdition/inventory/use_item.php b/AvocadoEdition/inventory/use_item.php new file mode 100644 index 0000000..a16dc35 --- /dev/null +++ b/AvocadoEdition/inventory/use_item.php @@ -0,0 +1,65 @@ +아이템 보유 정보를 확인할 수 없습니다.

    "; +} else { + $inven_function = $in['it_type']; + + if($inven_function == "프로필수정") { + echo location_url(G5_URL."/mypage/character/character_form.php?w=u&ch_id=".$in['ch_id']."&in_id=".$in['in_id']."&url=".$url); + } + if($inven_function == "아이템추가") { + include('./inc/add_item_form.php'); + } + if($inven_function == "스탯회복") { + set_status($ch['ch_id'], $in['st_id'], ($in['it_value'] * -1)); + delete_inventory($in['in_id'], $in['it_use_ever']); + echo location_url($return_url); + } + if($inven_function == "뽑기") { + $result = get_item_explo($in['ch_id'], $in['it_id']); + delete_inventory($in['in_id'], $in['it_use_ever']); + + if($result['it_name']) { + alert("『{$result['it_name']}』 획득 성공!"); + } else { + alert("아무것도 획득하지 못했습니다.", $return_url."&tabs=i"); + } + } + + + // use_item.php 파일을 수정할 필요가 없도록 확장합니다. + $use_extend_file = array(); + $use_tmp = dir(G5_PATH."/inventory/extend"); + while ($entry = $use_tmp->read()) { + // php 파일만 include 함 + if (preg_match("/(\.php)$/i", $entry)) + $use_extend_file[] = $entry; + } + if(!empty($use_extend_file) && is_array($use_extend_file)) { + natsort($use_extend_file); + foreach($use_extend_file as $file) { + include_once(G5_PATH."/inventory/extend/".$file); + } + } + unset($use_extend_file); +}?> \ No newline at end of file diff --git a/AvocadoEdition/js/_custom.js b/AvocadoEdition/js/_custom.js new file mode 100644 index 0000000..f94e57d --- /dev/null +++ b/AvocadoEdition/js/_custom.js @@ -0,0 +1,115 @@ +$(function() { + $('img').attr('title', ''); + $('img[usemap]').rwdImageMaps(); + + $('#header_control_box').on('click', function() { + $('html').toggleClass('close-header'); + + if($('html').hasClass('close-header')) { + // 닫힘상태 + // - 쿠키 설정 + set_cookie('header_close', 'close', 365, g5_cookie_domain); + } else { + // 열림상태 + // - 쿠키 제거 + delete_cookie('header_close'); + } + }); + +}); + +window.onscroll = function() { + var position = $(window).scrollTop(); + if (position > 50) { + $('.uparrow').fadeIn(); + } else { + $('.uparrow').fadeOut(); + } + $('.scroll-fix').css('transform', "translatey(" + position + "px)"); +} + +$(document).on("keydown", "textarea", function(e) { + if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey) { + $(this).parents('form').submit(); + } +}); + +if (document.all) { + document.onkeydown = trapRefreshIE; +} else { + document.captureEvents(Event.KEYDOWN) + document.onkeydown = trapRefreshNS; +} + +function trapRefreshNS(e){ + if (e.keyCode == 116){ + e.cancelBubble = true; + e.returnValue = false; + document.location.reload(); + } +} + +function trapRefreshIE(){ + if (event.keyCode == 116){ + event.keyCode = 0; + event.cancelBubble = true; + event.returnValue = false; + document.location.reload(); + } +} + +function ajax_link_url(url, obj_id) { + var h_link = url; + + if(typeof(history.pushState) != "undefined") { + $.ajax({ + async: true + , url: h_link + , beforeSend: function() {} + , success: function(data) { + // Toss + var response = data; + var temp_content = $(response).find(obj_id).clone(); + + $(obj_id).fadeOut(300, function(){$(this).empty().append(temp_content.html());}).fadeIn(300, function() { + + $(obj_id).find('img').attr('title', ''); + $(obj_id).find('img[usemap]').rwdImageMaps(); + + var link = url; + var link_obj = { Title: '', Url: link}; + history.pushState(link_obj, link_obj.Title, link_obj.Url); + }); + } + , error: function(data, status, err) { + $(obj_id).fadeOut(300, function(){$(this).empty(); }); + } + , complete: function() { + // Complete + } + }); + } else { + location.href=url; + } +} + + +function fn_save_title(val, ch_id) { + var formData = new FormData(); + var ch_id = ch_id; + var ti_id = val; + formData.append("ch_id", ch_id); + formData.append("ti_id", ti_id); + + $.ajax({ + url:g5_url+'/mypage/character/title_update.php' + , data: formData + , processData: false + , contentType: false + , type: 'POST' + , success: function(data){ + + } + }); +} + diff --git a/AvocadoEdition/js/autosave.js b/AvocadoEdition/js/autosave.js new file mode 100644 index 0000000..ac083b5 --- /dev/null +++ b/AvocadoEdition/js/autosave.js @@ -0,0 +1,117 @@ +// 임시 저장하는 시간을 초단위로 설정한다. +var AUTOSAVE_INTERVAL = 60; // 초 + +// 글의 제목과 내용을 바뀐 부분이 있는지 비교하기 위하여 저장해 놓는 변수 +var save_wr_subject = null; +var save_wr_content = null; + +function autosave() { + $("form#fwrite").each(function() { + if(g5_editor != "") { + if (g5_editor.indexOf("ckeditor4") != -1 && typeof(CKEDITOR.instances.wr_content)!="undefined") { + this.wr_content.value = CKEDITOR.instances.wr_content.getData(); + } else if (g5_editor.indexOf("cheditor5") != -1 && typeof(ed_wr_content)!="undefined") { + this.wr_content.value = ed_wr_content.outputBodyHTML(); + } else { + if(typeof get_editor_wr_content == "function") { + this.wr_content.value = get_editor_wr_content(); + } + } + } + + // 변수에 저장해 놓은 값과 다를 경우에만 임시 저장함 + if (save_wr_subject != this.wr_subject.value || save_wr_content != this.wr_content.value) { + $.ajax({ + url: g5_bbs_url+"/ajax.autosave.php", + data: { + "uid" : this.uid.value, + "subject": this.wr_subject.value, + "content": this.wr_content.value + }, + type: "POST", + success: function(data){ + if (data) { + $("#autosave_count").html(data); + } + } + }); + save_wr_subject = this.wr_subject.value; + save_wr_content = this.wr_content.value; + } + }); +} + +$(function(){ + + if (g5_is_member) { + setInterval(autosave, AUTOSAVE_INTERVAL * 1000); + } + + // 임시저장된 글목록을 가져옴 + $("#btn_autosave").click(function(){ + if ($("#autosave_pop").is(":hidden")) { + $.get(g5_bbs_url+"/ajax.autosavelist.php", function(data){ + //alert(data); + //console.log( "Data: " + data); + $("#autosave_pop ul").empty(); + if ($(data).find("list").find("item").length > 0) { + $(data).find("list").find("item").each(function(i) { + var id = $(this).find("id").text(); + var uid = $(this).find("uid").text(); + var subject = $(this).find("subject").text(); + var datetime = $(this).find("datetime").text(); + $("#autosave_pop ul") + .append('
  • '+subject+''+datetime+'
  • ') + .find("li:eq("+i+")") + .data({ as_id: id, uid: uid }); + }); + } + }, "xml"); + $("#autosave_pop").show(); + } else { + $("#autosave_pop").hide(); + } + }); + + // 임시저장된 글 제목과 내용을 가져와서 제목과 내용 입력박스에 노출해 줌 + $(document).on( "click", ".autosave_load", function(){ + var $li = $(this).parents("li"); + var as_id = $li.data("as_id"); + var as_uid = $li.data("uid"); + $("#fwrite input[name='uid']").val(as_uid); + $.get(g5_bbs_url+"/ajax.autosaveload.php", {"as_id":as_id}, function(data){ + var subject = $(data).find("item").find("subject").text(); + var content = $(data).find("item").find("content").text(); + $("#wr_subject").val(subject); + if(g5_editor != "") { + if (g5_editor.indexOf("ckeditor4") != -1 && typeof(CKEDITOR.instances.wr_content)!="undefined") { + CKEDITOR.instances.wr_content.setData(content); + } else if (g5_editor.indexOf("cheditor5") != -1 && typeof(ed_wr_content)!="undefined") { + ed_wr_content.putContents(content); + } else { + if(typeof put_editor_wr_content == "function") { + put_editor_wr_content(content); + } + } + } else { + $("#fwrite #wr_content").val(content); + } + }, "xml"); + $("#autosave_pop").hide(); + }); + + $(document).on( "click", ".autosave_del", function(){ + var $li = $(this).parents("li"); + var as_id = $li.data("as_id"); + $.get(g5_bbs_url+"/ajax.autosavedel.php", {"as_id":as_id}, function(data){ + if (data == -1) { + alert("임시 저장된글을 삭제중에 오류가 발생하였습니다."); + } else { + $("#autosave_count").html(data); + $li.remove(); + } + }); + }); + + $(".autosave_close").click(function(){ $("#autosave_pop").hide(); }); +}); diff --git a/AvocadoEdition/js/certify.js b/AvocadoEdition/js/certify.js new file mode 100644 index 0000000..616760c --- /dev/null +++ b/AvocadoEdition/js/certify.js @@ -0,0 +1,80 @@ +// 본인확인 인증창 호출 +function certify_win_open(type, url) +{ + if(type == 'kcb-ipin') + { + var popupWindow = window.open( url, "kcbPop", "left=200, top=100, status=0, width=450, height=550" ); + popupWindow.focus(); + } + else if(type == 'kcb-hp') + { + var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=430, height=590, scrollbar=yes" ); + popupWindow.focus(); + } + else if(type == 'kcp-hp') + { + if($("input[name=veri_up_hash]").size() < 1) + $("input[name=cert_no]").after(''); + + if( navigator.userAgent.indexOf("Android") > - 1 || navigator.userAgent.indexOf("iPhone") > - 1 ) + { + var $frm = $(event.target.form); + if($("#kcp_cert").size() < 1) { + $frm.wrap('
    '); + + $("#cert_info").append('
    ') + .after(''); + } + + var temp_form = document.form_temp; + temp_form.target = "kcp_cert"; + temp_form.action = url; + + document.getElementById( "cert_info" ).style.display = "none"; + document.getElementById( "kcp_cert" ).style.display = ""; + + temp_form.submit(); + } + else + { + var return_gubun; + var width = 410; + var height = 500; + + var leftpos = screen.width / 2 - ( width / 2 ); + var toppos = screen.height / 2 - ( height / 2 ); + + var winopts = "width=" + width + ", height=" + height + ", toolbar=no,status=no,statusbar=no,menubar=no,scrollbars=no,resizable=no"; + var position = ",left=" + leftpos + ", top=" + toppos; + var AUTH_POP = window.open(url,'auth_popup', winopts + position); + } + } + else if(type == 'lg-hp') + { + var popupWindow = window.open( url, "auth_popup", "left=200, top=100, width=400, height=400, scrollbar=yes" ); + popupWindow.focus(); + } +} + +// 인증체크 +function cert_confirm() +{ + var type; + var val = document.fregisterform.cert_type.value + + switch(val) { + case "ipin": + type = "아이핀"; + break; + case "hp": + type = "휴대폰"; + break; + default: + return true; + } + + if(confirm("이미 "+type+"으로 본인확인을 완료하셨습니다.\n\n이전 인증을 취소하고 다시 인증하시겠습니까?")) + return true; + else + return false; +} \ No newline at end of file diff --git a/AvocadoEdition/js/common.js b/AvocadoEdition/js/common.js new file mode 100644 index 0000000..c7f91ea --- /dev/null +++ b/AvocadoEdition/js/common.js @@ -0,0 +1,803 @@ +// 전역 변수 +var errmsg = ""; +var errfld = null; + +// 필드 검사 +function check_field(fld, msg) +{ + if ((fld.value = trim(fld.value)) == "") + error_field(fld, msg); + else + clear_field(fld); + return; +} + +// 필드 오류 표시 +function error_field(fld, msg) +{ + if (msg != "") + errmsg += msg + "\n"; + if (!errfld) errfld = fld; + fld.style.background = "#BDDEF7"; +} + +// 필드를 깨끗하게 +function clear_field(fld) +{ + fld.style.background = "#FFFFFF"; +} + +function trim(s) +{ + var t = ""; + var from_pos = to_pos = 0; + + for (i=0; i=0; i--) + { + if (s.charAt(i-1) == ' ') + continue; + else + { + to_pos = i; + break; + } + } + + t = s.substring(from_pos, to_pos); + // alert(from_pos + ',' + to_pos + ',' + t+'.'); + return t; +} + +// 자바스크립트로 PHP의 number_format 흉내를 냄 +// 숫자에 , 를 출력 +function number_format(data) +{ + + var tmp = ''; + var number = ''; + var cutlen = 3; + var comma = ','; + var i; + + var sign = data.match(/^[\+\-]/); + if(sign) { + data = data.replace(/^[\+\-]/, ""); + } + + len = data.length; + mod = (len % cutlen); + k = cutlen - mod; + for (i=0; i 0) + document.getElementById(id).rows -= row; +} + +function textarea_original(id, row) +{ + document.getElementById(id).rows = row; +} + +function textarea_increase(id, row) +{ + document.getElementById(id).rows += row; +} + +// 글숫자 검사 +function check_byte(content, target) +{ + var i = 0; + var cnt = 0; + var ch = ''; + var cont = document.getElementById(content).value; + + for (i=0; i 4) { + cnt += 2; + } else { + cnt += 1; + } + } + // 숫자를 출력 + document.getElementById(target).innerHTML = cnt; + + return cnt; +} + +// 브라우저에서 오브젝트의 왼쪽 좌표 +function get_left_pos(obj) +{ + var parentObj = null; + var clientObj = obj; + //var left = obj.offsetLeft + document.body.clientLeft; + var left = obj.offsetLeft; + + while((parentObj=clientObj.offsetParent) != null) + { + left = left + parentObj.offsetLeft; + clientObj = parentObj; + } + + return left; +} + +// 브라우저에서 오브젝트의 상단 좌표 +function get_top_pos(obj) +{ + var parentObj = null; + var clientObj = obj; + //var top = obj.offsetTop + document.body.clientTop; + var top = obj.offsetTop; + + while((parentObj=clientObj.offsetParent) != null) + { + top = top + parentObj.offsetTop; + clientObj = parentObj; + } + + return top; +} + +function flash_movie(src, ids, width, height, wmode) +{ + var wh = ""; + if (parseInt(width) && parseInt(height)) + wh = " width='"+width+"' height='"+height+"' "; + return ""; +} + +function obj_movie(src, ids, width, height, autostart) +{ + var wh = ""; + if (parseInt(width) && parseInt(height)) + wh = " width='"+width+"' height='"+height+"' "; + if (!autostart) autostart = false; + return ""; +} + +function doc_write(cont) +{ + document.write(cont); +} + +var win_password_lost = function(href) { + window.open(href, "win_password_lost", "left=50, top=50, width=617, height=330, scrollbars=1"); +} + +$(document).ready(function(){ + $("#login_password_lost, #ol_password_lost").click(function(){ + win_password_lost(this.href); + return false; + }); +}); + +/** + * 포인트 창 + **/ +var win_point = function(href) { + var new_win = window.open(href, 'win_point', 'left=100,top=100,width=600, height=600, scrollbars=1'); + new_win.focus(); +} + +/** + * 쪽지 창 + **/ +var win_memo = function(href) { + var new_win = window.open(href, 'win_memo', 'left=100,top=100,width=620,height=500,scrollbars=1'); + new_win.focus(); +} + +/** + * 메일 창 + **/ +var win_email = function(href) { + var new_win = window.open(href, 'win_email', 'left=100,top=100,width=600,height=580,scrollbars=0'); + new_win.focus(); +} + +/** + * 자기소개 창 + **/ +var win_profile = function(href) { + var new_win = window.open(href, 'win_profile', 'left=100,top=100,width=620,height=510,scrollbars=1'); + new_win.focus(); +} + +/** + * 스크랩 창 + **/ +var win_scrap = function(href) { + var new_win = window.open(href, 'win_scrap', 'left=100,top=100,width=600,height=600,scrollbars=1'); + new_win.focus(); +} + +/** + * 홈페이지 창 + **/ +var win_homepage = function(href) { + var new_win = window.open(href, 'win_homepage', ''); + new_win.focus(); +} + +/** + * 우편번호 창 + **/ +var win_zip = function(frm_name, frm_zip, frm_addr1, frm_addr2, frm_addr3, frm_jibeon) { + if(typeof daum === 'undefined'){ + alert("다음 우편번호 postcode.v2.js 파일이 로드되지 않았습니다."); + return false; + } + + var zip_case = 1; //0이면 레이어, 1이면 페이지에 끼워 넣기, 2이면 새창 + + var complete_fn = function(data){ + // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분. + + // 각 주소의 노출 규칙에 따라 주소를 조합한다. + // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다. + var fullAddr = ''; // 최종 주소 변수 + var extraAddr = ''; // 조합형 주소 변수 + + // 사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다. + if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우 + fullAddr = data.roadAddress; + + } else { // 사용자가 지번 주소를 선택했을 경우(J) + fullAddr = data.jibunAddress; + } + + // 사용자가 선택한 주소가 도로명 타입일때 조합한다. + if(data.userSelectedType === 'R'){ + //법정동명이 있을 경우 추가한다. + if(data.bname !== ''){ + extraAddr += data.bname; + } + // 건물명이 있을 경우 추가한다. + if(data.buildingName !== ''){ + extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName); + } + // 조합형주소의 유무에 따라 양쪽에 괄호를 추가하여 최종 주소를 만든다. + extraAddr = (extraAddr !== '' ? ' ('+ extraAddr +')' : ''); + } + + // 우편번호와 주소 정보를 해당 필드에 넣고, 커서를 상세주소 필드로 이동한다. + var of = document[frm_name]; + + of[frm_zip].value = data.zonecode; + + of[frm_addr1].value = fullAddr; + of[frm_addr3].value = extraAddr; + + if(of[frm_jibeon] !== undefined){ + of[frm_jibeon].value = data.userSelectedType; + } + + of[frm_addr2].focus(); + }; + + switch(zip_case) { + case 1 : //iframe을 이용하여 페이지에 끼워 넣기 + var daum_pape_id = 'daum_juso_page'+frm_zip, + element_wrap = document.getElementById(daum_pape_id), + currentScroll = Math.max(document.body.scrollTop, document.documentElement.scrollTop); + if (element_wrap == null) { + element_wrap = document.createElement("div"); + element_wrap.setAttribute("id", daum_pape_id); + element_wrap.style.cssText = 'display:none;border:1px solid;left:0;width:100%;height:300px;margin:5px 0;position:relative;-webkit-overflow-scrolling:touch;'; + element_wrap.innerHTML = '접기 버튼'; + jQuery('form[name="'+frm_name+'"]').find('input[name="'+frm_addr1+'"]').before(element_wrap); + jQuery("#"+daum_pape_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){ + e.preventDefault(); + jQuery(this).parent().hide(); + }); + } + + new daum.Postcode({ + oncomplete: function(data) { + complete_fn(data); + // iframe을 넣은 element를 안보이게 한다. + element_wrap.style.display = 'none'; + // 우편번호 찾기 화면이 보이기 이전으로 scroll 위치를 되돌린다. + document.body.scrollTop = currentScroll; + }, + // 우편번호 찾기 화면 크기가 조정되었을때 실행할 코드를 작성하는 부분. + // iframe을 넣은 element의 높이값을 조정한다. + onresize : function(size) { + element_wrap.style.height = size.height + "px"; + }, + width : '100%', + height : '100%' + }).embed(element_wrap); + + // iframe을 넣은 element를 보이게 한다. + element_wrap.style.display = 'block'; + break; + case 2 : //새창으로 띄우기 + new daum.Postcode({ + oncomplete: function(data) { + complete_fn(data); + } + }).open(); + break; + default : //iframe을 이용하여 레이어 띄우기 + var rayer_id = 'daum_juso_rayer'+frm_zip, + element_layer = document.getElementById(rayer_id); + if (element_layer == null) { + element_layer = document.createElement("div"); + element_layer.setAttribute("id", rayer_id); + element_layer.style.cssText = 'display:none;border:5px solid;position:fixed;width:300px;height:460px;left:50%;margin-left:-155px;top:50%;margin-top:-235px;overflow:hidden;-webkit-overflow-scrolling:touch;z-index:10000'; + element_layer.innerHTML = '닫기 버튼'; + document.body.appendChild(element_layer); + jQuery("#"+rayer_id).off("click", ".close_daum_juso").on("click", ".close_daum_juso", function(e){ + e.preventDefault(); + jQuery(this).parent().hide(); + }); + } + + new daum.Postcode({ + oncomplete: function(data) { + complete_fn(data); + // iframe을 넣은 element를 안보이게 한다. + element_layer.style.display = 'none'; + }, + width : '100%', + height : '100%' + }).embed(element_layer); + + // iframe을 넣은 element를 보이게 한다. + element_layer.style.display = 'block'; + } +} + +/** + * 새로운 비밀번호 분실 창 : 101123 + **/ +win_password_lost = function(href) +{ + var new_win = window.open(href, 'win_password_lost', 'width=617, height=330, scrollbars=1'); + new_win.focus(); +} + +/** + * 설문조사 결과 + **/ +var win_poll = function(href) { + var new_win = window.open(href, 'win_poll', 'width=616, height=500, scrollbars=1'); + new_win.focus(); +} + +/** + * 스크린리더 미사용자를 위한 스크립트 - 지운아빠 2013-04-22 + * alt 값만 갖는 그래픽 링크에 마우스오버 시 title 값 부여, 마우스아웃 시 title 값 제거 + **/ +$(function() { + $('a img').mouseover(function() { + $a_img_title = $(this).attr('alt'); + $(this).attr('title', $a_img_title); + }).mouseout(function() { + $(this).attr('title', ''); + }); +}); + +/** + * 텍스트 리사이즈 +**/ +function font_resize(id, rmv_class, add_class) +{ + var $el = $("#"+id); + + $el.removeClass(rmv_class).addClass(add_class); + + set_cookie("ck_font_resize_rmv_class", rmv_class, 1, g5_cookie_domain); + set_cookie("ck_font_resize_add_class", add_class, 1, g5_cookie_domain); +} + +/** + * 댓글 수정 토큰 +**/ +function set_comment_token(f) +{ + if(typeof f.token === "undefined") + $(f).prepend(''); + + $.ajax({ + url: g5_bbs_url+"/ajax.comment_token.php", + type: "GET", + dataType: "json", + async: false, + cache: false, + success: function(data, textStatus) { + f.token.value = data.token; + } + }); +} + +$(function(){ + $(".win_point").click(function() { + win_point(this.href); + return false; + }); + + $(".win_memo").click(function() { + win_memo(this.href); + return false; + }); + + $(".win_email").click(function() { + win_email(this.href); + return false; + }); + + $(".win_scrap").click(function() { + win_scrap(this.href); + return false; + }); + + $(".win_profile").click(function() { + win_profile(this.href); + return false; + }); + + $(".win_homepage").click(function() { + win_homepage(this.href); + return false; + }); + + $(".win_password_lost").click(function() { + win_password_lost(this.href); + return false; + }); + + /* + $(".win_poll").click(function() { + win_poll(this.href); + return false; + }); + */ + + // 사이드뷰 + var sv_hide = false; + $(".sv_member, .sv_guest").click(function() { + $(".sv").removeClass("sv_on"); + $(this).closest(".sv_wrap").find(".sv").addClass("sv_on"); + }); + + $(".sv, .sv_wrap").hover( + function() { + sv_hide = false; + }, + function() { + sv_hide = true; + } + ); + + $(".sv_member, .sv_guest").focusin(function() { + sv_hide = false; + $(".sv").removeClass("sv_on"); + $(this).closest(".sv_wrap").find(".sv").addClass("sv_on"); + }); + + $(".sv a").focusin(function() { + sv_hide = false; + }); + + $(".sv a").focusout(function() { + sv_hide = true; + }); + + // 셀렉트 ul + var sel_hide = false; + $('.sel_btn').click(function() { + $('.sel_ul').removeClass('sel_on'); + $(this).siblings('.sel_ul').addClass('sel_on'); + }); + + $(".sel_wrap").hover( + function() { + sel_hide = false; + }, + function() { + sel_hide = true; + } + ); + + $('.sel_a').focusin(function() { + sel_hide = false; + }); + + $('.sel_a').focusout(function() { + sel_hide = true; + }); + + $(document).click(function() { + if(sv_hide) { // 사이드뷰 해제 + $(".sv").removeClass("sv_on"); + } + if (sel_hide) { // 셀렉트 ul 해제 + $('.sel_ul').removeClass('sel_on'); + } + }); + + $(document).focusin(function() { + if(sv_hide) { // 사이드뷰 해제 + $(".sv").removeClass("sv_on"); + } + if (sel_hide) { // 셀렉트 ul 해제 + $('.sel_ul').removeClass('sel_on'); + } + }); + + $(document).on( "keyup change", "textarea#wr_content[maxlength]", function(){ + var str = $(this).val(); + var mx = parseInt($(this).attr("maxlength")); + if (str.length > mx) { + $(this).val(str.substr(0, mx)); + return false; + } + }); +}); + +function get_write_token(bo_table) +{ + var token = ""; + + $.ajax({ + type: "POST", + url: g5_bbs_url+"/write_token.php", + data: { bo_table: bo_table }, + cache: false, + async: false, + dataType: "json", + success: function(data) { + if(data.error) { + alert(data.error); + if(data.url) + document.location.href = data.url; + + return false; + } + + token = data.token; + } + }); + + return token; +} + +$(function() { + $(document).on("click", "form[name=fwrite] input:submit, form[name=fwrite] button:submit, form[name=fwrite] input:image", function() { + var f = this.form; + var bo_table = f.bo_table.value; + var token = get_write_token(bo_table); + + if(!token) { + alert("토큰 정보가 올바르지 않습니다."); + return false; + } + + var $f = $(f); + + if(typeof f.token === "undefined") + $f.prepend(''); + + $f.find("input[name=token]").val(token); + + return true; + }); +}); + + + + +function ajax_load(url, obj, list_id, rel_id, etc_value) { + + var keyword = obj.value; + var obj_id = obj.getAttribute('id'); + var list_obj = $('#'+list_id+' .list'); + + if(typeof(etc_value) == 'undefined') { + etc_value = ''; + } + + $.ajax({ + type: 'get' + , async: true + , url: url+"?keyword="+keyword+"&input_obj="+obj_id+"&output_obj="+rel_id+"&list_obj="+list_id+"&option="+etc_value + , beforeSend: function() { + //list_obj.empty(); + } + , success: function(data) { + var response = data.trim(); + if(response) { + list_obj.html(response); + list_obj.focus(); + } else { + list_obj.empty(); + } + } + , error: function(data, status, err) { } + , complete: function() { } + }); +} + +function get_ajax_character(obj, list_id, rel_id, etc_value) { + var url = g5_url + "/ajax/_search_character.php"; + ajax_load(url, obj, list_id, rel_id, etc_value); +} + +function get_ajax_title(obj, list_id, rel_id, etc_value) { + var url = g5_url + "/ajax/_search_title.php"; + ajax_load(url, obj, list_id, rel_id, etc_value); +} + +function get_ajax_item(obj, list_id, rel_id, etc_value) { + var url = g5_url + "/ajax/_search_item.php"; + ajax_load(url, obj, list_id, rel_id, etc_value); +} + +function get_ajax_member(obj, list_id, rel_id, etc_value) { + var url = g5_url + "/ajax/_search_member.php"; + ajax_load(url, obj, list_id, rel_id, etc_value); +} + + +function select_item(list_id, in_id, in_value, out_id, out_value) { + document.getElementById(in_id).value = in_value; + document.getElementById(out_id).value = out_value; + $('#'+list_id+' .list').empty(); + return false; +} diff --git a/AvocadoEdition/js/html5.js b/AvocadoEdition/js/html5.js new file mode 100644 index 0000000..560aa94 --- /dev/null +++ b/AvocadoEdition/js/html5.js @@ -0,0 +1,3 @@ +/*! HTML5 Shiv vpre3.6 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed + Uncompressed source: https://github.com/aFarkas/html5shiv */ +(function(a,b){function h(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function i(){var a=l.elements;return typeof a=="string"?a.split(" "):a}function j(a){var b={},c=a.createElement,f=a.createDocumentFragment,g=f();a.createElement=function(a){if(!l.shivMethods)return c(a);var f;return b[a]?f=b[a].cloneNode():e.test(a)?f=(b[a]=c(a)).cloneNode():f=c(a),f.canHaveChildren&&!d.test(a)?g.appendChild(f):f},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+i().join().replace(/\w+/g,function(a){return c(a),g.createElement(a),'c("'+a+'")'})+");return n}")(l,g)}function k(a){var b;return a.documentShived?a:(l.shivCSS&&!f&&(b=!!h(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),g||(b=!j(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea|object|iframe|option|optgroup)$/i,e=/^<|^(?:a|b|button|code|div|fieldset|form|h1|h2|h3|h4|h5|h6|i|iframe|img|input|label|li|link|ol|option|p|param|q|script|select|span|strong|style|table|tbody|td|textarea|tfoot|th|thead|tr|ul)$/i,f,g;(function(){var c=b.createElement("a");c.innerHTML="",f="hidden"in c,f&&typeof injectElementWithStyles=="function"&&injectElementWithStyles("#modernizr{}",function(b){b.hidden=!0,f=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle).display=="none"}),g=c.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var l={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:k};a.html5=l,k(b)})(this,document) \ No newline at end of file diff --git a/AvocadoEdition/js/jquery-1.12.3.min.js b/AvocadoEdition/js/jquery-1.12.3.min.js new file mode 100644 index 0000000..dad4f0a --- /dev/null +++ b/AvocadoEdition/js/jquery-1.12.3.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.3 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0; +}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" + + +
    +
    + <html> +
    +
    +
    +
     
    +
     
    +
     
    +
    + + ]]> + + + + + +
    +
    + +
    +
    +
    + + ]]> + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/cheditor.js b/AvocadoEdition/plugin/editor/cheditor5/cheditor.js new file mode 100644 index 0000000..85b983b --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/cheditor.js @@ -0,0 +1,7963 @@ +// ================================================================ +// CHEditor 5.1.9.3 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// EMail: support@chcode.com +// Copyright (c) 1997-2016 CHSOFT +// ================================================================ +var GB = { + colors: ['#000000','#313131','#434343','#535353','#666666','#999999','#a0a0a0','#b5b5b5','#c0c0c0','#dcdcdc','#eeeeee','#ffffff', + '#ff0000','#ff8000','#ffff00','#80ff00','#00ff00','#00ff99','#00ffff','#0080ff','#0000ff','#7f00ff','#ff00ff','#ff007f', + '#ffcccc','#ffe5cc','#ffffcc','#e5ffcc','#ccffcc','#ccffe5','#ccffff','#cce5ff','#ccccff','#e5ccff','#ffccff','#ffcce5', + '#ff9999','#ffcc99','#ffff99','#ccff99','#99ff99','#99ffcc','#99ffff','#99ccff','#9999ff','#cc99ff','#ff99ff','#ff99cc', + '#ff6666','#ffb266','#ffff66','#b2ff66','#66ff66','#66ffb2','#66ffff','#66b2ff','#6666ff','#b266ff','#ff66ff','#ff66b2', + '#ff3333','#ff9933','#ffff33','#99ff33','#33ff33','#33ff99','#33ffff','#3399ff','#3333ff','#9933ff','#ff33ff','#ff3399', + '#cc0000','#cc6600','#cccc00','#66cc00','#00cc00','#00cc66','#00cccc','#0066cc','#0000cc','#6600cc','#cc00cc','#cc0066', + '#990000','#994c00','#999900','#4c9900','#009900','#00994c','#009999','#004c99','#000099','#4c0099','#990099','#99004c', + '#660000','#663300','#666600','#336600','#006600','#006633','#006666','#003366','#000066','#330066','#660066','#660033'], + offElementTags: { + button: 1, embed: 1, fieldset: 1, form: 1, hr: 1, img: 1, input: 1, object: 1, select: 1, table: 1, textarea: 1 + }, + selfClosingTags: { + area: 1, base: 1, br: 1, col: 1, command: 1, embed: 1, hr: 1, img: 1, input: 1, keygen: 1, link: 1, meta: 1, + param: 1, source: 1, track: 1, wbr: 1 + }, + textFormatTags: { + a: 1, addr: 1, acronym: 1, b: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1, em: 1, font: 1, i: 1, ins: 1, kbd: 1, + q: 1, samp: 1, small: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1, span: 1 + }, + textFormatBlockTags: { + address: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, p: 1, pre: 1, code: 1, section: 1, aside: 1, article: 1, figcaption: 1 + }, + newLineBeforeTags: { + address: 1, article: 1, aside: 1, audio: 1, blockquote: 1, body: 1, canvas: 1, code: 1, comment: 1, dd: 1, div: 1, + dl: 1, fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, head: 1, + header: 1, hggroup: 1, hr: 1, li: 1, noscript: 1, ol: 1, output: 1, p: 1, pre: 1, script: 1, section: 1, table: 1, + tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, title: 1, tr: 1, ul: 1, video: 1 + }, + lineHeightBlockTags: { + address: 1, article: 1, aside: 1, blockquote: 1, code: 1, dd: 1, div: 1, dt: 1, figcaption: 1, figure: 1, + h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, li: 1, p: 1, pre: 1, section: 1, td: 1, th: 1 + }, + listTags: { dd: 1, dt: 1, li: 1 }, + lineBreakTags: { address: 1, article: 1, aside: 1, dd: 1, div: 1, dt: 1, figcaption: 1, li: 1, p: 1, section: 1 }, + doctype: '', + popupWindow: { + ColorPicker : {tmpl : 'color_picker.html', width : 420, title : '색상 선택'}, + Embed : {tmpl : 'media.html', width : 430, title : '미디어'}, + EmotionIcon : {tmpl : 'icon.html', width : 300, title : '표정 아이콘'}, + FlashMovie : {tmpl : 'flash.html', width : 584, title : '플래쉬 동영상'}, + GoogleMap : {tmpl : 'google_map.html', width : 538, title : '구글 지도'}, + ImageUpload : {tmpl : 'image.html', width : 700, title : '내 PC 사진 넣기'}, + ImageUrl : {tmpl : 'image_url.html', width : 350, title : '웹 사진 넣기'}, + Layout : {tmpl : 'layout.html', width : 430, title : '레이아웃'}, + Link : {tmpl : 'link.html', width : 350, title : '하이퍼링크'}, + ModifyTable : {tmpl : 'table_modify.html', width : 430, title : '표 고치기'}, + Symbol : {tmpl : 'symbol.html', width : 450, title : '특수 문자'}, + Table : {tmpl : 'table.html', width : 430, title : '표 만들기'} + }, + fontName: { + kr : ['맑은 고딕', '돋움', '굴림', '바탕', '궁서'], + en : ['Arial', 'Comic Sans MS', 'Courier New', 'Georgia', 'HeadLineA', 'Impact', 'Tahoma', 'Times New Roman', 'Verdana'] + }, + fontStyle: { + FontSize: 'font-size', FontName: 'font-family', ForeColor: 'color', BackColor: 'background-color' + }, + textAlign: { + JustifyLeft: '', JustifyCenter: 'center', JustifyRight: 'right', JustifyFull: 'justify' + }, + listStyle: { + ordered: { + decimal: '숫자', 'lower-alpha': '영문 소문자', 'upper-alpha': '영문 대문자', 'lower-roman': '로마 소문자', 'upper-roman': '로마 대문자' + }, + unOrdered: {desc: '동그라미', circle: '빈 원', square: '사각형'} + }, + fontSize: { + pt: [7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36], + px: [9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72] + }, + formatBlock: { + P: '일반 텍스트', + H1: '제목 1', + H2: '제목 2', + H3: '제목 3', + H4: '제목 4', + H5: '제목 5', + H6: '제목 6', + ADDRESS: 'Address', + DIV: 'DIV', + PRE: 'Preformatted (PRE)' + }, + lineHeight: { + '한 줄 간격': 1, '1.15': 1.15, '1.5': 1.5, '1.7': 1.7, '1.8': 1.8, '두 줄 간격': 2 + }, + textBlock: [ + ['1px #dedfdf solid','#f7f7f7'], + ['1px #aee8e8 solid','#bfffff'], + ['1px #d3bceb solid','#e6ccff'], + ['1px #e8e88b solid','#ffff99'], + ['1px #c3e89e solid','#d6ffad'], + ['1px #e8c8b7 solid','#ffdcc9'], + ['1px #666666 dashed','#ffffff'], + ['1px #d4d4d4 solid','#ffffff'], + ['1px #cccccc inset','#f7f7f7'] + ], + node: { + element: 1, attribute: 2, text: 3, cdata_section: 4, entity_reference: 5, entity: 6, + processing_instruction: 7, comment: 8, document: 9, document_type: 10, document_fragment: 11, + notation: 12 + }, + + selection: { none: 1, text: 2, element: 3 }, + readyState: { 0: 'uninitialized', 1: 'loading', 2: 'loaded', 3: 'interactive', 4: 'complete' }, + dragWindow: null, + colorDropper: null, + readyEditor: 0, + browser: {} +}; + +function isUndefined(obj) { + return obj === void(0); // obj === undefined; +} + +function detechBrowser() { + function detect(ua) { + var iosdevice = getFirstMatch(/(ipod|iphone|ipad)/i).toLowerCase(), + likeAndroid = /like android/i.test(ua), + android = !likeAndroid && /android/i.test(ua), + versionIdentifier = getFirstMatch(/version\/(\d+(\.\d+)?)/i), + tablet = /tablet/i.test(ua), + mobile = !tablet && /[^\-]mobi/i.test(ua), + result, + osVersion = '', + osMajorVersion, + osname, + app; + + function getFirstMatch(regex) { + var match = ua.match(regex); + return (match && match.length > 1 && match[1]) || ''; + } + + if (/opera|opr/i.test(ua)) { + result = { + name: 'Opera', opera: true, + version: versionIdentifier || getFirstMatch(/(?:opera|opr)[\s\/](\d+(\.\d+)?)/i) + }; + } else if (/windows phone/i.test(ua)) { + result = { + name: 'Windows Phone', windowsphone: true, msie: true, + version: getFirstMatch(/iemobile\/(\d+(\.\d+)?)/i) + }; + } else if (/msie|trident/i.test(ua)) { + result = { + name: 'Internet Explorer', msie: true, version: getFirstMatch(/(?:msie |rv:)(\d+(\.\d+)?)/i) + }; + } else if (/edge/i.test(ua)) { + result = { + name: 'edge', edge: true, version: getFirstMatch(/(?:edge)\/(\d+(\.\d+)?)/i) + }; + } else if (/chrome|crios|crmo/i.test(ua)) { + result = { + name: 'Chrome', chrome: true, version: getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.\d+)?)/i) + }; + } else if (iosdevice) { + result = { + name: iosdevice === 'iphone' ? 'iPhone' : iosdevice === 'ipad' ? 'iPad' : 'iPod' + }; + if (versionIdentifier) { + result.version = versionIdentifier; + } + } else if (/firefox|iceweasel/i.test(ua)) { + result = { + name: 'Firefox', firefox: true, + version: getFirstMatch(/(?:firefox|iceweasel)[ \/](\d+(\.\d+)?)/i) + }; + if (/\((mobile|tablet);[^\)]*rv:[\d\.]+\)/i.test(ua)) { + result.firefoxos = true; + } + } else if (/silk/i.test(ua)) { + result = { + name: 'Amazon Silk', silk: true, version : getFirstMatch(/silk\/(\d+(\.\d+)?)/i) + }; + } else if (android) { + result = { name: 'Android', version: versionIdentifier }; + } else if (/phantom/i.test(ua)) { + result = { + name: 'PhantomJS', phantom: true, version: getFirstMatch(/phantomjs\/(\d+(\.\d+)?)/i) + }; + } else if (/blackberry|\bbb\d+/i.test(ua) || /rim\stablet/i.test(ua)) { + result = { + name: 'BlackBerry', blackberry: true, + version: versionIdentifier || getFirstMatch(/blackberry[\d]+\/(\d+(\.\d+)?)/i) + }; + } else if (/(web|hpw)os/i.test(ua)) { + result = { + name: 'WebOS', webos: true, + version: versionIdentifier || getFirstMatch(/w(?:eb)?osbrowser\/(\d+(\.\d+)?)/i) + }; + if (/touchpad\//i.test(ua)) { + result.touchpad = true; + } + } else if (/safari/i.test(ua)) { + result = { + name: 'Safari', safari: true, version: versionIdentifier + }; + } else { + result = {}; + } + + if (/(apple)?webkit/i.test(ua)) { + result.name = result.name || 'Webkit'; + result.webkit = true; + if (!result.version && versionIdentifier) { + result.version = versionIdentifier; + } + } else if (!result.opera && /gecko\//i.test(ua)) { + result.gecko = true; + result.version = result.version || getFirstMatch(/gecko\/(\d+(\.\d+)?)/i); + result.name = result.name || 'Gecko'; + } + if (android || result.silk) { + result.android = true; + } else if (iosdevice) { + result[iosdevice] = true; + result.ios = true; + } + + if (iosdevice) { + osVersion = getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i); + osVersion = osVersion.replace(/[_\s]/g, '.'); + } else if (android) { + osVersion = getFirstMatch(/android[ \/\-](\d+(\.\d+)*)/i); + } else if (result.windowsphone) { + osVersion = getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i); + } else if (result.webos) { + osVersion = getFirstMatch(/(?:web|hpw)os\/(\d+(\.\d+)*)/i); + } else if (result.blackberry) { + osVersion = getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i); + } + + if (osVersion) { + result.osversion = osVersion; + } + + osMajorVersion = osVersion.split('.')[0]; + if (tablet || iosdevice === 'ipad' || + (android && (osMajorVersion === 3 || (osMajorVersion === 4 && !mobile))) || + result.silk) { + result.tablet = true; + } else if (mobile || iosdevice === 'iphone' || iosdevice === 'ipod' || android || + result.blackberry || result.webos) { + result.mobile = true; + } + + if (result.edge || + (result.msie && result.version >= 10) || + (result.chrome && result.version >= 20) || + (result.firefox && result.version >= 20.0) || + (result.safari && result.version >= 6) || + (result.opera && result.version >= 10.0) || + (result.ios && result.osversion && result.osversion.split('.')[0] >= 6) || + (result.blackberry && result.version >= 10.1)) { + result.a = true; + } else if ((result.msie && result.version < 10) || + (result.chrome && result.version < 20) || + (result.firefox && result.version < 20.0) || + (result.safari && result.version < 6) || + (result.opera && result.version < 10.0) || + (result.ios && result.osversion && result.osversion.split('.')[0] < 6)) { + result.c = true; + } else { + result.x = true; + } + + osname = ''; + if (/windows/i.test(ua)) { + osname = 'Windows'; + } else if (/mac/i.test(ua)) { + osname = 'MacOS'; + } else if (/x11/i.test(ua)) { + osname = 'UNIX'; + } else if (/linux/i.test(ua)) { + osname = 'Linux'; + } else if (/sunos/i.test(ua)) { + osname = 'Solaris'; + } else { + osname = 'Unknown OS'; + } + result.osname = osname; + + if (osname === 'Windows') { + app = getFirstMatch(/(Windows NT\s(\d+)\.(\d+))/i); + switch (app) { + case 'Windows NT 5.1' : result.os = 'Windows XP'; break; + case 'Windows NT 5.2' : result.os = 'Windows 2003'; break; + case 'Windows NT 6.0' : result.os = 'Windows Vista'; break; + case 'Windows NT 6.1' : result.os = 'Windows 7'; break; + case 'Windows NT 6.2' : result.os = 'Windows 8'; break; + case 'Windows NT 6.3' : result.os = 'Windows 8.1'; break; + case 'Windows NT 10.0' : result.os = 'Windows 10'; break; + default : result.os = app; + } + } + + if (result.msie) { + if (result.version > 10) { + result.msie_a = true; + result.msie_bogus = true; + } else if (result.version > 8) { + result.msie_b = true; + result.msie_bogus = false; + } else { + result.msie_c = true; + result.msie_bogus = (result.os === 'Windows XP'); + } + } + return result; + } + return detect(!isUndefined(navigator) ? navigator.userAgent : null); +} + +function URI(uri) { + this.scheme = null; + this.authority = null; + this.path = ''; + this.query = null; + this.fragment = null; + + this.parseUri = function (uri) { + var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.\-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/); + this.scheme = m[3] ? m[2] : null; + this.authority = m[5] ? m[6] : null; + this.path = m[7]; + this.query = m[9] ? m[10] : null; + this.fragment = m[12] ? m[13] : null; + return this; + }; + + this.azToString = function () { + var result = ''; + if (this.scheme !== null) { + result = result + this.scheme + ':'; + } + if (this.authority !== null) { + result = result + '//' + this.authority; + } + if (this.path !== null) { + result = result + this.path; + } + if (this.query !== null) { + result = result + '?' + this.query; + } + if (this.fragment !== null) { + result = result + '#' + this.fragment; + } + return result; + }; + + this.toAbsolute = function (location) { + var baseUri = new URI(location), + URIAbs = this, + target = new URI(), + removeDotSegments = function (path) { + var result = '', rm; + while (path) { + if (path.substr(0, 3) === '../' || path.substr(0, 2) === './') { + path = path.replace(/^\.+/, '').substr(1); + } else if (path.substr(0, 3) === '/./' || path === '/.') { + path = '/' + path.substr(3); + } else if (path.substr(0, 4) === '/../' || path === '/..') { + path = '/' + path.substr(4); + result = result.replace(/\/?[^\/]*$/, ''); + } else if (path === '.' || path === '..') { + path = ''; + } else { + rm = path.match(/^\/?[^\/]*/)[0]; + path = path.substr(rm.length); + result = result + rm; + } + } + return result; + }; + + if (baseUri.scheme === null) { + return false; + } + if (URIAbs.scheme !== null && URIAbs.scheme.toLowerCase() === baseUri.scheme.toLowerCase()) { + URIAbs.scheme = null; + } + + if (URIAbs.scheme !== null) { + target.scheme = URIAbs.scheme; + target.authority = URIAbs.authority; + target.path = removeDotSegments(URIAbs.path); + target.query = URIAbs.query; + } else { + if (URIAbs.authority !== null) { + target.authority = URIAbs.authority; + target.path = removeDotSegments(URIAbs.path); + target.query = URIAbs.query; + } else { + if (URIAbs.path === '') { + target.path = baseUri.path; + target.query = URIAbs.query || baseUri.query; + } else { + if (URIAbs.path.substr(0, 1) === '/') { + target.path = removeDotSegments(URIAbs.path); + } else { + if (baseUri.authority !== null && baseUri.path === '') { + target.path = '/' + URIAbs.path; + } else { + target.path = baseUri.path.replace(/[^\/]+$/, '') + URIAbs.path; + } + target.path = removeDotSegments(target.path); + } + target.query = URIAbs.query; + } + target.authority = baseUri.authority; + } + target.scheme = baseUri.scheme; + } + target.fragment = URIAbs.fragment; + return target; + }; + if (uri) { + this.parseUri(uri); + } +} + +function setConfig() { + var config = { + allowedOnEvent : true, + colorToHex : true, + docTitle : '내 문서', + editAreaMargin : '5px 10px', + editorBgColor : '#fff', + editorFontColor : '#000', + editorFontName : '"맑은 고딕", "Malgun Gothic", gulim', + editorFontSize : '12px', + editorHeight : '300px', + editorPath : null, + editorWidth : '100%', + exceptedElements : { script: true, style: true, iframe: false }, + fontSizeValue : 'px', // [pt, px] + fullHTMLSource : false, + imgBlockMargin : '5px 0px', + imgCaptionFigure : 'border: 1px #ccc solid; background-color: #f0f0f0; margin: 0', + imgCaptionText : 'margin: 5px 5px; text-align: left; line-height: 17px', + imgCaptionWrapper : '', + imgDefaultAlign : 'left', // [left, center, right] + imgJpegQuality : 0.92, // JPEG 사진의 퀄리티 값, 최대값 1 + imgMaxWidth : 800, // 사진 최대 가로 크기, 이 크기 보다 크면 리사이징 처리 + imgResizeMinLimit : 32, // 사진 리사이징의 사용자 직접 입력 값이 이 값 보다 작으면, 이 값으로 설정 + imgResizeSelected : 800, // 사진 리사이징의 선택 입력 폼의 기본 선택 값 + imgResizeValue : [120, 240, 320, 640, 800, -1], // -1 = 사용자 직접 입력 + imgSetAttrAlt : true, + imgSetAttrWidth : 1, // -1 = (width="100%"; height="auto"), 0 = 설정 안함, 1 = 기본값 + imgUploadNumber : 12, + imgUploadSortName : false, + imgWaterMarkAlpha : 1, // 워터마크 불투명도 (최대값 1) + imgWaterMarkUrl : '', // 워터마크 이미지 URL (예: 'http://udomain.com/cheditor/icons/watermark.png') + includeHostname : true, + lineHeight : 1.7, + linkTarget : '_blank', + makeThumbnail : false, // 사진의 썸네일 이미지 생성, 가로 크기는 thumbnailWidth 값, 세로는 자동 계산 + paragraphCss : false, // true =

    , false =

    + removeIndent : false, + showTagPath : false, + tabIndent : 3, + tabIndex : 0, + thumbnailWidth : 120, + + // 버튼 사용 유무 + useSource : true, + usePreview : true, + usePrint : true, + useNewDocument : true, + useUndo : true, + useRedo : true, + useCopy : true, + useCut : true, + usePaste : true, + usePasteFromWord : true, + useSelectAll : true, + useStrikethrough : true, + useUnderline : true, + useItalic : true, + useSuperscript : false, + useSubscript : false, + useJustifyLeft : true, + useJustifyCenter : true, + useJustifyRight : true, + useJustifyFull : true, + useBold : true, + useOrderedList : true, + useUnOrderedList : true, + useOutdent : true, + useIndent : true, + useFontName : true, + useFormatBlock : true, + useFontSize : true, + useLineHeight : true, + useBackColor : true, + useForeColor : true, + useRemoveFormat : true, + useClearTag : true, + useSymbol : true, + useLink : true, + useUnLink : true, + useFlash : true, + useMedia : false, + useImage : true, + useImageUrl : false, + useSmileyIcon : true, + useHR : true, + useTable : true, + useModifyTable : true, + useMap : true, + useTextBlock : true, + useFullScreen : true, + usePageBreak : false + }, + base, elem, i, editorUri, locationAbs; + + if (config.editorPath === null) { + base = location.href; + elem = document.getElementsByTagName('base'); + for (i = 0; i < elem.length; i++) { + if (elem[i].href) { + base = elem[i].href; + } + } + elem = document.getElementsByTagName('script'); + for (i = 0; i < elem.length; i++) { + if (elem[i].src) { + editorUri = new URI(elem[i].src); + if (/\/cheditor\.js$/.test(editorUri.path)) { + locationAbs = editorUri.toAbsolute(base).azToString(); + delete locationAbs.query; + delete locationAbs.fragment; + config.editorPath = locationAbs.replace(/[^\/]+$/, ''); + } + } + } + if (config.editorPath === null) { + throw 'CHEditor 경로가 바르지 않습니다.\nmyeditor.config.editorPath를 설정하여 주십시오.'; + } + } + + this.storedSelections = []; + this.keyPressStoredSelections = []; + this.images = []; + this.editImages = {}; + this.cheditor = {}; + this.toolbar = {}; + this.pulldown = {}; + this.currentRS = {}; + this.resizeEditor = {}; + this.setFullScreenMode = false; + this.modalElementZIndex = 1001; + this.config = config; + this.templateFile = 'template.xml'; + this.templatePath = config.editorPath + this.templateFile; + this.W3CRange = !(this.undefined(window.getSelection)); + this.inputForm = 'textAreaId'; + this.range = null; + this.tempTimer = null; + this.cheditor.tabSpaces = ''; + this.cheditor.modifyState = false; + this.cheditor.tabSpaces = new Array(this.config.tabIndent + 1).join(' '); +} + +function cheditor() { + this.toType = (function (global) { + var toString = cheditor.prototype.toString, + re = /^.*\s(\w+).*$/; + + return function (obj) { + if (obj === global) { + return 'global'; + } + return toString.call(obj).replace(re, '$1').toLowerCase(); + }; + }(this)); + + this.undefined = isUndefined; + GB.browser = this.browser = detechBrowser(); + + if (this.undefined(document.execCommand)) { + alert('현재 브라우저에서 CHEditor를 실행할 수 없습니다.'); + return null; + } + if (this.browser.msie && this.browser.version < 7) { + alert('CHEditor는 Internet Explorer 7 이하 버전은 지원하지 않습니다.'); + return null; + } + + try { + setConfig.call(this); + this.cheditor.id = (this.undefined(GB.readyEditor)) ? 1 : GB.readyEditor++; + } catch (e) { + alert(e.toString()); + return null; + } + + return this; +} + +cheditor.prototype = { + //---------------------------------------------------------------- + resetData : function () { + if (GB.browser.msie) { + if (this.undefined(this.cheditor.editArea.onreadystatechange)) { + GB.browser.version = 11; + } + GB.browser.msie_bogus = (GB.browser.version < 8 || GB.browser.version > 10); + document.execCommand('BackgroundImageCache', false, true); + } + this.resetEditArea(); + }, + + appendContents : function (contents) { + var div = this.doc.createElement('div'); + this.editAreaFocus(); + div.innerHTML = String(this.trimSpace(contents)); + + while (div.hasChildNodes()) { + this.doc.body.appendChild(div.firstChild); + } + this.editAreaFocus(); + }, + + insertContents : function (contents) { + this.editAreaFocus(); + this.doCmdPaste(String(this.trimSpace(contents))); + }, + + replaceContents : function (contents) { + this.editAreaFocus(); + this.doc.body.innerHTML = ''; + this.loadContents(contents); + this.editAreaFocus(); + }, + + loadContents : function (contents) { + if (typeof contents === 'string') { + contents = this.trimSpace(contents); + if (contents) { + this.cheditor.editArea.style.visibility = 'hidden'; + this.doc.body.innerHTML = contents; + this.cheditor.editArea.style.visibility = 'visible'; + } + } + }, + + setFolderPath : function () { + if (this.config.editorPath.charAt(this.config.editorPath.length - 1) !== '/') { + this.config.editorPath += '/'; + } + this.config.iconPath = this.config.editorPath + 'icons/'; + this.config.cssPath = this.config.editorPath + 'css/'; + this.config.popupPath = this.config.editorPath + 'popup/'; + }, + + checkInputForm : function () { + var textarea = document.getElementById(this.inputForm); + if (!textarea) { + throw 'ID가 "' + this.inputForm + '"인 textarea 개체를 찾을 수 없습니다.'; + } + textarea.style.display = 'none'; + this.cheditor.textarea = textarea; + }, + + setDesignMode : function (designMode, doc) { + var mode = designMode ? 'on' : 'off'; + + doc = doc || this.doc; + if (GB.browser.msie) { + if (doc.body.contentEditable !== designMode) { + doc.body.contentEditable = designMode; + } + return; + } + if (doc.designMode !== mode) { + doc.designMode = mode; + } + }, + + openDoc : function (doc, contents) { + var html = '' + + '' + this.config.docTitle + '' + + ''; + + doc.open(); + + if (typeof contents === 'string') { + html += this.trimSpace(contents); + } + + html += ''; + doc.write(html); + doc.close(); + }, + + getWindowHandle : function (iframeObj) { + var iframeWin; + if (iframeObj.contentWindow) { + iframeWin = iframeObj.contentWindow; + } else { + throw '현재 브라우저에서 에디터를 실행할 수 없습니다.'; + } + return iframeWin; + }, + + resetDoc : function () { + if (this.undefined(this.cheditor.editArea)) { + return false; + } + try { + this.editArea = this.getWindowHandle(this.cheditor.editArea); + this.doc = GB.browser.msie ? this.editArea.document : this.cheditor.editArea.contentDocument; + this.resetData(); + return true; + } catch (e) { + alert(e.toString()); + return false; + } + }, + + resetEditArea : function () { + this.openDoc(this.doc, this.cheditor.textarea.value); + this.setDocumentProp(); + }, + + resetDocumentBody : function () { + this.doc.body.parentNode.replaceChild(this.doc.createElement('body'), this.doc.body); + this.setDocumentBodyProp(); + }, + + setDocumentBodyProp : function () { + this.doc.body.setAttribute('spellcheck', 'false'); + this.doc.body.setAttribute('hidefocus', ''); + }, + + setDocumentProp : function () { + var oSheet, + bodyCss = 'font-size:' + this.config.editorFontSize + + '; font-family:' + this.config.editorFontName + + '; color:' + this.config.editorFontColor + + '; margin:' + this.config.editAreaMargin + + '; line-height:' + this.config.lineHeight, + tableCss = 'font-size:' + this.config.editorFontSize + '; line-height:' + this.config.lineHeight, + self = this; + + this.setDefaultCss({css: 'editarea.css', doc: this.doc}); + + oSheet = this.doc.styleSheets[0]; + if (!this.W3CRange) { + oSheet.addRule('body', bodyCss); + oSheet.addRule('table', tableCss); + } else { + oSheet.insertRule('body {' + bodyCss + '}', 0); + oSheet.insertRule('table {' + tableCss + '}', 1); + } + + this.setDocumentBodyProp(); + this.cheditor.bogusSpacerName = 'ch_bogus_spacer'; + + this.addEvent(this.doc, 'paste', function (event) { + self.handlePaste(event); + }); + + if (!GB.browser.msie) { + this.doc.execCommand('defaultParagraphSeparator', false, 'p'); + } + + this.setDesignMode(true); + this.initDefaultParagraphSeparator(); + }, + + initDefaultParagraphSeparator : function () { + var p = this.doc.createElement('p'), br; + + if (this.doc.body.firstChild && this.doc.body.firstChild.nodeName.toLowerCase() === 'br') { + this.doc.body.removeChild(this.doc.body.firstChild); + } + + if (this.W3CRange) { + if (!this.doc.body.hasChildNodes()) { + this.doc.body.appendChild(p); + if (!GB.browser.msie && !GB.browser.edge) { + br = this.doc.createElement('br'); + br.className = this.cheditor.bogusSpacerName; + p.appendChild(br); + this.placeCaretAt(p, false); + } else { + this.placeCaretAt(p, false); + } + } + } else { + this.doc.body.appendChild(p); + this.placeCaretAt(p, false); + } + }, + + handleBeforePaste : function () { + var range = this.getRange(), commonAncestorContainer, startOffset, wrapper; + this.backupRange(); + + if (!range.collapsed) { + range.deleteContents(); + range = this.getRange(); + } + + commonAncestorContainer = range.commonAncestorContainer; + startOffset = range.startOffset; + wrapper = this.doc.createElement('div'); + + if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) { + commonAncestorContainer.parentNode.insertBefore(wrapper, commonAncestorContainer); + } else { + range.insertNode(wrapper); + } + + this.placeCaretAt(wrapper, false); + return wrapper; + }, + + handlePaste : function (ev) { + var text, clip, elem, wrapper, pNode, space = [], div, self = this; + if (this.cheditor.mode === 'preview') { + return; + } + if (this.cheditor.paste !== 'text' && this.cheditor.mode === 'rich' && this.W3CRange) { + wrapper = this.handleBeforePaste(); + setTimeout(function () { + if (wrapper) { + if (wrapper.hasChildNodes()) { + text = wrapper.innerHTML; + text = text.replace(/[\r\n]/g, '\u00a0'); + text = text.replace(/]+)>(\s+| +)<\/font>/gi, '\u00a0'); + text = text.replace(/]+)>(\s+| +)<\/span>/gi, '\u00a0'); + text = text.replace(/<\/?(font)\s?([^>]+)?>/gi, ''); + text = text.replace(/([\s ]+)<\/strong>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/b>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/em>/gi, '\u00a0'); + text = text.replace(/([\s ]+)<\/i>/gi, '\u00a0'); + text = text.replace(/<\/?(colgroup|col\s?([^>]+))>/gi, ''); + text = text.replace(/<(\/)?strong>/gi, '<$1b>'); + text = text.replace(/<(\/)?em>/gi, '<$1i>'); + + wrapper.innerHTML = text; + if (wrapper.firstChild.nodeType === GB.node.text) { + text = wrapper.firstChild.data; + text = text.replace(/^( +|\s+)/g, ''); + wrapper.firstChild.data = text; + } + + elem = wrapper.firstChild; + while (elem) { + wrapper.parentNode.insertBefore(elem, wrapper); + elem = wrapper.firstChild; + } + } + + pNode = wrapper.parentNode; + if (pNode) { + if (pNode.firstChild === wrapper && pNode.lastChild === wrapper) { + pNode.parentNode.removeChild(pNode); + } else { + pNode.removeChild(wrapper); + } + } + self.setImageEvent(true); + } + }, 50); + return; + } + + if (ev !== null) { + clip = ev.clipboardData; + this.stopEvent(ev); + } + + text = this.trimSpace((this.undefined(clip) || clip === null) ? + window.clipboardData.getData('Text') : + clip.getData('text/plain')); + + if (text !== '') { + text = text.replace(/\r/g, ''); + if (this.cheditor.mode === 'code') { + div = this.doc.createElement('div'); + text = this.htmlEncode(text); + text = text.replace(/\s{2,}/gm, '\n'); + text = text.replace(/[\u200b\ufeff\xa0\u3000]+/g, ''); + + if (GB.browser.msie && GB.browser.version < 9) { + text = text.replace(/\n/g, '
    '); + text = text.replace(/\t/g, '__CHEDITOR_TAB_SPACE__'); + text = text.replace(/\s/gm, ' '); + } + div.innerHTML = text; + div.id = 'clipboardData'; + this.insertHTML(div); + return; + } + + text = this.htmlEncode(text); + text = text.replace(/[\r\n]+/g, '\n'); + text = text.split('\n').join('
    '); + + text = text.replace(/(\s{2,})/g, function (a, b) { + space = b.split(/\s/); + space.shift(); + return ' ' + space.join(' '); + }); + this.insertHTML(text); + self.setImageEvent(true); + } + }, + + editAreaFocus : function () { + this.editArea.focus(); + }, + + resizeGetY : function (evt) { + return GB.browser.msie ? + window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop : + evt.clientY + window.pageYOffset; + }, + + resizeStart : function (evt) { + var self = this; + self.currentRS.elNode = self.cheditor.mode === 'code' ? self.cheditor.textContent : self.cheditor.editArea; + self.currentRS.cursorStartY = self.resizeGetY(evt); + self.currentRS.elStartTop = parseInt(self.currentRS.elNode.style.height, 10); + + if (isNaN(self.currentRS.elStartTop)) { + self.currentRS.elStartTop = 0; + } + + evt = evt || window.event; + + self.resizeEditor.stopFunc = function (event) { + self.resizeStop(event); + }; + self.resizeEditor.moveFunc = function (event) { + self.resizeMove(event); + }; + + if (GB.browser.msie) { + self.setDesignMode(false); + } + + self.currentRS.elNode.style.visibility = 'hidden'; + self.addEvent(document, 'mousemove', self.resizeEditor.moveFunc); + self.addEvent(document, 'mouseup', self.resizeEditor.stopFunc); + self.stopEvent(evt); + }, + + resizeMove : function (evt) { + var offset = this.resizeGetY(evt), + height = this.currentRS.elStartTop + offset - this.currentRS.cursorStartY; + if (height < 1) { + this.resizeStop(evt); + height = 1; + } + this.config.editorHeight = this.currentRS.elNode.style.height = height + 'px'; + this.stopEvent(evt); + }, + + resizeStop : function (evt) { + this.stopEvent(evt); + this.removeEvent(document, 'mouseup', this.resizeEditor.stopFunc); + this.removeEvent(document, 'mousemove', this.resizeEditor.moveFunc); + this.currentRS.elNode.style.visibility = 'visible'; + if (GB.browser.msie) { + this.setDesignMode(true); + } + if (this.cheditor.mode === 'code') { + this.config.editorHeight = (parseInt(this.config.editorHeight, 10) + + parseInt(this.cheditor.textContent.getAttribute('xbar-height'), 10)) + 'px'; + this.cheditor.textContent.focus(); + } else if (this.cheditor.mode === 'rich') { + this.editAreaFocus(); + } + }, + + switchEditorMode : function (changeMode) { + var self = this, i, className, interval; + + this.editAreaFocus(); + if (this.cheditor.mode === changeMode) { + return; + } + + for (i in this.cheditor.modetab) { + if (this.cheditor.modetab.hasOwnProperty(i)) { + className = this.cheditor.modetab[i].className; + className = className.replace(/\-off$/, ''); + if (i !== changeMode) { + this.cheditor.modetab[i].className = className + '-off'; + } else { + this.cheditor.modetab[i].className = className; + } + } + } + + switch (changeMode) { + case 'rich' : + this.richMode(); + this.showTagSelector(true); + break; + case 'code' : + if (this.cheditor.modifyState) { + interval = setInterval(function () { + if (!self.cheditor.modifyState) { + clearInterval(interval); + self.editMode(); + } + }, 10); + } else { + this.editMode(); + } + this.showTagSelector(false); + break; + case 'preview' : + this.previewMode(); + this.showTagSelector(false); + } + this.cheditor.mode = changeMode; + }, + + initTemplate : function () { + var self = this, + httpRequest = null, + showError = function (msg) { + alert(self.templateFile + ' 파일 로딩 중 오류가 발생하였습니다.\n원인: ' + msg); + }, + templateReady = function () { + var event; + if (httpRequest.readyState === 4) { + if (httpRequest.status === 200) { + try { + self.xmlDoc = httpRequest.responseXML || httpRequest; + self.loadTemplate(self.xmlDoc); + if (self.W3CRange) { + event = document.createEvent('Event'); + event.initEvent(self.cheditor.id, true, true); + document.dispatchEvent(event); + } else { + document.documentElement.loadEvent = self.cheditor.id; + } + } catch (e) { + showError(e.toString()); + } + } else { + showError('XMLHttpRequest. Status ' + httpRequest.status); + } + } + }; + + if (window.XMLHttpRequest) { + httpRequest = new XMLHttpRequest(); + if (httpRequest.overrideMimeType) { + httpRequest.overrideMimeType('text/xml'); + } + httpRequest.onreadystatechange = templateReady; + try { + httpRequest.open('GET', self.templatePath, true); + } + catch (e) { + showError(e + '참고: 에디터를 웹 서버에서 실행하여 주십시오.'); + } + httpRequest.send(); + } else if (window.ActiveXObject) { + httpRequest = new window.ActiveXObject('Microsoft.XMLDOM'); + httpRequest.async = true; + httpRequest.onreadystatechange = templateReady; + httpRequest.load(self.templatePath); + } else { + showError('현재 브라우저에서 ' + self.templateFile + ' 파일을 사용할 수 없습니다.'); + } + }, + + getCDATASection : function (node) { + var elem, data; + if (node.hasChildNodes()) { + elem = node.firstChild; + while (elem && elem.nodeType !== GB.node.cdata_section) { + elem = elem.nextSibling; + } + if (elem && elem.nodeType === GB.node.cdata_section) { + data = elem.data; + data = data.replace(/\n/g, ''); + data = data.replace(/(\s+?)<([^>]*)>/g, '<$2>'); + data = this.trimSpace(data); + return data; + } + } + return null; + }, + + setToolbarBgPosition : function (elem, attr) { + elem.style.backgroundPosition = attr; + }, + + getToolbarBgPosition : function (elem) { + var pos; + switch (elem.className) { + case 'cheditor-tb-bg' : pos = 3; break; + case 'cheditor-tb-bg-last' : pos = 6; break; + case 'cheditor-tb-bg-single' : pos = 9; break; + case 'cheditor-tb-bg30-first' : pos = 12; break; + case 'cheditor-tb-bg30' : pos = 15; break; + case 'cheditor-tb-bg30-last' : pos = 18; break; + case 'cheditor-tb-bg55' : pos = 21; break; + case 'cheditor-tb-bg40' : pos = 24; break; + case 'cheditor-tb-bg44' : pos = 27; break; + case 'cheditor-tb-bgcombo' : pos = 30; break; + case 'cheditor-tb-bgcombo-last' : pos = 33; break; + default : pos = 0; + } + return pos; + }, + + toolbarMouseOverUp : function (elem) { + var pos, obj; + if (elem.checked) { + return; + } + this.setToolbarBgPosition(elem.button, '0 ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px'); + + if ((elem.name === 'combobox' && elem.prev && elem.prev.checked) || + (elem.name === 'combo' && elem.next && elem.next.checked)) { + return; + } + if (elem.type === 'combobox') { + if (elem.prev.checked) { + return; + } + obj = elem.prev; + pos = '0px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } else if (elem.type === 'combo') { + if (elem.prev && !elem.prev.checked && !elem.prev.active) { + obj = elem.prev; + pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } + if (elem.next) { + if (elem.next.checked) { + return; + } + obj = elem.next; + pos = (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'; + this.setToolbarBgPosition(obj.button, pos); + } + } else { + if (!elem.prev || (elem.prev && elem.prev.checked)) { + return; + } + obj = elem.prev; + if (obj.className === 'cheditor-tb-bg-first') { + pos = (~(obj.width) + 1) + 'px 0'; + } else { + pos = (~(obj.width) + 1) + 'px ' + (~(obj.pos * obj.height) + 1) + 'px'; + } + this.setToolbarBgPosition(obj.button, pos); + } + }, + + toolbarMouseDownOut : function (elem, mousedown) { + if (elem.next && elem.next.checked && !mousedown) { + this.setToolbarBgPosition(elem.button, (~(elem.width * 2) + 1) + 'px ' + + (~(elem.pos * elem.height) + 1) + 'px'); + } + if (elem.prev) { + if (elem.prev.active || (elem.prev.type === 'combo' && elem.checked)) { + return; + } + if (elem.prev.checked) { + this.setToolbarBgPosition(elem.prev.button, '0 ' + + (~((elem.prev.pos + 2) * elem.prev.height) + 1) + 'px'); + return; + } + if (mousedown) { + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } else { + this.setToolbarBgPosition(elem.prev.button, + '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + } + }, + + toolbarButtonChecked : function (elem) { + this.setToolbarBgPosition(elem.button, '0 ' + (~((elem.pos + 2) * elem.height) + 1) + 'px'); + if (elem.prev && elem.prev.type === 'combo') { + if (elem.prev.checked || elem.checked) { + return; + } + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + if (elem.prev && !elem.prev.checked) { + if (elem.checked) { + this.setToolbarBgPosition(elem.prev.button, (~(elem.prev.width * 2) + 1) + 'px ' + + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } else { + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + } + }, + + toolbarButtonUnchecked : function (elem) { + if (elem.type === 'combobox' && !elem.checked) { + if (elem.prev.checked) { + this.setToolbarBgPosition(elem.button, + (~(elem.width) + 1) + 'px ' + (~(((elem.pos + 1) * elem.height)) + 1) + 'px'); + return; + } + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + this.setToolbarBgPosition(elem.button, '0 ' + (~(elem.pos * elem.height) + 1) + 'px'); + if (elem.prev && elem.prev.name === 'BackColor') { + this.setToolbarBgPosition(elem.prev.button, '0 ' + (~(elem.prev.pos * elem.prev.height) + 1) + 'px'); + } + }, + + makeToolbarGrayscale : function (image) { + var context, imageData, filter, imgWidth = image.width, imgHeight = image.height, + canvas = this.doc.createElement('canvas'); + + filter = function (pixels) { + var d = pixels.data, i, r, g, b; + for (i = 0; i < d.length; i += 4) { + r = d[i]; + g = d[i + 1]; + b = d[i + 2]; + d[i] = d[i + 1] = d[i + 2] = (r + g + b) / 3; + } + return pixels; + }; + + context = canvas.getContext('2d'); + canvas.width = imgWidth; + canvas.height = imgHeight; + context.drawImage(image, 0, 0); + + imageData = context.getImageData(0, 0, imgWidth, imgHeight); + filter(imageData); + context.putImageData(imageData, 0, 0); + return canvas.toDataURL(); + }, + + toolbarSetBackgroundImage : function (elem, disable) { + var css = elem.firstChild.className, + tbEnable = (this.cheditor.toolbarGrayscale && elem.firstChild.style.backgroundImage); + + css = css.replace(/-disable$/i, ''); + if (disable) { + if (tbEnable) { + elem.firstChild.style.backgroundImage = 'url(' + this.cheditor.toolbarGrayscale + ')'; + } + css = css + '-disable'; + elem.style.cursor = 'default'; + } else { + if (tbEnable) { + elem.firstChild.style.backgroundImage = 'url(' + this.toolbar.icon + ')'; + } + elem.style.cursor = 'pointer'; + } + elem.firstChild.className = css; + }, + + toolbarDisable : function (elem, disable) { + if (disable) { + this.toolbarSetBackgroundImage(elem.button, true); + this.toolbarButtonUnchecked(elem); + this.toolbarMouseDownOut(elem); + this.toolbar[elem.name].disabled = true; + return true; + } + this.toolbarSetBackgroundImage(elem.button, false); + this.toolbar[elem.name].disabled = false; + return false; + }, + + colorConvert : function (color, which, opacity) { + var colorDefs = [ + { + re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, + process : function (bits) { + return [ + parseInt(bits[1], 10), + parseInt(bits[2], 10), + parseInt(bits[3], 10), + 1 + ]; + } + }, + { + re : /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d+(?:\.\d+)?|\.\d+)\s*\)/, + process : function (bits) { + return [ + parseInt(bits[1], 10), + parseInt(bits[2], 10), + parseInt(bits[3], 10), + parseFloat(bits[4]) + ]; + } + }, + { + re: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, + process : function (bits) { + return [ + parseInt(bits[1], 16), + parseInt(bits[2], 16), + parseInt(bits[3], 16), + 1 + ]; + } + }, + { + re: /^([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/, + process : function (bits) { + return [ + parseInt(bits[1] * 2, 16), + parseInt(bits[2] * 2, 16), + parseInt(bits[3] * 2, 16), + 1 + ]; + } + } + ], r = null, g = null, b = null, a = null, i, re, processor, bits, channels, min, rData = null; + + if (!which) { + which = 'rgba'; + } + + color = color.replace(/^\s*#|\s*$/g, ''); + if (color.length === 3) { + color = color.replace(/(.)/g, '$1$1'); + } + + color = color.toLowerCase(); + which = which.toLowerCase(); + + for (i = 0; i < colorDefs.length; i++) { + re = colorDefs[i].re; + processor = colorDefs[i].process; + bits = re.exec(color); + if (bits) { + channels = processor(bits); + r = channels[0]; + g = channels[1]; + b = channels[2]; + a = channels[3]; + } + } + + r = (r < 0 || isNaN(r)) ? 0 : ((r > 255) ? 255 : r); + g = (g < 0 || isNaN(g)) ? 0 : ((g > 255) ? 255 : g); + b = (b < 0 || isNaN(b)) ? 0 : ((b > 255) ? 255 : b); + a = (a < 0 || isNaN(a)) ? 0 : ((a > 1) ? 1 : a); + + function hex(x) { + return ('0' + parseInt(x, 10).toString(16)).slice(-2); + } + + switch (which) { + case 'rgba': + if (opacity) { + a = (255 - (min = Math.min(r, g, b))) / 255; + r = ((r - min) / a).toFixed(0); + g = ((g - min) / a).toFixed(0); + b = ((b - min) / a).toFixed(0); + a = a.toFixed(4); + } + rData = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')'; + break; + case 'rgb': + rData = 'rgb(' + r + ',' + g + ',' + b + ')'; + break; + case 'hex': + if (isNaN(parseInt(r, 10)) || isNaN(parseInt(g, 10)) || isNaN(parseInt(b, 10))) { + return color; + } + rData = '#' + hex(r) + hex(g) + hex(b); + break; + } + return rData; + }, + + toolbarUpdate : function (srcElement) { + var toolbar = this.toolbar, + range = this.getRange(), + isCollapsed = this.rangeCollapsed(range), + sType = GB.selection.text, + bControl = false, bTable = false, ancestorsLen = 0, bNoOff = { 'Link': 1 }, ancestors = [], + i, j, btn, cmd, autoOff, bDisable, el, wrapper, fontAttr, oldName, span, newAttr, defaultAttr, + state, css, node, alignment, pNode; + + pNode = srcElement || this.getRangeElement(range); + switch (pNode.nodeType) { + case GB.node.element: + sType = GB.selection.element; + break; + case GB.node.text: + sType = GB.selection.text; + pNode = pNode.parentNode; + break; + default: + return; + } + + if (sType === GB.selection.element && !isCollapsed) { + bControl = GB.offElementTags[pNode.nodeName.toLowerCase()]; + } else { + node = pNode; + while (node && node.nodeType === GB.node.element && node.nodeName.toLowerCase() !== 'body') { + ancestors.push(node); + if (node.nodeName.toLowerCase() === 'td' || node.nodeName.toLowerCase() === 'th') { + bTable = true; + } + node = node.parentNode; + } + ancestorsLen = ancestors.length; + } + + if (!bTable && sType === GB.selection.element && + (pNode.nodeName.toLowerCase() === 'table' || pNode.nodeName.toLowerCase() === 'td' || + pNode.nodeName.toLowerCase() === 'th')) { + bTable = true; + } + + alignment = { JustifyCenter : 'center', JustifyRight : 'right', JustifyFull : 'justify' }; + + for (i in toolbar) { + if (!toolbar.hasOwnProperty(i)) { + continue; + } + + btn = toolbar[i]; + if (!btn.cmd) { + continue; + } + + cmd = btn.cmd; + autoOff = false; + + if (bControl && sType === GB.selection.element) { + if (btn.group !== 'Alignment') { + autoOff = !(pNode.nodeName.toLowerCase() === 'img' && bNoOff[cmd]); + } + } + + if (btn.name === 'ModifyTable') { + autoOff = !bTable; + } + + bDisable = this.toolbarDisable(btn, autoOff); + + if (btn.name === 'ForeColor' || btn.name === 'BackColor') { + btn.button.lastChild.style.display = bDisable ? 'none' : 'block'; + } + if (btn.autocheck === null) { + continue; + } + + switch (cmd) { + case 'Copy' : + case 'Cut' : + this.toolbarDisable(btn, isCollapsed); + break; + case 'UnLink' : + if (GB.browser.firefox) { + this.toolbarDisable(btn, (pNode.nodeName.toLowerCase() !== 'a' && !pNode.getAttribute('href'))); + } else { + this.toolbarDisable(btn, this.doc.queryCommandEnabled(cmd) === false); + } + break; + case 'FormatBlock' : + wrapper = btn.button.firstChild; + oldName = wrapper.firstChild; + el = false; + span = document.createElement('span'); + for (j = 0; j < ancestorsLen; j++) { + if (GB.formatBlock[ancestors[j].nodeName]) { + span.appendChild(document.createTextNode(ancestors[j].nodeName)); + wrapper.replaceChild(span, oldName); + el = true; + break; + } + } + if (!el) { + span.appendChild(document.createTextNode('스타일')); + wrapper.replaceChild(span, oldName); + } + this.unselectionElement(span); + break; + case 'ForeColor' : + case 'BackColor' : + if (cmd === 'BackColor' && !GB.browser.msie) { + cmd = 'HiliteColor'; + } + fontAttr = this.doc.queryCommandValue(cmd); + if (fontAttr && !/^[rgb|#]/.test(fontAttr)) { + fontAttr = (((fontAttr & 0x0000ff) << 16) | (fontAttr & 0x00ff00) | ((fontAttr & 0xff0000) >>> 16)).toString(16); + fontAttr = '#000000'.slice(0, 7 - fontAttr.length) + fontAttr; + } else { + fontAttr = (cmd === 'ForeColor') ? this.config.editorFontColor : this.config.editorBgColor; + } + btn.button.lastChild.style.backgroundColor = fontAttr; + break; + case 'FontName' : + case 'FontSize' : + fontAttr = this.doc.queryCommandValue(cmd); + wrapper = btn.button.firstChild; + span = this.doc.createElement('span'); + + if (cmd === 'FontSize') { + fontAttr = pNode.style.fontSize; + if (!fontAttr) { + for (i = 0; i < ancestors.length; i++) { + fontAttr = ancestors[i].style.fontSize; + if (fontAttr) { + break; + } + } + } + } + if (fontAttr) { + newAttr = fontAttr; + newAttr = newAttr.replace(/'/g, ''); + span.appendChild(this.doc.createTextNode(newAttr)); + wrapper.replaceChild(span, wrapper.firstChild); + } + if (!span.hasChildNodes()) { + defaultAttr = (cmd === 'FontSize') ? this.config.editorFontSize : this.config.editorFontName; + if (wrapper.hasChildNodes()) { + wrapper.removeChild(wrapper.firstChild); + } + defaultAttr = defaultAttr.replace(/'/g, ''); + span.appendChild(this.doc.createTextNode(defaultAttr)); + wrapper.appendChild(span); + } + this.unselectionElement(span); + break; + case 'LineHeight': + wrapper = btn.button.firstChild; + this.unselectionElement(wrapper.firstChild); + break; + default : + if (!this.doc.queryCommandSupported(cmd)) { + continue; + } + state = this.doc.queryCommandState(cmd); + if (state === null) { + continue; + } + + if (GB.browser.msie && state === false && alignment[cmd]) { + el = pNode; + while (el && el.nodeName.toLowerCase() !== 'body') { + if (GB.lineHeightBlockTags[el.nodeName.toLowerCase()]) { + css = this.getCssValue(el); + if (css) { + for (j = 0; j < css.length; j++) { + if (css[j].name.toLowerCase() === 'text-align' && css[j].value === alignment[cmd]) { + state = true; + break; + } + } + } + } + el = el.parentNode; + } + } + + if (state) { + btn.checked = true; + this.toolbarButtonChecked(btn); + if (btn.type === 'combo' && btn.name === btn.next.node) { + btn.next.active = true; + this.setToolbarBgPosition(btn.next.button, + (~(btn.next.width) + 1) + 'px ' + (~(((btn.next.pos + 1) * btn.next.height)) + 1) + 'px'); + } + } else { + this.toolbarButtonUnchecked(btn); + btn.checked = false; + if (btn.next) { + btn.next.active = false; + if (btn.type === 'combo' && btn.name === btn.next.node) { + this.toolbarButtonUnchecked(btn.next); + } + } + } + + } + } + }, + + createButton : function (name, attr, prev) { + var self = this, + elem, icon, btnIcon, iconPos, method, cmd, check, type, node, btnHeight, btnWidth, text, + span, obj, btnClass, comboOut; + + method = attr.getElementsByTagName('Execution')[0].getAttribute('method'); + cmd = attr.getElementsByTagName('Execution')[0].getAttribute('value'); + check = attr.getAttribute('check'); + type = attr.getAttribute('type'); + node = attr.getAttribute('node'); + + btnClass = attr.getAttribute('class'); + btnWidth = attr.getAttribute('width'); + btnHeight = attr.getAttribute('height'); + + elem = document.createElement('div'); + elem.style.width = btnWidth + 'px'; + elem.setAttribute('name', name); + elem.style.height = btnHeight + 'px'; + elem.style.border = '0px solid transparent'; + + icon = attr.getElementsByTagName('Icon')[0]; + btnIcon = document.createElement('div'); + btnIcon.className = icon.getAttribute('class'); + btnIcon.style.marginLeft = icon.getAttribute('margin') || '3px'; + + iconPos = icon.getAttribute('position'); + if (iconPos) { + btnIcon.style.backgroundImage = 'url(' + self.toolbar.icon + ')'; + btnIcon.style.backgroundRepeat = 'no-repeat'; + self.setToolbarBgPosition(btnIcon, (~iconPos + 1) + 'px center'); + } else { + text = icon.getAttribute('alt'); + if (text) { + span = document.createElement('span'); + span.appendChild(document.createTextNode(text)); + btnIcon.appendChild(span); + } + } + + elem.appendChild(btnIcon); + obj = { 'autocheck': check, + 'button': elem, + 'className': btnClass, + 'checked': false, + 'cmd': cmd, + 'colorNode': {}, + 'disabled': false, + 'group': '', + 'height': btnHeight, + 'method': method, + 'name': name, + 'next': null, + 'node': node, + 'num': 0, + 'pos': 0, + 'prev': prev, + 'type': type, + 'width': btnWidth }; + + if (prev) { + prev.next = obj; + } + + elem.attr = obj; + self.toolbar[name] = obj; + + self.addEvent(elem, 'mouseover', function (ev) { + if (!obj.disabled) { + self.toolbarMouseOverUp(obj); + } + self.stopEvent(ev || window.event); + }); + + self.addEvent(elem, 'mousedown', function (ev) { + if (!obj.checked && !obj.disabled) { + self.toolbarButtonChecked(obj); + self.toolbarMouseDownOut(obj, true); + if (obj.prev && obj.prev.type === 'combo' && !obj.prev.checked) { + self.setToolbarBgPosition(obj.prev.button, + '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px'); + } + } + if (obj.next) { + obj.next.button.style.visibility = 'hidden'; + obj.next.button.style.visibility = 'visible'; + } + self.stopEvent(ev || window.event); + }); + + self.addEvent(elem, 'click', function (ev) { + if (obj.disabled) { + return; + } + switch (obj.method) { + case 'doCmd' : + self.backupRange(); + self.doCmd(obj.cmd, null); + break; + case 'windowOpen' : + self.windowOpen(obj.cmd); + break; + case 'showPulldown' : + if (obj.checked) { + obj.checked = false; + self.boxHideAll(); + self.toolbarButtonUnchecked(obj); + return; + } + obj.checked = true; + self.showPulldown(obj.cmd, obj.button); + self.toolbarButtonChecked(obj); + self.toolbarMouseDownOut(obj, true); + break; + default : + alert('지원하지 않는 명령입니다.'); + } + self.stopEvent(ev || window.event); + }); + + comboOut = function (combo, startPos) { + self.setToolbarBgPosition(combo.button, + startPos + 'px ' + (~(((self.getToolbarBgPosition(combo.button) + (combo.checked ? 2 : 1)) * combo.height)) + 1) + 'px'); + }; + + self.addEvent(elem, 'mouseout', function () { + if (!obj.checked) { + if (obj.type === 'combo') { + if (obj.next) { + if (!obj.next.checked) { + self.toolbarButtonUnchecked(obj.next); + self.toolbarMouseDownOut(obj.next, false); + } else { + return; + } + } + } + if (obj.type === 'combobox' && obj.prev.checked) { + self.setToolbarBgPosition(obj.button, + (~(obj.width) + 1) + 'px ' + (~(((obj.pos + 1) * obj.height)) + 1) + 'px'); + return; + } + self.toolbarButtonUnchecked(obj); + self.toolbarMouseDownOut(obj, false); + } else { + if (obj.node && obj.node === obj.prev.name) { + if (!obj.prev.checked) { + self.setToolbarBgPosition(obj.prev.button, + '0 ' + (~((self.getToolbarBgPosition(obj.prev.button) + 1) * obj.prev.height) + 1) + 'px'); + } + comboOut(obj, 0); + } + } + }); + + return obj; + }, + + showToolbar : function (toolbar, toolbarWrapper) { + var self = this, + i, j, grpName, btn, btnLen, prevObj, attr, btnName, btnObj = null, btnNum, spacer, + currentColor, fullscreen, child, len, + toolbarIcon = toolbar.getElementsByTagName('Image').item(0).getAttribute('file'), + tmpArr = toolbarIcon.split(/\./), + group = toolbar.getElementsByTagName('Group'), + grpNum = group.length, + appendSpaceBlock = function (pNode) { + var split = document.createElement('div'); + split.className = 'cheditor-tb-split'; + pNode.appendChild(split); + }, + onClickEventHandler = function () { + if (self.setFullScreenMode) { + this.className = 'cheditor-tb-fullscreen'; + this.setAttribute('title', '전체 화면'); + } else { + this.className = 'cheditor-tb-fullscreen-actual'; + this.setAttribute('title', '이전 크기로 복원'); + } + self.fullScreenMode(); + }; + + self.toolbar.icon = self.config.iconPath + toolbarIcon; + self.toolbar.iconDisable = self.config.iconPath + tmpArr[0] + '-disable' + '.' + tmpArr[1]; + toolbarWrapper.className = 'cheditor-tb-wrapper'; + + fullscreen = document.createElement('span'); + if (self.config.useFullScreen === true) { + fullscreen.appendChild(document.createTextNode('\u00a0')); + fullscreen.className = 'cheditor-tb-fullscreen'; + fullscreen.setAttribute('title', '전체 화면'); + (function () { + fullscreen.onclick = onClickEventHandler; + })(); + } else { + fullscreen.clsaaName = 'cheditor-tb-fullscreen-disable'; + } + toolbarWrapper.appendChild(fullscreen); + + for (i = 0; i < grpNum; i++) { + grpName = group[i].getAttribute('name'); + if (grpName === 'Split') { + appendSpaceBlock(toolbarWrapper); + continue; + } + + btn = group[i].getElementsByTagName('Button'); + btnLen = btn.length; + btnNum = 0; btnObj = null; + + for (j = 0; j < btnLen; j++) { + attr = btn[j].getElementsByTagName('Attribute')[0]; + btnName = btn[j].getAttribute('name'); + if (!attr.getAttribute('node') && self.config['use' + btnName] !== true) { + continue; + } + if (attr.getAttribute('type') === 'combobox' && self.config['use' + attr.getAttribute('node')] !== true) { + continue; + } + + btnObj = self.createButton(btnName, attr, btnObj); + self.toolbar[btnObj.name].num = btnNum++; + self.toolbar[btnObj.name].group = grpName; + + if (btn[j].getAttribute('tooltip') !== null) { + btnObj.button.setAttribute('title', btn[j].getAttribute('tooltip')); + } + + if (btnObj.name === 'ForeColor' || btnObj.name === 'BackColor') { + currentColor = document.createElement('div'); + currentColor.className = 'cheditor-tb-color-btn'; + currentColor.style.backgroundColor = attr.getAttribute('default'); + btnObj.button.appendChild(currentColor); + } + toolbarWrapper.appendChild(btnObj.button); + } + + if (btnObj === null) { + continue; + } + + prevObj = btnObj.prev; + + if (!prevObj) { + btnObj.button.className = btnObj.className; + if (btnObj.className === 'cheditor-tb-bg') { + btnObj.className = btnObj.className + '-single'; + btnObj.button.className = btnObj.className; + } + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + } else { + btnObj.className = btnObj.className + '-last'; + btnObj.button.className = btnObj.className; + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + while (prevObj) { + prevObj.button.className = prevObj.className; + prevObj.pos = self.getToolbarBgPosition(prevObj.button); + btnObj = prevObj; + prevObj = prevObj.prev; + } + btnObj.className = btnObj.className + '-first'; + btnObj.button.className = btnObj.className; + btnObj.pos = self.getToolbarBgPosition(btnObj.button); + } + spacer = document.createElement('div'); + spacer.className = 'cheditor-tb-button-spacer'; + toolbarWrapper.appendChild(spacer); + } + + appendSpaceBlock(toolbarWrapper); + + if (GB.browser.msie) { + child = toolbarWrapper.getElementsByTagName('div'); + len = child.length; + for (i = 0; i < len; i++) { + self.unselectionElement(child[i]); + } + self.unselectionElement(toolbarWrapper); + } else { + self.unselectionElement(toolbarWrapper); + } + }, + + unselectionElement : function (elem) { + if (!elem || elem.nodeType !== GB.node.element) { + return; + } + if (GB.browser.msie) { + elem.setAttribute('unselectable', 'on'); + elem.setAttribute('contentEditable', 'false'); + } else { + elem.onselectstart = new Function('return false'); + } + }, + + createEditorElement : function (container, toolbar) { + var child = container.firstChild, + self = this, + i, id, tab, tabId, editArea, done = false, frameEl = false, tryScroll, textContent, node, + + onClickEventHandler = function () { + self.switchEditorMode(this.getAttribute('mode')); + }, + onMouseDownEventHandler = function (evt) { + self.resizeStart(evt); + }, + modeOnMouseDownEventHandler = function (evt) { + self.backupRange(); + self.stopEvent(evt); + }, + + pNode = self.cheditor.textarea.parentNode, + nNode = self.cheditor.textarea.nextSibling; + + if (!child) { + return; + } + + do { + id = child.getAttribute('id'); + switch (id) { + case 'toolbar' : + self.showToolbar(toolbar, child); + self.cheditor.toolbarWrapper = child; + break; + case 'viewMode' : + self.cheditor[id] = child; + self.cheditor.mode = 'rich'; + + if (child.hasChildNodes()) { + tab = child.childNodes; + self.cheditor.modetab = {}; + for (i = 0; i < tab.length; i++) { + tabId = tab[i].getAttribute('id'); + if (!tabId) { + continue; + } + if ((tabId === 'code' && self.config.useSource === false) || + (tabId === 'preview' && self.config.usePreview === false)) { + tab[i].style.display = 'none'; + tab[i].removeAttribute('id'); + continue; + } + + tab[i].setAttribute('mode', tabId); + tab[i].onclick = onClickEventHandler; + tab[i].onmousedown = modeOnMouseDownEventHandler; + tab[i].removeAttribute('id'); + self.cheditor.modetab[tabId] = tab[i]; + self.unselectionElement(tab[i]); + } + } + break; + case 'editWrapper' : + node = child.firstChild; + while (node) { + if (node.nodeName.toLowerCase() === 'iframe') { + editArea = node; + } else if (node.nodeName.toLowerCase() === 'textarea') { + textContent = node; + } + node = node.nextSibling; + } + + editArea.style.height = self.config.editorHeight; + editArea.style.backgroundColor = this.config.editorBgColor; + + self.cheditor.editArea = editArea; + self.cheditor.editWrapper = child; + self.cheditor.textContent = textContent; + break; + case 'modifyBlock' : + self.cheditor.editBlock = child; + break; + case 'tagPath' : + if (self.config.showTagPath) { + self.cheditor.tagPath = child.firstChild; + child.style.display = 'block'; + } + break; + case 'resizeBar' : + self.cheditor.resizeBar = child; + child.onmousedown = onMouseDownEventHandler; + self.unselectionElement(child); + break; + default : break; + } + child.removeAttribute('id'); + child = child.nextSibling; + } while (child); + + if (!nNode) { + pNode.appendChild(container); + } else { + pNode.insertBefore(container, nNode); + } + + function ready() { + if (done) { + return; + } + done = true; + } + + if (GB.browser.msie) { + frameEl = window.frameElement !== null; + if (document.documentElement.doScroll && !frameEl) { + tryScroll = function () { + if (done) { + return; + } + try { + document.documentElement.doScroll('left'); + ready(); + } catch (e) { + setTimeout(tryScroll, 10); + } + }; + tryScroll(); + } + self.addEvent(document, 'readystatechange', function () { + if (document.readyState === 'complete') { + ready(); + } + }); + } else { + self.addEvent(document, 'DOMContentLoaded', function () { + ready(); + }); + } + + container.style.width = self.config.editorWidth; + self.cheditor.container = container; + }, + + loadTemplate : function (xmlDoc) { + var self = this, + tmpl = xmlDoc.getElementsByTagName('Template').item(0), + toolbar = tmpl.getElementsByTagName('Toolbar').item(0), + cdata = tmpl.getElementsByTagName('Container').item(0).getElementsByTagName('Html').item(0), + html = self.getCDATASection(cdata), + tmpDiv = document.createElement('div'), + container, popupWindow, modalFrame, dragHandle; + + if (!(tmpl.getElementsByTagName('Image').item(0).getAttribute('file'))) { + throw '툴바 아이콘 이미지 파일 이름이 정의되지 않았습니다.'; + } + + tmpDiv.innerHTML = html; + + container = tmpDiv.firstChild; + self.createEditorElement(container, toolbar); + + cdata = tmpl.getElementsByTagName('PopupWindow').item(0).getElementsByTagName('Html').item(0); + html = self.getCDATASection(cdata); + tmpDiv.innerHTML = html; + + popupWindow = tmpDiv.firstChild; + self.cheditor.popupElem = popupWindow; + + dragHandle = popupWindow.firstChild; + self.cheditor.dragHandle = dragHandle; + self.cheditor.popupTitle = dragHandle.getElementsByTagName('label')[0]; + self.cheditor.popupFrameWrapper = dragHandle.nextSibling; + + container.appendChild(popupWindow); + + modalFrame = document.createElement('div'); + modalFrame.className = 'cheditor-modalPopupTransparent'; + self.cheditor.modalBackground = modalFrame; + self.cheditor.modalBackground.id = 'popupModalBackground'; + self.cheditor.modalBackground.className = 'cheditor-popupModalBackground'; + container.parentNode.insertBefore(modalFrame, container); + + self.cheditor.htmlEditable = document.createElement('iframe'); + self.cheditor.htmlEditable.style.display = 'none'; + self.cheditor.htmlEditable.style.width = '1px'; + self.cheditor.htmlEditable.style.height = '1px'; + self.cheditor.htmlEditable.style.visibility = 'hidden'; + container.appendChild(self.cheditor.htmlEditable); + }, + + imageEvent : function (img, action) { + var self = this, + onMouseUpEventHandler = function () { + self.cheditor.editBlock.style.display = 'block'; + self.modifyImage(this); + }, + onClickEventHandler = function () { + self.cheditor.editBlock.style.display = 'block'; + self.modifyImage(this); + }; + + if (GB.browser.msie) { + if (!action) { + img.onmouseup = null; + return; + } + (function () { + img.onmouseup = onMouseUpEventHandler; + })(); + } else { + if (!action) { + self.removeEvent(img, 'click', onClickEventHandler); + return; + } + this.addEvent(img, 'click', onClickEventHandler); + } + }, + + setImageEvent : function (action) { + var images = this.doc.images, i, + len = images.length; + + for (i = 0; i < len; i++) { + if (/icons\/em\//.test(images[i].src)) { + continue; + } + this.imageEvent(images[i], action); + } + }, + + run : function () { + var self = this, + showEditor = function () { + var grayImage = null; + + if (!self.resetDoc()) { + return; + } + self.editAreaFocus(); + self.setEditorEvent(); + + if (GB.browser.msie && GB.browser.version > 8 || GB.browser.a) { + grayImage = new Image(); + grayImage.onload = function () { + self.cheditor.toolbarGrayscale = self.makeToolbarGrayscale(this); + self.toolbarUpdate(); + }; + grayImage.src = self.toolbar.icon; + grayImage.style.width = '750px'; grayImage.style.height = '16px'; + } else { + self.cheditor.toolbarGrayscale = null; + self.toolbarUpdate(); + } + self.setImageEvent(true); + self.removeEvent(document, self.cheditor.id, showEditor); + }; + + try { + this.setFolderPath(); + this.checkInputForm(); + } + catch (e) { + alert(e.toString()); + return; + } + + self.setDefaultCss({css: 'ui.css', doc: window.document}); + + if (this.W3CRange) { + this.addEvent(document, this.cheditor.id, showEditor); + } else { + document.documentElement.loadEvent = 0; + document.documentElement.attachEvent('onpropertychange', function (evt) { + if (evt.propertyName === 'loadEvent') { + showEditor(); + } + }); + } + + this.initTemplate(); + }, + + fullScreenMode : function () { + var self = this, + container = self.cheditor.container, + windowSize, height, + child = container.firstChild, + except = 0, + editorHeight = parseInt(self.config.editorHeight, 10), + + containerReSize = function () { + windowSize = self.getWindowSize(); + container.style.width = windowSize.width + 'px'; + if (self.cheditor.mode === 'code') { + self.resizeTextContent(); + height = (windowSize.height - except - 6 - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10)); + self.cheditor.textContent.style.height = height + 'px'; + } + self.cheditor.editArea.style.height = (windowSize.height - except - 6) + 'px'; + }, + onMouseDownEventHandler = function (evt) { + self.resizeStart(evt); + }; + + self.editAreaFocus(); + self.boxHideAll(); + self.cheditor.editArea.style.visibility = 'hidden'; + + if (!self.setFullScreenMode) { + container.className = 'cheditor-container-fullscreen'; + + if (GB.browser.msie && GB.browser.version < 7) { + self.cheditor.fullScreenFlag = document.createElement('span'); + self.cheditor.fullScreenFlag.style.display = 'none'; + container.parentNode.insertBefore(self.cheditor.fullScreenFlag, container); + document.body.insertBefore(container, document.body.firstChild); + } + + while (child) { + if (child.className !== 'cheditor-editarea-wrapper' && + child.className !== 'cheditor-popup-window' && + child.className !== '') { + except += child.offsetHeight; + } + child = child.nextSibling; + } + + (function () { + window.onresize = containerReSize; + })(); + + containerReSize(); + self.cheditor.resizeBar.onmousedown = null; + self.cheditor.resizeBar.className = 'cheditor-resizebar-off'; + } else { + window.onresize = null; + container.removeAttribute('style'); + container.className = 'cheditor-container'; + container.style.width = self.config.editorWidth; + + if (self.cheditor.mode === 'code') { + height = editorHeight - parseInt(self.cheditor.textContent.getAttribute('xbar-height'), 10); + self.cheditor.textContent.style.height = height + 'px'; + } else { + self.cheditor.editArea.style.height = editorHeight + 'px'; + } + + (function () { + self.cheditor.resizeBar.onmousedown = onMouseDownEventHandler; + })(); + self.cheditor.resizeBar.className = 'cheditor-resizebar'; + + if (GB.browser.msie && GB.browser.version < 7) { + self.cheditor.fullScreenFlag.parentNode.replaceChild(container, self.cheditor.fullScreenFlag); + } + } + + self.cheditor.editArea.style.visibility = 'visible'; + self.setFullScreenMode = !(self.setFullScreenMode); + self.editAreaFocus(); + }, + + showPulldown : function (cmd, btn) { + switch (cmd) { + case 'FontName' : + this.showFontTypeMenu(btn); + break; + case 'FontSize' : + this.showFontSizeMenu(btn); + break; + case 'FormatBlock' : + this.showFormatBlockMenu(btn); + break; + case 'ForeColor' : + case 'BackColor' : + this.showColorMenu(btn); + break; + case 'TextBlock' : + this.showTextBlockMenu(btn); + break; + case 'LineHeight' : + this.showLineHeightMenu(btn); + break; + case 'OrderedList' : + case 'UnOrderedList' : + this.showOrderedListMenu(btn); + } + }, + + setPulldownClassName : function (labels, pNode) { + var i = 0, label; + for (; i < labels.length; i++) { + label = labels[i]; + if (label.getAttribute('name') === pNode.firstChild.firstChild.firstChild.nodeValue) { + label.parentNode.style.backgroundImage = 'url(' + this.config.editorPath + 'icons/checked.png)'; + label.parentNode.style.backgroundPosition = '0 center'; + label.parentNode.style.backgroundRepeat = 'no-repeat'; + } else { + label.parentNode.style.backgroundImage = ''; + } + label.parentNode.className = 'cheditor-pulldown-mouseout'; + } + }, + + showOrderedListMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var cmd = (menu === 'UnOrderedListCombo') ? 'InsertUnOrderedList' : 'InsertOrderedList', + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup(cmd, this.id, self.toolbar[menu].prev.checked); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }, + list = (cmd === 'InsertUnOrderedList') ? GB.listStyle.unOrdered : GB.listStyle.ordered, + i, div, label, li, ol; + + for (i in list) { + if (list.hasOwnProperty(i)) { + div = document.createElement('div'); + label = document.createElement('label'); + div.id = i; + + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + + self.pulldownMouseOut(div); + + label.style.fontFamily = 'verdana'; + label.style.textAlign = 'center'; + label.style.width = '15px'; + label.setAttribute('name', i); + + li = document.createElement('li'); + li.appendChild(document.createTextNode(list[i])); + + ol = document.createElement('ul'); + ol.style.width = '90px'; + ol.style.padding = '0 15px'; + ol.style.margin = '0px'; + ol.style.listStyleType = i; + ol.style.cursor = 'default'; + ol.style.textAlign = 'left'; + ol.appendChild(li); + label.appendChild(ol); + div.appendChild(label); + outputHtml.appendChild(div); + } + } + self.createWindow(110, outputHtml); + self.createPulldownFrame(outputHtml, menu); + } + })(); + + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showColorMenu : function (pNode) { + var menu = pNode.getAttribute('name'), + elem = this.pulldown[menu], + selectedColor = this.colorConvert(pNode.lastChild.style.backgroundColor, 'hex'), + i, len, nodes, node, outputHtml; + + if (!elem) { + outputHtml = this.setColorTable(menu); + this.createWindow(220, outputHtml); + this.createPulldownFrame(outputHtml, menu); + elem = this.pulldown[menu]; + elem.firstChild.className = 'cheditor-pulldown-color-container'; + } + + this.toolbar[menu].colorNode.selectedValue.style.backgroundColor = selectedColor; + this.toolbar[menu].colorNode.colorPicker.hidePicker(); + this.toolbar[menu].colorNode.colorPicker.fromString(selectedColor); + this.toolbar[menu].colorNode.showPicker = false; + + nodes = elem.getElementsByTagName('span'); + len = nodes.length; + + for (i = 0; i < len; i++) { + node = nodes[i]; + node.style.backgroundImage = ''; + if (node.id && node.id.toLowerCase() === selectedColor.toLowerCase()) { + node.style.backgroundImage = 'url("' + this.config.iconPath + '/color_picker_tick.png")'; + node.style.backgroundRepeat = 'no-repeat'; + node.style.backgroundPosition = 'center center'; + + } + } + this.toolbar[menu].colorNode.selectedValue.style.backgroundImage = 'url("' + + this.config.iconPath + '/color_picker_tick.png")'; + this.toolbar[menu].colorNode.selectedValue.style.backgroundRepeat = 'no-repeat'; + this.toolbar[menu].colorNode.selectedValue.style.backgroundPosition = 'center center'; + this.windowPos(pNode, menu); + this.displayWindow(pNode, menu); + }, + + showFontTypeMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var fonts = null, type, i, div, label, + outputHtml = self.doc.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup(menu, this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (type in GB.fontName) { + if (GB.fontName.hasOwnProperty(type)) { + fonts = GB.fontName[type]; + for (i = 0; i < fonts.length; i++) { + div = self.doc.createElement('div'); + label = self.doc.createElement('label'); + div.id = fonts[i]; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + label.style.fontFamily = fonts[i];//(type !== 'kr') ? fonts[i] : this.config.editorFontName; + label.appendChild(self.doc.createTextNode(fonts[i])); + label.setAttribute('name', fonts[i]); + div.appendChild(label); + outputHtml.appendChild(div); + } + } + } + self.createWindow(155, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showFormatBlockMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var para, label, fontSize, div, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup('FormatBlock', '<' + this.id + '>'); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (para in GB.formatBlock) { + if (GB.formatBlock.hasOwnProperty(para)) { + div = document.createElement('div'); + div.id = para; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + label = document.createElement('label'); + if (para.match(/H[123456]/)) { + fontSize = {'H1': '2em','H2': '1.5em','H3': '1.17em','H4': '1em','H5': '0.83em','H6': '0.75em'}; + label.style.fontWeight = 'bold'; + label.style.fontSize = fontSize[para]; + label.style.lineHeight = 1.4; + } else if (para === 'ADDRESS') { + label.style.fontStyle = 'italic'; + } + + label.appendChild(document.createTextNode(GB.formatBlock[para])); + div.appendChild(label); + label.setAttribute('name', GB.formatBlock[para]); + outputHtml.appendChild(div); + + } + } + self.createWindow(150, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('label'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showFontSizeMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var size, div, label, text, i, + value = GB.fontSize[self.config.fontSizeValue], + len = value.length, + outputHtml = document.createElement('div'), + onClickEventHandler = function (e) { + self.stopEvent(e); + self.doCmdPopup(menu, this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (i = 0; i < len; i++) { + size = value[i]; + div = document.createElement('div'); + label = document.createElement('label'); + text = size > 48 ? '가' : (size > 28 ? '가나다' : '가나다라'); + size = size + self.config.fontSizeValue; + div.id = size; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + div.style.fontSize = size; + label.style.fontFamily = self.config.editorFontName; + label.setAttribute('name', size); + label.appendChild(document.createTextNode(text + '(' + size + ')')); + div.appendChild(label); + outputHtml.appendChild(div); + } + self.createWindow(350, outputHtml); + outputHtml.style.height = '300px'; + outputHtml.style.overflow = 'auto'; + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showLineHeightMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var i, div, label, text, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.doCmdPopup('LineHeight', this.id); + }, + onMouseOverEventHandler = function () { + self.pulldownMouseOver(this); + }, + onMouseOutEventHandler = function () { + self.pulldownMouseOut(this); + }; + + for (i in GB.lineHeight) { + if (!(GB.lineHeight.hasOwnProperty(i))) { + continue; + } + if (!GB.lineHeight[i]) { + break; + } + div = document.createElement('div'); + label = document.createElement('label'); + text = i; + + div.id = GB.lineHeight[i]; + (function () { + div.onclick = onClickEventHandler; + div.onmouseover = onMouseOverEventHandler; + div.onmouseout = onMouseOutEventHandler; + })(); + + label.style.fontFamily = self.config.editorFontName; + label.setAttribute('name', GB.lineHeight[i]); + label.appendChild(document.createTextNode(text)); + div.appendChild(label); + outputHtml.appendChild(div); + } + self.createWindow(100, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + } + })(); + + self.setPulldownClassName(elem.firstChild.getElementsByTagName('LABEL'), pNode); + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + showTextBlockMenu : function (pNode) { + var self = this, + menu = pNode.getAttribute('name'), + elem = self.pulldown[menu]; + + (function () { + if (!elem) { + var i, wrapper, div, label, + outputHtml = document.createElement('div'), + onClickEventHandler = function () { + self.boxStyle(this); + }, + onMouseOverEventHandler = function () { + this.className = 'cheditor-pulldown-textblock-over'; + }, + onMouseOutEventHandler = function () { + this.className = 'cheditor-pulldown-textblock-out'; + }, + quote = GB.textBlock; + + for (i = 0; i < quote.length; i++) { + wrapper = document.createElement('div'); + div = document.createElement('div'); + (function () { + div.onclick = onClickEventHandler; + wrapper.onmouseover = onMouseOverEventHandler; + wrapper.onmouseout = onMouseOutEventHandler; + })(); + wrapper.className = 'cheditor-pulldown-textblock-out'; + div.id = i; + div.style.border = quote[i][0]; + div.style.backgroundColor = quote[i][1]; + div.style.fontFamily = self.config.editorFontName; + + label = document.createElement('label'); + label.appendChild(document.createTextNode('가나다라 ABC')); + div.appendChild(label); + wrapper.appendChild(div); + outputHtml.appendChild(wrapper); + } + self.createWindow(160, outputHtml); + self.createPulldownFrame(outputHtml, menu); + elem = self.pulldown[menu]; + elem.firstChild.className = 'cheditor-pulldown-textblock-container'; + } + })(); + + self.windowPos(pNode, menu); + self.displayWindow(pNode, menu); + }, + + createPulldownFrame : function (contents, id) { + var div = document.createElement('div'); + div.className = 'cheditor-pulldown-frame'; + div.appendChild(contents); + this.pulldown[id] = div; + this.cheditor.container.firstChild.appendChild(div); + }, + + setDefaultCss : function (ar) { + var cssFile, head, found = false, children, i, href, css; + + ar = ar || {css: 'editarea.css', doc: this.doc}; + cssFile = this.config.cssPath + ar.css; + head = ar.doc.getElementsByTagName('head')[0]; + + if (this.undefined(head)) { + return; + } + + if (head.hasChildNodes()) { + children = head.childNodes; + for (i = 0; i < children.length; i++) { + if (children[i].nodeName.toLowerCase() === 'link') { + href = children[i].getAttribute('href'); + if (href && href === cssFile) { + found = true; + break; + } + } + } + } + + if (!found) { + css = head.appendChild(ar.doc.createElement('link')); + css.setAttribute('type', 'text/css'); + css.setAttribute('rel', 'stylesheet'); + css.setAttribute('media', 'all'); + css.setAttribute('href', this.config.cssPath + ar.css); + } + }, + + setEditorEvent : function () { + var self = this, + onKeyDownEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyDown(evt); + }, + onKeyPressEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyPress(evt); + }, + onKeyUpEventHandler = function (evt) { + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + return; + } + self.doOnKeyUp(evt); + }, + onMouseUpEventHandler = function (evt) { + if (self.cheditor.mode === 'rich') { + if (evt.clientX <= self.doc.body.offsetWidth) { + self.doEditorEvent(evt); + } else { + self.restoreRange(); + } + return; + } + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + } + }, + onMouseDownEventHandler = function (evt) { + if (self.cheditor.mode === 'rich') { + if (evt.clientX <= self.doc.body.offsetWidth) { + // self.clearSelection(); + } else { + self.backupRange(); + } + self.boxHideAll(); + return; + } + if (self.cheditor.mode === 'preview') { + self.stopEvent(evt); + } + }; + + (function () { + self.addEvent(self.doc, 'keydown', onKeyDownEventHandler); + self.addEvent(self.doc, 'keypress', onKeyPressEventHandler); + self.addEvent(self.doc, 'keyup', onKeyUpEventHandler); + self.addEvent(self.doc, 'mouseup', onMouseUpEventHandler); + self.addEvent(self.doc, 'mousedown', onMouseDownEventHandler); + })(); + }, + + addEvent : function (evTarget, evType, evHandler) { + if (evTarget.addEventListener) { + evTarget.addEventListener(evType, evHandler, false); + } else { + evTarget.attachEvent('on' + evType, evHandler); + } + }, + + removeEvent : function (elem, ev, func) { + if (elem.removeEventListener) { + elem.removeEventListener(ev, func, false); + } else { + elem.detachEvent('on' + ev, func); + } + }, + + stopEvent : function (ev) { + if (ev && ev.preventDefault) { + ev.preventDefault(); + ev.stopPropagation(); + } else { + ev = ev || window.event; + ev.cancelBubble = true; + ev.returnValue = false; + } + }, + + toolbarButtonOut : function (elemButton, nTop) { + elemButton.style.top = -nTop + 'px'; + }, + + toolbarButtonOver : function (elemButton) { + var nTop = elemButton.style.top.substring(0, elemButton.style.top.length - 2); + elemButton.style.top = nTop - 22 + 'px'; + }, + + getElement : function (elem, tag) { + if (!elem || !tag) { + return null; + } + while (elem && elem.nodeName.toLowerCase() !== tag.toLowerCase()) { + if (elem.nodeName.toLowerCase() === 'body') { + break; + } + elem = elem.parentNode; + } + return elem; + }, + + hyperLink : function (href, target, title) { + var self = this, + links = null, i, + createLinks = function () { + var range = self.restoreRange(), + selectedLinks = [], + linkRange = self.createRange(), selection = null, container = null, k; + + self.backupRange(range); + + if (self.W3CRange) { + self.doc.execCommand("CreateLink", false, href); + selection = self.getSelection(); + + for (i = 0; i < selection.rangeCount; ++i) { + range = selection.getRangeAt(i); + container = range.commonAncestorContainer; + + if (self.getSelectionType(range) === GB.selection.text) { + container = container.parentNode; + } + + if (container.nodeName.toLowerCase() === 'a') { + selectedLinks.push(container); + } else { + links = container.getElementsByTagName('a'); + for (k = 0; k < links.length; ++k) { + linkRange.selectNodeContents(links[k]); + if (linkRange.compareBoundaryPoints(range.END_TO_START, range) < 1 && + linkRange.compareBoundaryPoints(range.START_TO_END, range) > -1) + { + selectedLinks.push(links[k]); + } + } + } + } + linkRange.detach(); + } else { + range = self.doc.selection.createRange(); + range.execCommand("UnLink", false); + range.execCommand("CreateLink", false, href); + + switch (self.getSelectionType(range)) { + case GB.selection.text : + container = range.parentElement(); + break; + case GB.selection.element : + container = range.item(0).parentNode; + break; + default : return null; + } + + if (container.nodeName.toLowerCase() === 'a') { + selectedLinks.push(container); + } else { + links = container.getElementsByTagName('a'); + for (i = 0; i < links.length; ++i) { + linkRange.moveToElementText(links[i]); + if (linkRange.compareEndPoints("StartToEnd", range) > -1 && + linkRange.compareEndPoints("EndToStart", range) < 1) + { + selectedLinks.push(links[i]); + } + } + } + } + return selectedLinks; + }; + + this.editArea.focus(); + links = createLinks(); + if (links) { + for (i = 0; i < links.length; ++i) { + if (target) { + links[i].setAttribute("target", target); + } + if (title) { + links[i].setAttribute("title", title); + } + } + } + }, + + getOffsetBox : function (el) { + var box = el.getBoundingClientRect(), + doc = this.doc.documentElement, + body = this.doc.body, + scrollTop = doc.scrollTop || body.scrollTop, + scrollLeft = doc.scrollLeft || body.scrollLeft, + clientTop = doc.clientTop || body.clientTop || 0, + clientLeft = doc.clientLeft || body.clientLeft || 0, + top = box.top + scrollTop - clientTop, + left = box.left + scrollLeft - clientLeft; + + return { top: Math.round(top), left: Math.round(left) }; + }, + + makeSpacerElement : function () { + var elem, + para = this.doc.createElement('p'); + + if (GB.browser.msie && GB.browser.version < 11 && GB.browser.version > 8) { + elem = this.doc.createComment(this.cheditor.bogusSpacerName); + } else if (GB.browser.msie_c) { + elem = this.createNbspTextNode(); + } else { + elem = this.doc.createElement('br'); + elem.className = this.cheditor.bogusSpacerName; + } + + para.appendChild(elem); + return para; + }, + + boxStyle : function (el) { + var range, elem, ctx, textRange, frag, pNode, + blockQuote = this.doc.createElement('blockquote'), + para = null; + + this.editAreaFocus(); + range = this.range || this.getRange() + + blockQuote.style.border = GB.textBlock[el.id][0]; + blockQuote.style.backgroundColor = GB.textBlock[el.id][1]; + blockQuote.style.padding = '5px 10px'; + + if (!this.W3CRange) { + ctx = range.htmlText; + blockQuote.innerHTML = ctx || ' '; + range.select(); + this.insertHTML(blockQuote); + textRange = this.getRange(); + elem = range.parentElement(); + textRange.moveToElementText(elem); + textRange.collapse(false); + textRange.select(); + } else { + try { + frag = range.extractContents(); + if (!frag.firstChild) { + para = this.makeSpacerElement(); + blockQuote.appendChild(para); + } else { + blockQuote.appendChild(frag); + } + + range.insertNode(blockQuote); + pNode = blockQuote.parentNode; + + while (pNode && pNode.nodeName.toLowerCase() !== 'body') { + if (pNode.nodeName.toLowerCase() === 'p' || pNode.nodeName.toLowerCase() === 'div') { + pNode.parentNode.insertBefore(blockQuote, pNode.nextSibling); + break; + } + pNode = pNode.parentNode; + } + this.placeCaretAt(para || blockQuote, false); + } catch (ignore) { + // -- + } + } + this.boxHideAll(); + }, + + insertFlash : function (elem) { + var embed = null, pos, str, obj, child, movieHeight, params = [], movieWidth, i, + div = this.doc.createElement('div'); + + this.editAreaFocus(); + this.restoreRange(); + + if (typeof elem === 'string') { + elem = this.trimSpace(elem); + pos = elem.toLowerCase().indexOf('embed'); + + if (pos !== -1) { + str = elem.substr(pos); + pos = str.indexOf('>'); + div.innerHTML = '<' + str.substr(0, pos) + '>'; + embed = div.firstChild; + } else { + div.innerHTML = elem; + obj = div.getElementsByTagName('object')[0]; + + if (obj && obj.hasChildNodes()) { + child = obj.firstChild; + movieWidth = (isNaN(obj.width) !== true) ? obj.width : 320; + movieHeight = (isNaN(obj.height) !== true) ? obj.height : 240; + do { + if ((child.nodeName.toLowerCase() === 'param') && + (!this.undefined(child.name) && !this.undefined(child.value))) { + params.push({key: (child.name === 'movie') ? 'src' : child.name, val: child.value}); + } + child = child.nextSibling; + } while (child); + + if (params.length > 0) { + embed = this.doc.createElement('embed'); + embed.setAttribute('width', movieWidth); + embed.setAttribute('height', movieHeight); + for (i = 0; i < params.length; i++) { + embed.setAttribute(params[i].key, params[i].val); + } + embed.setAttribute('type', 'application/x-shockwave-flash'); + } + } + } + + if (embed) { + if (this.W3CRange) { + this.insertNodeAtSelection(embed); + } else { + this.doCmdPaste(embed.outerHTML); + } + } + } + }, + + insertHtmlPopup : function (elem) { + this.editAreaFocus(); + this.restoreRange(); + + if (!this.W3CRange) { + this.doCmdPaste((this.toType(elem) === 'string') ? elem : elem.outerHTML); + } else { + this.insertNodeAtSelection(elem); + } + this.clearStoredSelections(); + }, + + insertHTML : function (html) { + if (!this.W3CRange) { + this.getRange().pasteHTML((this.toType(html) === 'string') ? html : html.outerHTML); + } else { + this.insertNodeAtSelection(html); + } + }, + + placeCaretAt : function (elem, az) { + var range = this.createRange(), + selection = this.getSelection(); + + if (this.undefined(az)) { + az = false; + } + + if (this.W3CRange) { + selection.removeAllRanges(); + try { + if (elem.lastChild && elem.lastChild.nodeName.toLowerCase() === 'br') { + az = true; + } + range.selectNodeContents(elem); + } catch (e) { + range.selectNode(elem); + } + + range.collapse(az); + + try { + selection.addRange(range); + } catch (e) { + this.placeCaretAt(this.doc.body, az); + } + } else if (elem.nodeType === GB.node.element) { + range.moveToElementText(elem); + range.collapse(az); + range.select(); + } + }, + + selectNodeContents : function (node, pos) { + var collapsed = !this.undefined(pos), + selection = this.getSelection(), + range = this.getRange(); + + if (node.nodeType === GB.node.element) { + range.selectNode(node); + if (collapsed) { + range.collapse(pos); + } + } + selection.removeAllRanges(); + selection.addRange(range); + return range; + }, + + insertNodeAtSelection : function (insertNode) { + var range = this.getRange(), + selection = this.getSelection(), + frag = this.doc.createDocumentFragment(), + lastNode = null, + elem, commonAncestorContainer, startOffset, pNode, tmpWrapper; + + if (!range.collapsed) { + range.deleteContents(); + range = this.getRange(); + } + + commonAncestorContainer = range.commonAncestorContainer; + startOffset = range.startOffset; + pNode = commonAncestorContainer; + + if (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + + this.removeBogusSpacer(pNode); + + if (typeof insertNode === 'string') { + tmpWrapper = this.doc.createElement('div'); + tmpWrapper.innerHTML = insertNode; + + elem = tmpWrapper.firstChild; + while (elem) { + lastNode = frag.appendChild(elem); + elem = tmpWrapper.firstChild; + } + } else { + lastNode = frag.appendChild(insertNode); + } + + if (startOffset < 1 && commonAncestorContainer.nodeType === GB.node.text) { + commonAncestorContainer.parentNode.insertBefore(frag, commonAncestorContainer); + } else { + range.insertNode(frag); + } + + if (lastNode) { + range = range.cloneRange(); + range.setStartAfter(lastNode); + selection.removeAllRanges(); + selection.addRange(range); + } + this.toolbarUpdate(); + return lastNode; + }, + + findBogusSpacer : function (elem, all) { + var self = this, result = []; + (function findBogusSpacer(elem) { + var i = 0, node; + for (; i < elem.childNodes.length; i++) { + node = elem.childNodes[i]; + if ((node.nodeType === GB.node.element && node.className === self.cheditor.bogusSpacerName) || + (node.nodeType === GB.node.comment && node.nodeValue === self.cheditor.bogusSpacerName)) { + result.push(node); + } + if (node.nodeType === GB.node.text && node.nodeValue === '\u00a0' && !node.nextSibling) { + result.push(node); + } + if (all) { + findBogusSpacer(node); + } + } + })(elem); + return result; + }, + + removeBogusSpacer : function (elem, removeEmpty, all) { + var remove = this.findBogusSpacer(elem, all), i = 0; + for (; i < remove.length; i++) { + remove[i].parentNode.removeChild(remove[i]); + } + if (removeEmpty && !(elem.hasChildNodes())) { + elem.parentNode.removeChild(elem); + } + }, + + ieGetRangeAt : function (range) { + var self = this, start = {}, end = {}; + + function convert(result, bStart) { + var point = range.duplicate(), + span = self.doc.createElement('span'), + parent = point.parentElement(), + cursor = self.createRange(), + compareStr = bStart ? 'StartToStart' : 'StartToEnd'; + + point.collapse(bStart); + parent.appendChild(span); + cursor.moveToElementText(span); + + while (cursor.compareEndPoints(compareStr, point) > 0 && span.previousSibling) { + parent.insertBefore(span, span.previousSibling); + cursor.moveToElementText(span); + } + + result.container = span.nextSibling || span.previousSibling; + if (result.container === null) { + result.container = span.parentNode; + } + parent.removeChild(span); + } + + convert(start, true); convert(end, false); + return { startContainer: start.container, endContainer: end.container }; + }, + + applyLineHeight : function (opt) { + var range = this.getRange(), + isBlockElement = function (elem) { + return GB.lineHeightBlockTags[elem.toLowerCase()]; + }, + getNextLeaf = function (elem, endLeaf, value) { + while (!elem.nextSibling) { + elem = elem.parentNode; + if (!elem) { + return elem; + } + } + + if (elem === endLeaf) { + return elem; + } + + var leaf = elem.nextSibling; + if (isBlockElement(leaf.nodeName)) { + leaf.style.lineHeight = value; + } + + while (leaf.firstChild) { + leaf = leaf.firstChild; + if (leaf.nodeType !== GB.node.text && isBlockElement(leaf.nodeName)) { + leaf.style.lineHeight = value; + } + } + return leaf; + }, + applyBlockElement = function (elem) { + while (elem) { + if (elem.nodeName.toLowerCase() === "body") { + para = self.doc.createElement("p"); + para.style.lineHeight = opt; + + if (elem.firstChild) { + elem.insertBefore(para, elem.firstChild); + } else { + elem.appendChild(para); + break; + } + + nextNode = para.nextSibling; + while (nextNode) { + if (isBlockElement(nextNode.nodeName)) { + break; + } + para.appendChild(nextNode); + nextNode = para.nextSibling; + } + break; + } + + if (isBlockElement(elem.nodeName)) { + elem.style.lineHeight = opt; + break; + } + elem = elem.parentNode; + } + }, + ieRange, startContainer, endContainer, para, nextNode, startLeaf, endLeaf, nextLeaf; + + if (!this.W3CRange) { + ieRange = this.ieGetRangeAt(range); + startContainer = ieRange.startContainer; + endContainer = ieRange.endContainer; + } else { + startContainer = range.startContainer; + endContainer = range.endContainer; + } + + if (!this.doc.body.hasChildNodes() || !startContainer || !endContainer) { + throw "Object Error"; + } + + if (startContainer && startContainer.nodeName.toLowerCase() === "body") { + startContainer = startContainer.firstChild; + } + + try { + if (startContainer === endContainer) { + applyBlockElement(startContainer); + } else { + startLeaf = startContainer; + while (startLeaf) { + if (startLeaf.nodeName.toLowerCase() === "body" || isBlockElement(startLeaf.nodeName)) { + break; + } + startLeaf = startLeaf.parentNode; + } + + endLeaf = endContainer; + while (endLeaf) { + if (endLeaf.nodeName.toLowerCase() === "body" || isBlockElement(endLeaf.nodeName)) { + break; + } + endLeaf = endLeaf.parentNode; + } + + if (startLeaf === endLeaf) { + if (isBlockElement(startLeaf.nodeName)) { + startLeaf.style.lineHeight = opt; + } else { + para = this.doc.createElement("p"); + para.style.lineHeight = opt; + startLeaf.insertBefore(para, startLeaf.firstChild); + + nextNode = para.nextSibling; + while (nextNode) { + if (isBlockElement(nextNode.nodeName)) { + break; + } + para.appendChild(nextNode); + nextNode = para.nextSibling; + } + } + } else { + applyBlockElement(startLeaf); + while (startLeaf) { + nextLeaf = getNextLeaf(startLeaf, endLeaf, opt); + if (startLeaf === endLeaf) { + break; + } + startLeaf = nextLeaf; + } + } + } + } catch (ignore) { + // -- + } + }, + + doInsertImage : function (imgs, para, insertSpace) { + var range, i, count = 0, imgAttr, img, space, lastNode = null, pNode, div, selection, + len = imgs.length, self = this, + fragment = this.doc.createDocumentFragment(); + + function checkPara(pNode) { + var result = true, text; + if (!pNode.hasChildNodes()) { + return false; + } + self.getNodeTree(pNode, function (node) { + if (!node.node || node === pNode) { + return; + } + if (node.type === GB.node.text) { + text = self.trimSpace(node.node.nodeValue); + if (!text || text === '\u00a0') { + result = false; + } + } else if (node.type === GB.node.element + && (node.name === 'br' && node.node.className === self.cheditor.bogusSpacerName)) { + result = false; + } + }); + return result; + } + + this.editAreaFocus(); + range = this.restoreRange(); + pNode = this.getRangeElement(range); + if (!pNode) { + return; + } + + if (pNode.nodeName.toLowerCase() === 'body') { + pNode = this.doc.createElement('p'); + if (this.W3CRange) { + range.insertNode(pNode); + } else { + range.pasteHTML(pNode.outerHTML); + } + } + + if (para) { + do { + if (GB.lineHeightBlockTags[pNode.nodeName.toLowerCase()]) { + break; + } + pNode = pNode.parentNode; + } while (pNode && pNode.nodeName.toLowerCase() !== 'body'); + } + + for (i in imgs) { + if (!imgs.hasOwnProperty(i) || this.undefined(imgs[i])) { + continue; + } + imgAttr = imgs[i]; + img = this.doc.createElement('img'); + img.setAttribute('src', imgAttr.fileUrl); + + if (this.config.imgSetAttrWidth === 1) { + img.style.width = imgAttr.width; + img.style.height = imgAttr.height; + } else if (this.config.imgSetAttrWidth === -1) { + img.style.width = '100%'; + img.style.height = 'auto'; + } + + if (this.config.imgSetAttrAlt) { + img.setAttribute('alt', imgAttr.alt || imgAttr.origName); + } else { + img.removeAttribute('alt'); + } + + count++; + if (para) { + lastNode = fragment.appendChild(this.doc.createElement('p')); + if (imgAttr.align !== 'left') { + lastNode.style.textAlign = imgAttr.align; + } + lastNode.appendChild(img); + if (insertSpace && count < len) { + space = this.makeSpacerElement(); + fragment.appendChild(space); + } + } else { + lastNode = fragment.appendChild(img); + if (insertSpace && count < len) { + fragment.appendChild(this.doc.createTextNode('\u00a0')); + } + } + this.images.push(imgAttr); + } + + if (lastNode) { + if (para) { + if (pNode.nodeName.toLowerCase() === 'p') { + if (!checkPara(pNode)) { + pNode.parentNode.replaceChild(fragment, pNode); + } else { + pNode.parentNode.insertBefore(fragment, pNode.nextSibling); + } + } else { + if (!this.W3CRange) { + div = this.doc.createElement('div'); + div.appendChild(fragment); + range.pasteHTML(div.innerHTML); + } else { + range.insertNode(fragment); + } + } + this.placeCaretAt(lastNode.nextSibling ? lastNode.nextSibling : lastNode, false); + } else { + if (!this.W3CRange) { + div = this.doc.createElement('div'); + div.appendChild(fragment); + range.pasteHTML(div.innerHTML); + } else { + range.deleteContents(); + range.insertNode(fragment); + range.setStartAfter(lastNode); + range.setEndAfter(lastNode); + selection = this.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + } + } + this.setImageEvent(true); + } + }, + + showTagSelector : function (on) { + if (this.config.showTagPath !== true) { + return; + } + this.cheditor.tagPath.style.display = on ? 'block' : 'none'; + }, + + getTextContentSelectionPos : function (newline) { + var textContent = this.cheditor.textContent, + start, end, docRange, startRange, endRange, textContentLength, normalizedText; + + if (typeof textContent.selectionStart === 'number') { + start = textContent.selectionStart; + end = textContent.selectionEnd; + } else { + textContentLength = textContent.value.length; + normalizedText = textContent.value.replace(/\r\n/g, '\n'); + docRange = document.selection.createRange(); + startRange = textContent.createTextRange(); + endRange = startRange.duplicate(); + endRange.collapse(false); + startRange.moveToBookmark(docRange.getBookmark()); + + if (startRange.compareEndPoints('StartToEnd', endRange) > -1) { + start = end = textContentLength; + } else { + start = -startRange.moveStart('character', -textContentLength); + if (newline) { + start += normalizedText.slice(0, start).split('\n').length - 1; + } + if (startRange.compareEndPoints('EndToEnd', endRange) > -1) { + end = textContentLength; + } else { + end = -startRange.moveEnd('character', -textContentLength); + if (newline) { + end += normalizedText.slice(0, end).split('\n').length - 1; + } + } + } + } + return { startPos: start, endPos: end }; + }, + + removeEmptyBogusTag : function (content) { + if (/^<(p|div)([^>]+?)?>( |\s+?)<\/(p|div)>$/g.test(this.trimSpace(content))) { + return ''; + } + if (/^]+?)?>$/g.test(content)) { + return ''; + } + return content; + }, + + setTextContentSelection : function (startPos, endPos, content) { + var textContent = this.cheditor.textContent, range, top; + + content = this.removeEmptyBogusTag(content); + + if (!content) { + textContent.focus(); + return; + } + if (startPos === 0 && endPos === 0) { + textContent.value = content; + textContent.focus(); + return; + } + textContent.select(); + if (typeof textContent.setSelectionRange === 'function') { + textContent.value = content; + textContent.setSelectionRange(startPos, startPos); + textContent.focus(); + if (this.browser.msie || this.browser.edge) { + setTimeout(function () { + top = textContent.scrollTop; + if (top > 0) { + textContent.scrollTop = top + textContent.clientHeight / 2; + } + textContent.selectionEnd = endPos; + }, 0); + } else { + textContent.selectionEnd = endPos; + } + } else { + range = document.selection.createRange(); + textContent.value = content; + range.moveEnd('character', endPos - content.length); + range.moveStart('character', startPos); + range.select(); + top = textContent.scrollTop; + if (top > 0) { + textContent.scrollTop = top + textContent.clientHeight / 2; + } + } + }, + + richMode : function () { + var char, collapsed, cursor, endNode, endPos, endRange, outputHTML = null, pNode, pos, range, + scrollTop, selection, startNode, startPos, startRange, textContent = null, textContentLength; + + if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') { + this.cheditor.textContent.focus(); + textContent = this.makeHtmlContent(); + textContentLength = textContent.length; + + pos = this.getTextContentSelectionPos(true); + startPos = pos.startPos; + endPos = pos.endPos; + + collapsed = startPos === endPos; + cursor = startPos; + + if (textContent.charAt(startPos) === '>') { + startPos++; + collapsed = true; + } else { + while (cursor > -1) { + char = textContent.charAt(cursor); + if (char === '&' + && textContent.charAt(cursor + 1) === 'n' && textContent.charAt(cursor + 2) === 'b' + && textContent.charAt(cursor + 3) === 's' && textContent.charAt(cursor + 4) === 'p' + && textContent.charAt(cursor + 5) === ';') + { + startPos = cursor; + collapsed = endPos < (startPos + 6); + break; + } + if (char === '>') { + break; + } + if (char === '<') { + startPos = cursor; + collapsed = true; + break; + } + cursor--; + } + } + + if (!collapsed) { + cursor = endPos; + if (textContent.charAt(endPos - 1) === '<' || + (textContent.charAt(endPos) === '\n' && cursor === textContentLength - 1)) { + endPos = startPos; + } else { + while (cursor < textContentLength) { + char = textContent.charAt(cursor); + if (char === '<') { + break; + } + if (char === '>') { + endPos = startPos; + break; + } + cursor++; + } + } + } else { + endPos = startPos; + } + + if (startPos > 0 && endPos < textContentLength - 1) { + outputHTML = textContent.substring(0, startPos); + outputHTML += ''; + outputHTML += textContent.substring(startPos, endPos); + outputHTML += ''; + outputHTML += textContent.substring(endPos, textContent.length); + textContent = outputHTML; + } + + this.cheditor.textContent.value = ''; + this.removeEvent(window, 'resize', this.resizeTextContent); + this.putContents(this.convertContentsSpacer(textContent)); + } + + this.range = null; + this.cheditor.textContent.blur(); + this.cheditor.textContent.removeAttribute('start-pos'); + this.cheditor.textContent.removeAttribute('end-pos'); + this.cheditor.textContent.style.display = 'none'; + this.cheditor.toolbarWrapper.style.display = ''; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper'; + this.cheditor.editArea.style.visibility = 'hidden'; + + if (!this.setFullScreenMode) { + this.cheditor.editArea.style.height = this.config.editorHeight; + } + + this.cheditor.editArea.style.display = 'block'; + this.cheditor.editArea.style.visibility = 'visible'; + this.setDesignMode(true); + this.editAreaFocus(); + + if (outputHTML) { + startNode = this.doc.getElementById('startBogusNode'); + endNode = this.doc.getElementById('endBogusNode'); + if (startNode && endNode) { + scrollTop = 0; + pNode = startNode; + if (pNode) { + while (pNode.offsetParent) { + scrollTop += pNode.offsetTop; + pNode = pNode.offsetParent; + } + scrollTop -= this.getWindowSize(this.doc).height / 2; + } + + if (this.doc.compatMode === 'CSS1Compat') { + this.doc.documentElement.scrollTop = scrollTop; + } else { + this.doc.body.scrollTop = scrollTop; + } + + if (this.W3CRange) { + selection = this.clearSelection(); + range = this.createRange(); + range.setStartAfter(startNode); + range.setEndBefore(endNode); + try { + selection.addRange(range); + } catch (ignore) { + // display: none? + } + } else { + startRange = this.createRange(); + endRange = startRange.duplicate(); + startRange.moveToElementText(startNode); + endRange.moveToElementText(endNode); + startRange.setEndPoint('StartToEnd', startRange); + startRange.setEndPoint('EndToEnd', endRange); + startRange.select(); + } + + pNode = startNode.parentNode; + pNode.removeChild(startNode); + pNode = endNode.parentNode; + pNode.removeChild(endNode); + } + } + + this.setImageEvent(true); + this.toolbarUpdate(); + }, + + editMode : function () { + var self = this, + editorWidth, scrollBarWidth, scrollBarHeight, resize, content = null, borderWidth = 1, borderHeight = 1, + startPos, endPos, startNode, endNode, startEndNode, + editorHeight = this.cheditor.editWrapper.offsetHeight, + textContent = this.cheditor.textContent, + startNodeValue = 'startBogusNode', endNodeValue = 'endBogusNode', + startNodeCommentTag = '', endNodeCommentTag = '', + range = this.restoreRange(); + + if (this.cheditor.mode === 'preview') { + if (textContent.getAttribute('start-pos')) { + startPos = parseInt(textContent.getAttribute('start-pos'), 10); + textContent.removeAttribute('start-pos'); + + if (textContent.getAttribute('end-pos')) { + endPos = parseInt(textContent.getAttribute('end-pos'), 10); + textContent.removeAttribute('end-pos'); + } else { + endPos = startPos; + } + content = textContent.value.replace(/\r\n/g, '\n'); + } else { + this.placeCaretAt(this.doc.body.firstChild || this.doc.body, true); + range = this.getRange(); + } + } + + if (!content) { + startEndNode = this.insertStartEndNode(range); + startNode = this.doc.createComment(startNodeValue); + endNode = this.doc.createComment(endNodeValue); + startEndNode.startNode.parentNode.replaceChild(startNode, startEndNode.startNode); + startEndNode.endNode.parentNode.replaceChild(endNode, startEndNode.endNode); + startEndNode.startNode = startNode; + startEndNode.endNode = endNode; + + content = this.getContents(startEndNode); + + startPos = content.search(startNodeCommentTag); + endPos = content.search(endNodeCommentTag); + endPos -= endNodeCommentTag.length + 2; + content = content.replace(startNodeCommentTag, '').replace(endNodeCommentTag, ''); + + } + + this.resetDocumentBody(); + this.cheditor.editArea.style.display = 'none'; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-code'; + this.cheditor.editBlock.style.display = 'none'; + + textContent.value = ''; + textContent.style.lineHeight = '17px'; + textContent.style.width = '100px'; + textContent.style.height = '100px'; + textContent.style.display = 'block'; + + scrollBarWidth = textContent.offsetWidth - 100; + scrollBarHeight = textContent.offsetHeight - 100; + if (this.browser.msie && this.browser.version < 8) { + scrollBarHeight += 2; + } + + textContent.setAttribute('xbar-height', scrollBarHeight.toString()); + textContent.setAttribute('ybar-width', scrollBarWidth.toString()); + + resize = textContent.offsetHeight + (editorHeight - textContent.offsetHeight) - scrollBarHeight - borderHeight; + textContent.style.height = resize + 'px'; + + this.resizeTextContent = function () { + editorWidth = self.cheditor.editWrapper.offsetWidth; + resize = textContent.offsetWidth + (editorWidth - textContent.offsetWidth) - scrollBarWidth - borderWidth; + self.cheditor.textContent.style.width = resize + 'px'; + }; + + (function () { + self.addEvent(window, 'resize', self.resizeTextContent); + self.resizeTextContent(); + })(); + + this.setTextContentSelection(startPos, endPos, content); + this.setDesignMode(false); + }, + + makeHtmlContent : function () { + var content = this.trimSpace(this.cheditor.textContent.value); + content = this.trimZeroSpace(content); + return content || '

     

    '; + }, + + resetStatusBar : function () { + if (this.config.showTagPath) { + this.cheditor.tagPath.innerHTML = '<html> <body> '; + } + }, + + previewMode : function () { + var content, oSheet, pos = this.getTextContentSelectionPos(false); + + if (this.cheditor.mode === 'code' && typeof this.resizeTextContent !== 'undefined') { + this.cheditor.textContent.setAttribute('start-pos', pos.startPos.toString()); + this.cheditor.textContent.setAttribute('end-pos', pos.endPos.toString()); + content = this.makeHtmlContent(); + this.cheditor.textContent.blur(); + this.cheditor.textContent.style.display = 'none'; + this.removeEvent(window, 'resize', this.resizeTextContent); + this.putContents(content); + } + + this.clearSelection(); + this.cheditor.editBlock.style.display = 'none'; + this.cheditor.toolbarWrapper.className = 'cheditor-tb-wrapper-preview'; + if (!this.setFullScreenMode) { + this.cheditor.editArea.style.height = this.config.editorHeight; + } + this.cheditor.editArea.style.display = 'block'; + + if (GB.browser.msie && parseInt(GB.browser.version, 10) === 8) { + try { + oSheet = this.doc.styleSheets[0]; + oSheet.addRule('p:before', 'content:"\u200b"'); + } catch (ignore) { + // ignore + } + } + this.setImageEvent(false); + this.setDesignMode(false); + }, + + convertContentsSpacer : function (content) { + var self = this, bogusBr = true, + excepted = '<\/span><\/span>', + reSpacer = new RegExp('<([^>]+)>(' + excepted + ')?(?: |\s+?|\u00a0)(' + excepted + ')?<\/([^>]+)>', 'g'); + + if (GB.browser.msie && GB.browser.msie_bogus === false) { + bogusBr = false; + } + content = content.replace(/\s{2,}|[\r\n\t]+?/gm, ''); + content = content.replace(reSpacer, + function (all, open, excepted_a, excepted_b, close) { + var tagName = self.trimSpace(open.split(' ')[0]).toLowerCase(), rdata = null; + if (GB.lineHeightBlockTags[tagName] || GB.textFormatTags[tagName]) { + rdata = '<' + open + '>' + (excepted_a || ''); + rdata += bogusBr ? '
    ' : + ''; + rdata += (excepted_b || '') + ''; + } + return rdata || all; + } + ); + return content; + }, + + putContents : function (content) { + if (this.config.fullHTMLSource) { + content = content.substr(content.search(/') + 1); + content = '' + content; + this.doc.open(); + this.doc.write('' + content + ''); + this.doc.close(); + } else { + content = 'remove_this' + content; + this.doc.body.innerHTML = content; + this.doc.body.removeChild(this.doc.body.firstChild); + } + }, + + getImages : function () { + var img = this.doc.body.getElementsByTagName('img'), + imgLength = this.images.length, + imgs = [], i, imgId, j; + + for (i = 0; i < img.length; i++) { + if (img[i].src) { + imgId = img[i].src; + imgId = imgId.slice(imgId.lastIndexOf('/') + 1); + for (j = 0; j < imgLength; j++) { + if (this.images[j].fileName === imgId) { + imgs.push(this.images[j]); + break; + } + } + } + } + return imgs.length > 0 ? imgs : null; + }, + + getElementStyle : function (elem) { + return (window.getComputedStyle) ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle; + }, + + getElementDefaultDisplay : function (elem) { + return (window.getComputedStyle ? this.doc.defaultView.getComputedStyle(elem, null) : elem.currentStyle).display; + }, + + tabRepeat : function (count) { + var i = 0, tab = ''; + if (count < 1) { + return tab; + } + for (; i < count; i++) { + tab += this.cheditor.tabSpaces; + } + return tab; + }, + + htmlEncode : function (text) { + //text = text.replace(/\n{2,}$/g, '\n'); + //text = text.replace(/&/g, '&'); + text = text.replace(//g, '>'); + text = text.replace(/\u00a0/g, ' '); + //text = text.replace(/]+)> <\/font>/mgi, ''); + //text = text.replace(/\x22/g, '"'); + return text; + }, + + checkDocLinks : function () { + var links = this.doc.links, + len = links.length, + host = location.host, + i, href; + + this.cheditor.links = []; + + for (i = 0; i < len; i++) { + if (!this.config.includeHostname) { + href = links[i].href; + if (href.indexOf(host) !== -1) { + links[i].setAttribute('href', href.substring(href.indexOf(host) + host.length)); + } + } + if (this.config.linkTarget !== '' && this.config.linkTarget !== null) { + if (!(links[i].getAttribute('target'))) { + links[i].setAttribute('target', this.config.linkTarget); + } + } + if (GB.browser.msie) { + this.cheditor.links.push(links[i]); + } + } + }, + + checkDocImages : function () { + var img = this.doc.images, + len = img.length, + host = location.host, + i = 0, imgUrl; + + for (; i < len; i++) { + if (!this.config.includeHostname) { + imgUrl = img[i].src; + if (imgUrl) { + if (imgUrl.indexOf(host) !== -1) { + img[i].src = imgUrl.substring(imgUrl.indexOf(host) + host.length); + } + } + } + if (img[i].style.width) { + img[i].removeAttribute('width'); + } + if (img[i].style.height) { + img[i].removeAttribute('height'); + } + } + }, + + createNbspTextNode : function () { + return this.doc.createTextNode('\u00a0'); + }, + + getNodeTree : function (pNode, callback) { + function Node(node) { + this.node = node; + this.name = node.nodeName.toLowerCase(); + this.type = node.nodeType; + this.parent = node.parentNode; + this.indent = 0; + } + (function recurse(cNode, indent) { + var i, child, + node = new Node(cNode), + children = cNode.childNodes, + len = children.length; + + node.indent = indent; + + for (i = 0; i < len; i++) { + child = children[i]; + if (child) { + recurse(child, indent + 1); + } + } + + if (node.name !== 'body') { + callback(node); + } + })(pNode, -1); + }, + + getContents : function (startEndNode) { + var self = this, + mydoc, indentNodes = [], i, node, msie_c = typeof this.browser.msie_c !== 'undefined', + allowedIndent = this.getContents.caller !== this.getBodyContents, + insertTabSpace = function (indent) { + return msie_c ? self.doc.createComment('Tab Size:' + indent) : + self.doc.createTextNode('\n' + self.tabRepeat(indent)); + }; + + function checkChildNodes(child) { + if (!child) { + return null; + } + if (!startEndNode) { + return child; + } + do { + if (child !== startEndNode.startNode && child !== startEndNode.endNode) { + break; + } + child = child.nextSibling; + } while (child); + + return child; + } + + this.checkDocLinks(); + this.checkDocImages(); + this.getNodeTree(this.doc.body, function (node) { + if (!node.node) { + return; + } + if (self.config.exceptedElements[node.name]) { + node.parent.replaceChild(self.doc.createTextNode(''), node.node); + return; + } + + switch (node.type) { + case GB.node.text : + if (!self.isTextVisible(node.node.nodeValue)) { + node.parent.replaceChild(self.doc.createTextNode(''), node.node); + } + break; + case GB.node.element : + if (node.node.className === self.cheditor.bogusSpacerName) { + if (node.node.firstChild === null) { + if (node.name === 'br') { + node.parent.removeChild(node.node); + if (!checkChildNodes(node.parent.firstChild)) { + node.parent.appendChild(self.createNbspTextNode()); + } + } else { + node.node.appendChild(self.createNbspTextNode()); + } + } else if (!checkChildNodes(node.node.firstChild)) { + node.node.appendChild(self.createNbspTextNode()); + } + node.node.className = ''; + } + if ((node.name === 'p' || node.name === 'div') && !checkChildNodes(node.node.firstChild)) { + node.node.appendChild(self.createNbspTextNode()); + } + if (GB.newLineBeforeTags[node.name] && allowedIndent) { + if (node.node.firstChild && (node.node.firstChild.nodeType === GB.node.element)) { + node.node.insertBefore(insertTabSpace(node.indent + 1), node.node.firstChild); + node.node.appendChild(insertTabSpace(node.indent)); + } + indentNodes.push(node); + } + if (GB.selfClosingTags[node.name]) { + node.node.setAttribute('self-close-tag', '1'); + } + break; + case GB.node.comment : + if (node.node.nodeValue === self.cheditor.bogusSpacerName) { + node.parent.removeChild(node.node); + if (!checkChildNodes(node.parent.firstChild)) { + node.parent.appendChild(self.createNbspTextNode()); + } else if (node.parent.firstChild.nodeName.toLowerCase() === 'br') { + node.parent.replaceChild(self.createNbspTextNode(), node.node.firstChild); + } + } + } + }); + + for (i in indentNodes) { + if (indentNodes.hasOwnProperty(i)) { + node = indentNodes[i]; + node.parent.insertBefore(insertTabSpace(node.indent), node.node); + + if (node.node.nextSibling) { + node.node.nextSibling.parentNode.insertBefore(insertTabSpace(node.indent), node.node.nextSibling); + } else { + node.parent.appendChild(insertTabSpace(node.indent)); + } + } + } + + indentNodes = []; + mydoc = this.doc.body.innerHTML; + mydoc = mydoc.replace(/^\s*[\r\n]/gm, '').replace(/\u200b/g, ''); + + if (msie_c) { + mydoc = mydoc.replace(/(?:[\r\n]*)/g, + function (a, b) { + return '\n' + self.tabRepeat(b); + }).replace(/<(\/?)([A-Za-z]+)([^>]*)>/g, + function (a, close, tag, attr) { + attr = attr.replace(/\s(\w+)=([^'"\s>]+)/g, + function (a, k, v) { + return ' ' + k.toLowerCase() + '="' + v + '"'; + }).replace(/([A-Za-z\-]+)(?:\s*):\s+?/g, + function (a, k) { + return k.toLowerCase() + ': '; + }); + return '<' + close + tag.toLowerCase() + attr + '>'; + } + ); + } + + mydoc = mydoc.replace(/<[^>]+>/gm, function (match) { + match = match.replace(/\sself-close-tag="1"([^>]+)?/g, '$1 /'); + + if (self.config.allowedOnEvent !== true) { + match = match.replace(/\s+on([A-Za-z]+)=("[^"]*"|'[^']*'|[^\s>]*)/g, ''); + } + + if (self.config.colorToHex) { + match = match.replace(/(background-color|color)\s*([:=])\s*(rgba?)\(\s*(\d+)\s*,\s*(\d+),\s*(\d+)\)/ig, + function (all, p, s, rgb, r, g, b) { + return p + s + ' ' + self.colorConvert(rgb + '(' + r + ',' + g + ',' + b + ')', 'hex'); + }); + } else { + match = match.replace(/(background-color|color)\s*([:=])\s*(#[A-Fa-f0-9]{3,6})/ig, + function (all, p, s, hex) { + return p + s + ' ' + self.colorConvert(hex, 'rgb'); + }); + } + + return match; + }); + + return mydoc; + }, + + returnContents : function (mydoc) { + mydoc = this.removeEmptyBogusTag(mydoc); + this.setDesignMode(true); + this.cheditor.textarea.value = mydoc; + return mydoc; + }, + + makeAmpTag : function (str) { + return str.replace(/</g, '&lt;').replace(/>/g, '&gt;'); + }, + + removeAmpTag : function (str) { + if (this.config.removeIndent) { + str = str.replace(/^[\t]+/gm, ''); + } + return str.replace (/&lt;/g, '<').replace(/&gt;/g, '>'); + }, + + getOutputContents : function () { + this.resetViewHTML(); + return this.removeAmpTag(this.getContents(null)); + }, + + outputHTML : function () { + return '\n' + + '\n' + + ' \n' + + ' ' + this.config.docTitle + '\n' + + ' \n' + + ' \n' + + this.returnContents(this.getOutputContents()) + + ' \n' + + ''; + }, + + getBodyContents : function () { + return (this.cheditor.mode === 'code') ? this.makeHtmlContent() : this.getContents(null); + }, + + outputBodyHTML : function () { + return this.returnContents(this.getOutputContents()); + }, + + outputBodyText : function () { + return this.returnContents(this.getBodyText()); + }, + + getBodyText : function () { + this.resetViewHTML(); + return this.trimSpace(String(GB.browser.msie ? this.doc.body.innerText : this.doc.body.textContent)); + }, + + returnFalse : function () { + var img = this.doc.images, i; + this.editAreaFocus(); + + for (i = 0; i < img.length; i++) { + if (img[i].src) { + if (img[i].getAttribute('onload')) { + img[i].onload = 'true'; + } + } else { + img[i].removeAttribute('onload'); + img[i].removeAttribute('className'); + } + } + return false; + }, + + trimZeroSpace : function (str) { + return str ? str.replace(/[\ufeff\u200b\xa0\u3000]+/gm, '') : ''; + }, + + trimSpace : function (str) { + return str ? str.replace(/^[\s\ufeff\u200b\xa0\u3000]+|[\s\ufeff\u200b\xa0\u3000]+$/g, '') : ''; + }, + + makeRandomString : function () { + var chars = '_-$@!#0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz', + len = 32, + clen = chars.length, + rData = '', i, rnum; + + for (i = 0; i < len; i++) { + rnum = Math.floor(Math.random() * clen); + rData += chars.substring(rnum, rnum + 1); + } + return rData; + }, + + strLength : function (str) { + var len = str.length, mbytes = 0, i, c; + for (i = 0; i < len; i++) { + c = str.charCodeAt(i); + if (c > 128) { + mbytes++; + } + } + return (len - mbytes) + (mbytes * 2); + }, + + resetViewHTML : function () { + if (this.cheditor.mode === 'code') { + this.switchEditorMode('rich'); + } + }, + + contentsLengthAll : function () { + return this.strLength(this.outputHTML()); + }, + + contentsLength : function () { + var content = String(this.trimSpace(this.outputBodyHTML())); + if (!content) { + return 0; + } + return this.strLength(content); + }, + + inputLength : function () { + var content = this.getBodyText(); + if (content === '') { + return 0; + } + return this.strLength(content); + }, + + displayWindow : function (pNode, id) { + var pullDown = this.pulldown[id]; + this.editAreaFocus(); + this.backupRange(); + this.boxHideAll(id); + pullDown.style.visibility = 'visible'; + pullDown.style.zIndex = 10002; + pullDown.focus(); + }, + + pulldownMouseOver : function (el) { + if (el.className === 'cheditor-pulldown-selected') { + return; + } + el.className = 'cheditor-pulldown-mouseover'; + }, + pulldownMouseOut : function (el) { + if (el.className === 'cheditor-pulldown-selected') { + return; + } + el.className = 'cheditor-pulldown-mouseout'; + }, + + windowPos : function (pNode, id) { + var left = pNode.offsetLeft, box = this.pulldown[id]; + + if (this.toolbar[id].type === 'combobox') { + left -= parseInt(this.toolbar[this.toolbar[id].node].width, 10); + } + if (this.toolbar[id].prev && !this.toolbar[id].next) { + left -= 1; + } + box.style.left = left + 'px'; + box.style.top = pNode.offsetTop + parseInt(pNode.style.height, 10) + 'px'; + }, + + boxHideAll : function (showId) { + var menu, box, ishide; + for (menu in this.pulldown) { + if (this.pulldown.hasOwnProperty(menu)) { + box = this.pulldown[menu]; + if (box) { + box.style.visibility = 'hidden'; + ishide = this.undefined(showId) ? true : (menu !== showId); + if (ishide && this.toolbar[menu].checked) { + this.toolbar[menu].checked = false; + this.toolbarButtonUnchecked(this.toolbar[menu]); + } + } + } + } + this.editAreaFocus(); + }, + + createWindow : function (width, elem) { + elem.className = 'cheditor-pulldown-container'; + elem.style.width = width + 'px'; + }, + + setColorTable : function (menu) { + var self = this, + pulldown = document.createElement('div'), + len = GB.colors.length, + container = document.createElement('div'), + selected = document.createElement('input'), + selectedValue = document.createElement('input'), + cellWrapper = document.createElement('div'), + br = document.createElement('div'), + reset = document.createElement('span'), + pickerSwitch = document.createElement('span'), + button = document.createElement('img'), + showTooltip = '더 많은 색 보기', + hideTooltip = '감추기', + i, cell, color = 0, colorPicker, cellBorder, + onMouseOverEventHandler = function () { + colorPicker.fromString(this.id); + this.parentNode.className = 'cheditor-pulldown-color-cell-over'; + }, + onMouseOutEventHandler = function () { + this.parentNode.className = 'cheditor-pulldown-color-cell'; + }, + onClickEventHandler = function () { + self.doCmdPopup(menu, this.id); + }, + onResetEventHandler = function () { + colorPicker.fromString(self.colorConvert(selectedValue.style.backgroundColor, 'hex')); + }, + onPickerEventHandler = function () { + if (self.toolbar[menu].colorNode.showPicker) { + colorPicker.hidePicker(); + self.toolbar[menu].colorNode.showPicker = false; + pickerSwitch.setAttribute('title', showTooltip); + } else { + colorPicker.showPicker(); + self.toolbar[menu].colorNode.showPicker = true; + pickerSwitch.setAttribute('title', hideTooltip); + } + }, + onSubmitEventHandler = function () { + self.doCmdPopup(menu, selected.value); + }; + + selected.setAttribute('type', 'text'); + selected.setAttribute('maxlength', '7'); + selected.className = 'cheditor-pulldown-color-selected'; + + selectedValue.setAttribute('type', 'text'); + selectedValue.onfocus = function () { + selected.focus(); + }; + + selectedValue.style.cursor = 'default'; + selectedValue.className = 'cheditor-pulldown-color-selected'; + selected.style.marginLeft = '-1px'; + selected.style.borderLeft = 'none'; + selected.spellcheck = false; + + cellWrapper.style.margin = '2px'; + cellWrapper.style.position = 'relative'; + container.style.position = 'relative'; + + br.style.clear = 'both'; + br.style.height = '0px'; + colorPicker = new GB.colorDropper(selected, {'iconDir': this.config.iconPath}); + + for (i = 0; i < len; i++) { + if (i % 13 === 0) { + cellWrapper.appendChild(br.cloneNode(true)); + if (i === 26) { + cellWrapper.lastChild.style.height = '4px'; + } + len++; + continue; + } + cellBorder = document.createElement('span'); + cellBorder.className = 'cheditor-pulldown-color-cell'; + cell = document.createElement('span'); + cell.id = GB.colors[color]; + cell.style.backgroundColor = GB.colors[color++]; + cell.appendChild(document.createTextNode('\u00a0')); + cellBorder.appendChild(cell); + cellWrapper.appendChild(cellBorder); + (function () { + cell.onclick = onClickEventHandler; + cell.onmouseover = onMouseOverEventHandler; + cell.onmouseout = onMouseOutEventHandler; + })(); + } + + cellWrapper.appendChild(br); + cellWrapper.appendChild(selectedValue); + cellWrapper.appendChild(selected); + + reset.appendChild(document.createTextNode('\u00a0')); + reset.className = 'cheditor-pulldown-color-reset'; + reset.onclick = onResetEventHandler; + + cellWrapper.appendChild(reset); + + pickerSwitch.appendChild(document.createTextNode('\u00a0')); + pickerSwitch.className = 'cheditor-pulldown-color-show-picker'; + pickerSwitch.setAttribute('title', showTooltip); + pickerSwitch.onclick = onPickerEventHandler; + cellWrapper.appendChild(pickerSwitch); + + button.className = 'cheditor-pulldown-color-submit'; + button.src = this.config.iconPath + 'button/input_color.gif'; + button.onclick = onSubmitEventHandler; + cellWrapper.appendChild(button); + container.appendChild(cellWrapper); + + self.toolbar[menu].colorNode.selectedValue = selectedValue; + self.toolbar[menu].colorNode.colorPicker = colorPicker; + + pulldown.appendChild(container); + return pulldown; + }, + + onKeyPressToolbarUpdate : function () { + var self = this; + if (this.tempTimer) { + clearTimeout(this.tempTimer); + } + this.tempTimer = setTimeout(function () { + if (self.config.showTagPath) { + self.doEditorEvent(); + } else { + self.toolbarUpdate(); + } + self.tempTimer = null; + }, 50); + }, + + doOnKeyDown : function (evt) { + switch (evt.keyCode) { + case 37: case 38: case 39: case 40: case 46: case 8: + this.onKeyPressToolbarUpdate(evt); + } + }, + + doOnKeyUp : function (evt) { + var caretRange, css, enterNode, i, keyCode = evt.keyCode, node, self = this, storedNode, storedRange, + clearBackgroundColor = function (cNode) { + if (cNode.nodeType !== GB.node.element || cNode.hasChildNodes() || !cNode.getAttribute('style')) { + return cNode; + } + if (GB.textFormatTags[cNode.nodeName.toLowerCase()]) { + css = self.checkCssValue(cNode, 'background-color'); + if (css) { + css = self.clearCss(cNode, 'background-color'); + if (cNode.nodeName.toLowerCase() === 'span' && !css) { + node = cNode.parentNode; + node.removeChild(cNode); + return node; + } + } + } + return cNode; + }; + + if (keyCode !== 13 || this.cheditor.mode !== 'rich') { + return; + } + + if (typeof GB.browser.msie_c !== 'undefined') { + node = this.storedSelections[0]; + if (!node) { + return; + } + if (node.className === this.cheditor.bogusSpacerName) { + node.className = ''; + } + while (node.firstChild) { + node = node.firstChild; + } + if (node.nodeType === GB.node.element && node.canHaveChildren) { + node.className = this.cheditor.bogusSpacerName; + } + return; + } + + caretRange = this.getRange(); + enterNode = caretRange.commonAncestorContainer; + + if (GB.browser.msie || GB.browser.edge) { + this.backupRange(caretRange); + if (enterNode.nodeType === GB.node.element) { + enterNode = clearBackgroundColor(enterNode); + enterNode.className = this.cheditor.bogusSpacerName; + } + for (i = 0; i < this.keyPressStoredSelections.length; i++) { + storedRange = this.keyPressStoredSelections[i]; + storedNode = storedRange.commonAncestorContainer; + if (storedNode && storedNode.nodeType === GB.node.element) { + node = storedNode.childNodes[storedRange.startOffset]; + if (!node) { + break; + } + while (node.firstChild) { + node = node.firstChild; + } + node = clearBackgroundColor(node); + node.className = this.cheditor.bogusSpacerName; + } + } + this.restoreRange(); + this.keyPressStoredSelections = []; + } else { + this.applyBogusClassName(caretRange); + } + }, + + doOnKeyPress : function (evt) { + var keyCode = evt.keyCode, caretRange; + if (keyCode && keyCode === 13 && this.cheditor.mode === 'rich') { + caretRange = this.getRange(); + if (typeof this.browser.msie_c !== 'undefined') { + try { + this.storedSelections[0] = caretRange.parentElement(); + } catch (e) { + this.keyPressBackupRange(); + } + } else if (GB.browser.msie || GB.browser.edge) { + this.keyPressBackupRange(); + } else { + this.applyBogusClassName(caretRange); + } + } + }, + + applyBogusClassName : function (range) { + var node = range.commonAncestorContainer; + if (range.startOffset < 1 && (!node.lastChild || node.lastChild.nodeName.toLowerCase() !== 'br')) { + do { + if (node.parentNode.nodeName.toLowerCase() === 'body') { + break; + } + node = node.parentNode; + } while (GB.textFormatTags[node.nodeName.toLowerCase()]); + + node = node.previousSibling; + if (node) { + while (node.firstChild) { + node = node.firstChild; + } + if (node.nodeType === GB.node.element && node.nodeName.toLowerCase() === 'br') { + node.className = this.cheditor.bogusSpacerName; + } + } + } else { + if (!node || node.nodeType !== GB.node.element) { + return; + } + if (node.lastChild + && node.lastChild.nodeName.toLowerCase() === 'br' + && node.lastChild.className !== this.cheditor.bogusSpacerName) + { + node.lastChild.className = this.cheditor.bogusSpacerName; + } + } + }, + + setWinPosition : function (oWin, popupAttr, windowSize) { + oWin.style.width = popupAttr.width + 'px'; + oWin.style.left = Math.round(((this.cheditor.editArea.clientWidth - popupAttr.width) / 2) + + windowSize.offsetLeft) + 'px'; + oWin.style.top = Math.round(windowSize.offsetTop) + 'px'; + }, + + getWindowSize : function (doc) { + var mydoc = doc || document, + docMode = mydoc.compatMode === 'CSS1Compat', + docBody = mydoc.body, + docElem = mydoc.documentElement, + factor, rect, physicalWidth, logicalWidth, + editAreaRect, + rData = { + width: docMode ? docElem.clientWidth : docBody.clientWidth, + height: docMode ? docElem.clientHeight : docBody.clientHeight, + scrollHeight: docMode ? docElem.scrollHeight : docBody.scrollHeight, + scrollWidth: docMode ? docElem.scrollWidth : docBody.scrollWidth + }; + + if (this.undefined(window.pageXOffset)) { + factor = 1; + if (docBody.getBoundingClientRect) { + rect = docBody.getBoundingClientRect(); + physicalWidth = rect.right - rect.left; + logicalWidth = mydoc.body.offsetWidth; + factor = Math.round ((physicalWidth / logicalWidth) * 100) / 100; + } + rData.scrollY = Math.round(docElem.scrollTop / factor); + rData.scrollX = Math.round(docElem.scrollLeft / factor); + } else { + rData.scrollY = window.pageYOffset; + rData.scrollX = window.pageXOffset; + } + + editAreaRect = this.cheditor.editArea.getBoundingClientRect(); + rData.clientTop = docElem.clientTop || docBody.clientTop || 0; + rData.clientLeft = docElem.clientLeft || docBody.clientLeft || 0; + rData.offsetTop = rData.scrollY + (rData.height / 2); + rData.offsetLeft = editAreaRect.left + rData.scrollX - rData.clientLeft; + return rData; + }, + + popupWinLoad : function (popupAttr) { + var self = this, + windowSize = self.getWindowSize(), + iframe = document.createElement('iframe'), + body = document.getElementsByTagName('body')[0], + done = false, + + popWinResizeHeight = function (evt) { + iframe.contentWindow.focus(); + iframe.contentWindow.init.call(self, iframe, popupAttr.argv || null); + + if (self.cheditor.popupElem.style.visibility !== 'visible') { + self.cheditor.popupElem.style.top = Math.ceil(parseInt(self.cheditor.popupElem.style.top, 10) - + Math.ceil(self.cheditor.popupElem.clientHeight / 2)) + 'px'; + self.cheditor.popupElem.style.visibility = 'visible'; + } + + self.stopEvent(evt); + }, + modalResize = function () { + self.cheditor.modalBackground.style.height = (windowSize.scrollHeight > windowSize.height) ? + windowSize.scrollHeight : windowSize.height + 'px'; + + if (window.scrollWidth > window.width) { + self.cheditor.modalBackground.style.width = windowSize.width + + (windowSize.scrollWidth - windowSize.width) + 'px'; + } else { + self.cheditor.modalBackground.style.width = windowSize.width + 'px'; + } + self.cheditor.modalBackground.style.left = windowSize.scrollX + 'px'; + }, + onReadyStateChangeEventHandler = function (evt) { + if (!done && (!this.readyState || this.readyState === 'complete' || this.readyState === 'loaded')) { + popWinResizeHeight(evt); + done = true; + } + }; + + if (self.cheditor.popupTitle.hasChildNodes()) { + self.cheditor.popupTitle.removeChild(self.cheditor.popupTitle.firstChild); + } + + if (self.cheditor.popupFrameWrapper.hasChildNodes()) { + self.cheditor.popupFrameWrapper.removeChild(self.cheditor.popupFrameWrapper.firstChild); + } + + self.cheditor.popupTitle.appendChild(document.createTextNode(popupAttr.title)); + self.cheditor.popupElem.style.zIndex = self.modalElementZIndex + 1; + self.setWinPosition(self.cheditor.popupElem, popupAttr, windowSize); + + iframe.setAttribute('frameBorder', '0'); + iframe.setAttribute('height', '0'); + iframe.setAttribute('width', String(popupAttr.width - 22)); + iframe.setAttribute('name', popupAttr.tmpl); + iframe.setAttribute('src', self.config.popupPath + popupAttr.tmpl); + iframe.id = popupAttr.tmpl; + + self.cheditor.modalBackground.style.zIndex = self.modalElementZIndex; + body.insertBefore(self.cheditor.modalBackground, body.firstChild); + body.insertBefore(self.cheditor.popupElem, body.firstChild); + + self.cheditor.popupFrameWrapper.appendChild(iframe); + self.cheditor.popupElem.style.visibility = 'hidden'; + self.cheditor.popupElem.style.display = 'block'; + self.cheditor.modalBackground.style.display = 'block'; + GB.dragWindow.init(self.cheditor.dragHandle, self.cheditor.popupElem); + + (function () { + if (GB.browser.msie && !(self.undefined(iframe.onreadystatechange))) { + iframe.onreadystatechange = onReadyStateChangeEventHandler; + } else { + iframe.onload = popWinResizeHeight; + } + + if (GB.browser.msie && GB.browser.version < 9) { + window.onresize = function () { + windowSize = self.getWindowSize(); + modalResize(); + }; + modalResize(); + self.cheditor.modalBackground.style.filter = 'alpha(opacity=50)'; + self.cheditor.modalBackground.style.opacity = 0.5; + } else { + self.cheditor.modalBackground.style.opacity = 0.5; + } + self.cheditor.modalBackground.focus(); + })(); + }, + + popupWinCancel : function () { + this.restoreRange(); + this.popupWinClose(); + }, + + popupWinClose : function () { + if (!this.cheditor.popupElem) { + return; + } + this.cheditor.popupElem.style.display = 'none'; + this.cheditor.popupElem.style.zIndex = -1; + this.cheditor.popupFrameWrapper.src = ''; + + if (this.cheditor.popupFrameWrapper.hasChildNodes()) { + this.cheditor.popupFrameWrapper.removeChild(this.cheditor.popupFrameWrapper.firstChild); + } + + this.cheditor.modalBackground.style.display = 'none'; + this.cheditor.modalBackground.style.zIndex = -1; + + if (this.modalReSize !== null) { + if (GB.browser.opera) { + window.removeEventListener('resize', this.modaReSize, false); + } + this.modalReSize = null; + } + this.editAreaFocus(); + }, + + clearStoredSelections : function () { + this.storedSelections.splice(0, this.storedSelections.length); + }, + + restoreRange : function () { + var range = null, selection = null; + if (this.storedSelections[0]) { + if (this.W3CRange) { + selection = this.getSelection(); + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + selection.addRange(this.storedSelections[0]); + range = selection.getRangeAt(0); + } else { + range = this.createRange(); + if (this.storedSelections[0]) { + if (typeof this.storedSelections[0] === 'string') { + range.moveToBookmark(this.storedSelections[0]); + } else { + range = this.storedSelections[0]; + } + } + range.select(); + } + } + return range; + }, + + keyPressBackupRange : function (range) { + var selection = null, i; + if (this.W3CRange) { + selection = this.getSelection(); + if (selection) { + for (i = 0; i < selection.rangeCount; i++) { + this.keyPressStoredSelections.push(selection.getRangeAt(i)); + } + } + } else { + range = range || this.getRange(); + switch (this.getSelectionType()) { + case GB.selection.none: + case GB.selection.text: + this.storedSelections[0] = range.getBookmark(); + break; + case GB.selection.element: + this.storedSelections[0] = range; + break; + default: + this.storedSelections[0] = null; + } + } + }, + + backupRange : function (range) { + var selection = null; + if (this.W3CRange) { + selection = this.getSelection(); + if (selection && selection.rangeCount > 0) { + this.storedSelections[0] = selection.getRangeAt(0); + } + } else { + range = range || this.getRange(); + switch (this.getSelectionType()) { + case GB.selection.none: + case GB.selection.text: + this.storedSelections[0] = range.getBookmark(); + break; + case GB.selection.element: + this.storedSelections[0] = range; + break; + default: + this.storedSelections[0] = null; + } + } + }, + + getSelection : function () { + return this.W3CRange ? this.editArea.getSelection() : this.doc.selection; + }, + + clearSelection : function () { + var sel = this.getSelection(); + if (!sel) { + return; + } + if (this.W3CRange) { + sel.removeAllRanges(); + } else { + sel.empty(); + } + return sel; + }, + + getRange : function () { + var selection = this.getSelection(), range = null; + if (this.W3CRange) { + if (selection.getRangeAt) { + range = selection.rangeCount ? selection.getRangeAt(0) : this.doc.createRange(); + } else { + range = this.doc.createRange(); + range.setStart(selection.anchorNode, selection.anchorOffset); + range.setEnd(selection.focusNode, selection.focusOffset); + if (range.collapsed !== selection.isCollapsed) { + range.setStart(selection.focusNode, selection.focusOffset); + range.setEnd(selection.anchorNode, selection.anchorOffset); + } + } + } else { + range = selection.createRange ? selection.createRange() : this.doc.createRange(); + if (!range) { + range = this.doc.body.createTextRange(); + } + } + this.range = range; + return range; + }, + + createRange : function () { + return this.W3CRange ? this.doc.createRange() : this.doc.body.createTextRange(); + }, + + rangeCollapsed : function (range) { + return this.W3CRange ? + range.collapsed : + (!this.undefined(range.text) && range.text.length === 0 && range.boundingWidth === 0); + }, + + getRangeElement : function (range) { + return this.W3CRange ? this.getW3CRangeElement(range) : this.getIeRangeElement(range); + }, + + getIeRangeElement : function (range) { + var sType = this.getSelectionType(), + node; + + if (!range) { + range = this.createRange(); + } + + switch (sType) { + case GB.selection.text : + node = range.parentElement(); + break; + case GB.selection.element : + node = range.item(0); + break; + case GB.selection.none : + if (!this.undefined(range.parentElement)) { + node = range.parentElement(); + } else { + node = range.item(0); + } + } + return node; + }, + + getW3CRangeElement : function (range) { + var ancestorContainer = range.commonAncestorContainer, + startContainer = range.startContainer, + startOffset = range.startOffset, + endContainer = range.endContainer, + endOffset = range.endOffset, + docFragment = null, node = startContainer; + + if (GB.browser.msie || GB.browser.edge) { + if (!range.collapsed && ancestorContainer.nodeType === GB.node.element) { + if (ancestorContainer === endContainer) { + node = ancestorContainer.childNodes[endOffset - 1]; + } else if (ancestorContainer === startContainer) { + node = ancestorContainer.childNodes[startOffset]; + } else { + docFragment = range.cloneContents(); + node = (docFragment.childNodes.length === 1) ? startContainer.nextSibling : ancestorContainer; + } + } + } else { + if (!range.collapsed + && startContainer.nodeType === GB.node.element + && startContainer === endContainer + && endOffset - startOffset === 1 + && startContainer.hasChildNodes()) + { + node = startContainer.childNodes[startOffset]; + } + } + + if (node.nodeType === GB.node.text) { + node = node.parentNode; + } + return node; + }, + + getSelectionType : function () { + var selection = this.getSelection(), type; + + if (this.W3CRange) { + if (!selection) { + type = GB.selection.none; + } else if (selection.rangeCount && !selection.isCollapsed && !selection.toString()) { + type = GB.selection.element; + } else { + type = GB.selection.text; + } + } else { + switch (selection.type) { + case 'Text' : type = GB.selection.text; break; + case 'Control' : type = GB.selection.element; break; + default : type = GB.selection.none; + } + if (selection.createRange().parentElement) { + type = GB.selection.text; + } + } + return type; + }, + + windowOpen : function (popupName) { + this.editAreaFocus(); + this.boxHideAll(); + this.backupRange(); + if (!(this.undefined(GB.popupWindow[popupName]))) { + var popup = GB.popupWindow[popupName]; + if (popupName === 'ImageUpload' && window.File && window.FileReader && window.FileList && window.Blob) { + popup.tmpl = 'image.html5.html'; + } + this.popupWinLoad(popup); + } else { + alert('사용할 수 없는 명령입니다.'); + } + }, + + doCmd : function (cmd, opt) { + var self = this, range = this.range, + i, keyboard = '', command = '', pNode, node, tmpframe, tmpdoc, html, content, + hr, newHr, para, next = null, nNode, tagName, style, id, hRule, nodeType, css, found = false, + isEmpty = false, selectionType, selection, nodeRange, + cleanPaste = function () { + self.editAreaFocus(); + var tmpDoc = self.cheditor.tmpdoc; + tmpDoc.execCommand('SelectAll'); + tmpDoc.execCommand('Paste'); + return self.cleanFromWord(tmpDoc); + }, + isTextVisible = function (elem) { + return (!(elem.firstChild.nodeType === GB.node.text && elem.firstChild === elem.lastChild && + elem.firstChild.nodeValue === '')); + }; + + this.editAreaFocus(); + this.boxHideAll(); + + if (!range) { + return; + } + + if (cmd === 'NewDocument') { + if (confirm('글 내용이 모두 사라집니다. 계속하시겠습니까?')) { + this.doc.body.innerHTML = ''; + } + this.images = []; + this.editImages = {}; + this.editAreaFocus(); + this.toolbarUpdate(); + this.initDefaultParagraphSeparator(); + return; + } + + if (cmd === 'ClearTag') { + if (confirm('모든 HTML 태그를 삭제합니다. 계속하시겠습니까?\n(P, DIV, BR 태그와 텍스트는 삭제하지 않습니다.)')) { + content = this.doc.body.innerHTML; + this.doc.body.innerHTML = content.replace(/<(\/?)([^>]*)>/g, + function (a, b, c) { + var el = c.toLowerCase().split(/ /)[0]; + if (el !== 'p' && el !== 'div' && el !== 'br') { + return ''; + } + return '<' + b + el + '>'; + }); + } + this.editAreaFocus(); + this.toolbarUpdate(); + return; + } + + if (cmd === 'Print') { + this.editArea.print(); + return; + } + + if (cmd === 'PageBreak') { + this.printPageBreak(); + this.editAreaFocus(); + return; + } + + selectionType = this.getSelectionType(); + if (this.W3CRange || selectionType === GB.selection.none) { + range = this.doc; + } + + if (!GB.browser.msie && (cmd === 'Cut' || cmd === 'Copy' || cmd === 'Paste')) { + if ((range.execCommand(cmd, false, opt)) !== true) { + switch (cmd) { + case 'Cut' : keyboard = 'x'; command = '자르기'; break; + case 'Copy' : keyboard = 'c'; command = '복사'; break; + case 'Paste': keyboard = 'v'; command = '붙이기'; break; + } + alert('사용하고 계신 브라우저는 보안 상의 이유로 \'' + command + '\' 명령을 사용하실 수 없습니다. \n\n' + + '키보드 단축키를 이용하여 주십시오.\n단축키: Windows: Ctrl+' + keyboard + ', Mac OS X: Command+' + keyboard); + this.editAreaFocus(); + + } + return; + } + + try { + if (cmd === 'PasteFromWord') { + if (this.undefined(this.cheditor.tmpdoc)) { + tmpframe = this.doc.createElement('iframe'); + tmpframe.setAttribute('contentEditable', 'true'); + tmpframe.style.visibility = 'hidden'; + tmpframe.style.height = tmpframe.style.width = '0px'; + tmpframe.setAttribute('frameBorder', '0'); + this.cheditor.editWrapper.appendChild(tmpframe); + + tmpdoc = tmpframe.contentWindow.document; + tmpdoc.designMode = 'On'; + tmpdoc.open(); + tmpdoc.close(); + this.cheditor.tmpdoc = tmpdoc; + } + + if (this.W3CRange) { + html = cleanPaste(); + // range = this.restoreRange(); + this.insertNodeAtSelection(html); + } else { + range = this.getRange(); + range.pasteHTML(cleanPaste()); + range.select(); + } + } else if (cmd === 'Paste') { + this.cheditor.paste = 'text'; + this.handlePaste(null); + this.cheditor.paste = 'html'; + } else if (cmd === 'InsertHorizontalRule') { + hr = this.doc.createElement('hr'); + hr.style.height = '1px'; + hr.style.backgroundColor = '#999'; + hr.style.border = 'none'; + + this.unselectionElement(hr); + range = this.getRange(); + + if (this.W3CRange) { + range.insertNode(hr); + } else { + nodeType = this.getSelectionType(); + id = this.makeRandomString(); + range.execCommand('InsertHorizontalRule', false, id); + switch (nodeType) { + case GB.selection.none : + case GB.selection.text : + node = range.parentElement(); + break; + case GB.selection.element : + node = range.item(0); + break; + default : + return; + } + newHr = this.$(id); + newHr.parentNode.replaceChild(hr, newHr); + } + + hRule = hr; + pNode = hRule.parentNode; + para = this.makeSpacerElement(); + + while (pNode && GB.textFormatTags[pNode.nodeName.toLowerCase()]) { + pNode = pNode.parentNode; + } + + tagName = pNode.tagName.toLowerCase(); + if (GB.textFormatBlockTags[tagName]) { + if (hr.nextSibling) { + next = this.doc.createElement(tagName); + pNode.parentNode.insertBefore(next, pNode.nextSibling); + while (hr.nextSibling) { + if (hr.nextSibling.nodeType === GB.node.text && hr.nextSibling.nodeValue === '') { + hr = hr.nextSibling; + continue; + } + if (hr.nextSibling.parentNode !== pNode) { + node = hr.nextSibling.parentNode; + while (node !== pNode && GB.textFormatTags[node.nodeName.toLowerCase()]) { + nNode = this.doc.createElement(node.nodeName); + style = this.getCssValue(node); + if (style) { + for (i = 0; i < style.length; i++) { + nNode.style[style[i].name] = style[i].value; + } + } + if (next.hasChildNodes() === false) { + next.appendChild(nNode); + while (hr.nextSibling) { + nNode.appendChild(hr.nextSibling); + } + } else { + next.appendChild(nNode); + nNode.appendChild(next.firstChild); + } + node = node.parentNode; + } + } else { + next.appendChild(hr.nextSibling); + } + } + } + node = hr.parentNode; + pNode.parentNode.insertBefore(hRule, pNode.nextSibling); + + while (node && node !== pNode) { + if (node.hasChildNodes() === false || (isTextVisible(node)) === false) { + nNode = node.parentNode; + node.parentNode.removeChild(node); + node = nNode; + continue; + } + node = node.parentNode; + } + + if (pNode.hasChildNodes() === false || (isTextVisible(pNode)) === false) { + pNode.parentNode.replaceChild(para.cloneNode(true), pNode); + } + if (next === null || next.hasChildNodes() === false) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling); + } + + node = hRule.nextSibling; + while (node.firstChild) { + node = node.firstChild; + } + if (node && node.nodeType !== GB.node.text) { + node = node.parentNode; + } + this.placeCaretAt(this.W3CRange ? node : hRule.nextSibling, true); + } else { + if (!hRule.previousSibling) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule); + } + if (!hRule.nextSibling) { + hRule.parentNode.insertBefore(para.cloneNode(true), hRule.nextSibling); + } + this.placeCaretAt(hRule.nextSibling, hRule.nextSibling.nodeType === GB.node.text); + } + } else { + switch (cmd) { + case 'JustifyLeft' : + case 'JustifyCenter' : + case 'JustifyRight' : + case 'JustifyFull' : + pNode = this.getRangeElement(this.range); + node = null; + + if (GB.offElementTags[pNode.nodeName.toLowerCase()]) { + nodeRange = this.createRange(); + selection = this.clearSelection(); + if (this.W3CRange) { + nodeRange.selectNode(pNode); + selection.addRange(nodeRange); + } else { + nodeRange.moveToElementText(pNode); + nodeRange.select(); + range = nodeRange; + } + } + // Caption + if (pNode.nodeName.toLowerCase() === 'img') { + if (pNode.parentNode.nodeName.toLowerCase() === 'figure') { + node = pNode.parentNode; + if (node.parentNode.nodeName.toLowerCase() === 'div') { + node = node.parentNode; + node.style.textAlign = GB.textAlign[cmd]; + break; + } + } + } else if (pNode.nodeName.toLowerCase() === 'figure') { + node = pNode.parentNode; + if (node.nodeName.toLowerCase() === 'div') { + node.style.textAlign = GB.textAlign[cmd]; + break; + } + } + + do { + if (pNode.nodeName.toLowerCase() === 'li') { + node = pNode; + break; + } + pNode = pNode.parentNode; + } while (pNode && pNode.nodeName.toLowerCase() !== 'body'); + + + if (node) { + node.style.textAlign = GB.textAlign[cmd]; + break; + } + + range.execCommand(cmd, false, opt); + pNode = this.getRangeElement(this.W3CRange ? this.getRange() : range); + + while (pNode && pNode.nodeName.toLowerCase() !== 'body') { + if (typeof pNode.getAttribute !== 'undefined' && pNode.getAttribute('align')) { + node = pNode; + break; + } else { + css = this.getCssValue(pNode); + if (css) { + for (i = 0; i < css.length; i++) { + if (css[i].name === 'text-align') { + node = pNode; + break; + } + } + } + } + pNode = pNode.parentNode; + } + + if (node) { + pNode.style.textAlign = GB.textAlign[cmd]; + pNode.removeAttribute('align'); + break; + } + break; + case 'InsertOrderedList' : + case 'InsertUnOrderedList' : + range.execCommand(cmd, false, opt); + if (this.W3CRange) { + range = this.getRange(); + node = range.commonAncestorContainer; + if (node.nodeType === GB.node.element && node.lastChild && + node.lastChild.nodeName.toLowerCase() === 'br') { + node.lastChild.className = this.cheditor.bogusSpacerName; + isEmpty = true; + } + found = false; + while (node) { + if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') { + found = true; + break; + } + node = node.parentNode; + } + if (found) { + node.style.listStyleType = ''; + if (!GB.browser.msie) { + if (node.parentNode.nodeName.toLowerCase() === 'p' || + node.parentNode.nodeName.toLowerCase() === 'div') { + pNode = node.parentNode; + if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') { + pNode.removeChild(pNode.lastChild); + } + if (pNode.firstChild === node && pNode.lastChild === node) { + pNode.parentNode.insertBefore(node, pNode); + pNode.parentNode.removeChild(pNode); + this.placeCaretAt(node.lastChild, isEmpty); + } + } + } + } + } + break; + default : + if (range.queryCommandSupported(cmd)) { + range.execCommand(cmd, false, opt); + } + } + } + } catch (e) { + alert(cmd + ': 지원되지 않는 명령입니다. ' + e.toString()); + } + + this.toolbarUpdate(); + }, + + cleanFromWord : function (tmpDoc) { + var doc = tmpDoc.body.innerHTML; + doc = doc.replace(/MsoNormal/g, ''); doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, ''); + doc = doc.replace(/<\/?v:[^>]*>/g, ''); doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, ''); + doc = doc.replace(//g, ''); doc = doc.replace(//g, ''); + doc = doc.replace(/<\\?\?xml[^>]*>/g, ''); doc = doc.replace(/<\/?o:p[^>]*>/g, ''); doc = doc.replace(/<\/?v:[^>]*>/g, ''); + doc = doc.replace(/<\/?o:[^>]*>/g, ''); doc = doc.replace(/<\/?st1:[^>]*>/g, ''); //doc = doc.replace(/lang=.?[^' >]*/ig, ''); + doc = doc.replace(/type=.?[^' >]*/g, ''); doc = doc.replace(/href='#[^']*'/g, ''); doc = doc.replace(/href='#[^']*'/g, ''); + doc = doc.replace(/name=.?[^' >]*/g, ''); doc = doc.replace(/ clear='all'/g, ''); doc = doc.replace(/id='[^']*'/g, ''); + doc = doc.replace(/title='[^']*'/g, ''); doc = doc.replace(/\n/g, ''); doc = doc.replace(/\r/g, ''); + doc = doc.replace(/mso\-[^'>;]*/g, ''); doc = doc.replace(/]*/ig, ']*<\/span>/ig, ''); + return doc; + }, + + printPageBreak : function () { + var hr = document.createElement('hr'), + div = this.doc.createElement('div'); + hr.style.pageBreakAfter = 'always'; + hr.style.border = '1px #999 dotted'; + this.insertHTML(hr); + div.appendChild(this.doc.createTextNode('\u00a0')); + this.insertHTML(div); + }, + + doCmdPaste : function (html) { + var range = null; + this.editAreaFocus(); + if (!this.W3CRange) { + if (this.range.item) { + range = this.doc.body.createTextRange(); + if (range) { + range.moveToElementText(this.range.item(0)); + range.select(); + this.range.item(0).outerHTML = html; + } + this.toolbarUpdate(); + } else { + this.range.pasteHTML(html); + this.range.select(); + } + } else { + this.insertNodeAtSelection(html); + } + }, + + getPreviousLeaf : function (node) { + var leaf; + while (!node.previousSibling) { + node = node.parentNode; + if (!node) { + return node; + } + } + leaf = node.previousSibling; + while (leaf.lastChild) { + leaf = leaf.lastChild; + } + return leaf; + }, + + getNextLeaf : function (node, breakNode) { + var leaf; + while (!node.nextSibling) { + node = node.parentNode; + if ((breakNode && breakNode === node) || !node) { + return node; + } + } + leaf = node.nextSibling; + if (breakNode && leaf === breakNode) { + return node; + } + while (leaf.firstChild) { + leaf = leaf.firstChild; + } + return leaf; + }, + + isTextVisible : function (text) { + var i, found = false, len = text.length; + for (i = 0; i < len; i++) { + if (text.charAt(i) !== ' ' && text.charAt(i) !== '\t' && text.charAt(i) !== '\r' && text.charAt(i) !== '\n') { + found = true; + break; + } + } + return found; + }, + + checkCssValue : function (elem, prop) { + var css = this.getCssValue(elem), i; + if (!css) { + return null; + } + for (i = 0; i < css.length; i++) { + if (css[i].name === prop) { + return css[i]; + } + } + return null; + }, + + getCssValue : function (elem) { + var i, q, style = [], len, css; + + css = elem.getAttribute('style'); + if (!css) { + return null; + } + if (typeof css === 'object') { + css = css.cssText; + } + if (this.trimSpace(css) === '') { + return null; + } + + css = css.replace(/;$/, '').split(';'); + len = css.length; + + for (i = 0; i < len; i++) { + q = css[i].split(':'); + style.push({'name': this.trimSpace(q[0]).toLowerCase(), 'value': this.trimSpace(q[1]).toLowerCase()}); + } + return style; + }, + + makeFontCss : function (cmd, opt, elem) { + switch (cmd) { + case 'font-size' : elem.style.fontSize = opt; break; + case 'font-family' : elem.style.fontFamily = opt; break; + case 'color': elem.style.color = opt; break; + case 'background-color': elem.style.backgroundColor = opt; break; + } + }, + + insertStartEndNode : function (range) { + var startNode = this.doc.createElement('span'), + startRange, endRange, endNode, collapsed, node = null; + + startNode.id = 'startNode'; + + if (!this.W3CRange) { + startNode.appendChild(this.doc.createTextNode('\u200b')); + try { + endRange = range.duplicate(); + startRange = range.duplicate(); + endRange.collapse(false); + startRange.collapse(true); + } catch (e) { + node = this.getRangeElement(range); + if (node.nodeType === GB.node.element) { + + } else { + return null; + } + } + + endNode = startNode.cloneNode(true); + endNode.id = 'endNode'; + + if (node) { + node.parentNode.insertBefore(startNode, node); + node.parentNode.insertBefore(endNode, node.nextSibling); + collapsed = false; + } else { + collapsed = startRange.isEqual(endRange); + endRange.pasteHTML(endNode.outerHTML); + endRange.moveStart('character', -1); + endNode = endRange.parentElement(); + + if (collapsed || range.text.length === 0) { + endNode.parentNode.insertBefore(startNode, endNode); + } else { + startNode = endNode.cloneNode(true); + startNode.id = 'startNode'; + startRange.pasteHTML(startNode.outerHTML); + startRange.moveStart('character', -1); + startNode = startRange.parentElement(); + } + } + endRange = null; + startRange = null; + } else { + endRange = range.cloneRange(); + startRange = range.cloneRange(); + startRange.collapse(true); + + endRange.collapse(false); + endNode = startNode.cloneNode(false); + endNode.id = 'endNode'; + + collapsed = range.collapsed; + if (collapsed) { + endRange.insertNode(endNode); + endNode.parentNode.insertBefore(startNode, endNode); + } else { + endRange.insertNode(endNode); + startRange.insertNode(startNode); + } + + if (startNode.previousSibling && startNode.previousSibling.nodeType === GB.node.text && + startNode.previousSibling.nodeValue === '') { + startNode.previousSibling.parentNode.removeChild(startNode.previousSibling); + } + if (endNode.nextSibling && endNode.nextSibling.nodeType === GB.node.text && + endNode.nextSibling.nodeValue === '') { + endNode.nextSibling.parentNode.removeChild(endNode.nextSibling); + } + startRange.detach(); endRange.detach(); + endRange = null; startRange = null; + } + return {startNode: startNode, endNode: endNode, collapsed: collapsed}; + }, + + removeStartEndNode : function (nodes) { + if (nodes.startNode) { + nodes.startNode.parentNode.removeChild(nodes.startNode); + } + if (nodes.endNode) { + nodes.endNode.parentNode.removeChild(nodes.endNode); + } + }, + + clearCss : function (node, name) { + var i, css, styles = []; + + if (!node || node.nodeType !== GB.node.element) { + return null; + } + + css = this.getCssValue(node); + if (!css) { + return null; + } + + node.removeAttribute('style'); + for (i = 0; i < css.length; i++) { + if (css[i].name !== name) { + node.style[css[i].name] = css[i].value; + styles.push(css[i]); + } + } + + return styles.length ? styles : null; + }, + + doCmdPopup : function (cmd, opt, checked) { + var self = this, + range, cursor, selectionType, pNode, node, found, isEmpty, span, endNode, startNode, i, endNodeAncestorRange, + startNodeRange, endNodeRange, compare, tNode, len, selection, child, css, tempNodes, endNodeAncestor, + backupRange, removeNodes = [], spanNodes = [], applyTextNodes = [], tailNodes = [], headNodes = [], rootNode = null, + zeroWidth = this.doc.createTextNode('\u200b'), inRange, + + makeSpanText = function (elem, ancestor) { + if (self.undefined(ancestor)) { + ancestor = elem.parentNode; + } + span = self.doc.createElement('span'); + self.makeFontCss(cmd, opt, span); + ancestor.insertBefore(span, elem); + span.appendChild(elem); + spanNodes.push(span); + return span; + }, + searchTextNode = function (node, match) { + var i = 0, len = node.childNodes.length; + for (; i < len; i++) { + child = node.childNodes[i]; + match = searchTextNode(child, match); + if (child === startNode) { + break; + } + if (child.nodeType === GB.node.text) { + match = true; + break; + } + if (child.nodeType === GB.node.element && child.hasChildNodes() === false && + GB.textFormatTags[child.nodeName.toLowerCase()]) { + removeNodes.push(child); + } + } + return match; + }, + compareBoundaryPoints = function (range, type, source) { + var values = { + 'StartToStart': 0, //Range.START_TO_START, + 'StartToEnd': 1, //Range.START_TO_END, + 'EndToEnd': 2, //Range.END_TO_END, + 'EndToStart': 3 //Range.END_TO_START + }; + + if (self.W3CRange) { + return range.compareBoundaryPoints(values[type], source); + } + + type = type === 'StartToEnd' ? 'EndToStart' : (type === 'EndToStart' ? 'StartToEnd' : type); + return range.compareEndPoints(type, source); + }, + rangeSelectNode = function (range, node) { + if (self.W3CRange) { + range.selectNode(node); + } else { + if (node.nodeType === GB.node.text) { + node = node.parentNode; + } + range.moveToElementText(node); + } + }, + clearPreviousLeaf = function (node) { + var leaf, css = []; + while (!node.previousSibling) { + node = node.parentNode; + if (!node || node.nodeName.toLowerCase() === 'body') { + return null; + } + } + + leaf = node.previousSibling; + + while (leaf.lastChild && leaf.nodeType === GB.node.element && leaf !== startNode) { + rangeSelectNode(cursor, leaf); + compare = compareBoundaryPoints(cursor, 'StartToStart', startNodeRange); + if (compare === 1) { + css = self.clearCss(leaf, cmd); + if (!css && (leaf.nodeName.toLowerCase() === 'span' || leaf.nodeName.toLowerCase() === 'font')) { + while (leaf.firstChild) { + leaf.parentNode.insertBefore(leaf.firstChild, leaf); + } + removeNodes.push(leaf); + break; + } + } else if (compare === 0) { + self.clearCss(leaf, cmd); + if (!rootNode && leaf.nodeName.toLowerCase() === 'span') { + rootNode = leaf; + } + } else { // -1 + node = startNode; + found = false; + while (node) { + if (node.nodeType === GB.node.text) { + found = true; + break; + } + node = checkPreviousLeaf(node, leaf); + } + if (!found) { + self.clearCss(leaf, cmd); + if (!rootNode && leaf.nodeName.toLowerCase() === 'span') { + rootNode = leaf; + } + } + } + + leaf = leaf.lastChild; + } + + if (leaf.nodeType === GB.node.text && self.isTextVisible(leaf.nodeValue)) { + applyTextNodes.push(leaf); + } + + return leaf; + }, + checkPreviousLeaf = function (node, breakNode) { + var leaf; + while (!node.previousSibling) { + node = node.parentNode; + if (node === breakNode || node.nodeName.toLowerCase() === 'body') { + return null; + } + } + leaf = node.previousSibling; + while (leaf.lastChild) { + leaf = leaf.lastChild; + } + return leaf; + }, + checkInRange = function (range, source) { + return (typeof range.inRange !== 'undefined') ? range.inRange(source) : + (compareBoundaryPoints(range, 'StartToStart', source) < 1 + && compareBoundaryPoints(range, 'EndToEnd', source) > -1); + }, + checkNextLeaf = function (node) { + var leaf, inRange; + while (!node.nextSibling) { + node = node.parentNode; + + if (!node || node.nodeName.toLowerCase() === 'body') { + return null; + } + + rangeSelectNode(cursor, node); + inRange = checkInRange(cursor, endNodeRange); + if (inRange) { + inRange = checkInRange(cursor, startNodeRange); + if (!inRange) { + tailNodes.push(node); + } else { + headNodes.push(node); + } + } + + if (node === endNodeAncestor) { + return null; + } + } + + leaf = node.nextSibling; + if (leaf.nodeType === GB.node.text || !endNodeAncestor) { + return null; + } + + rangeSelectNode(cursor, leaf); + inRange = checkInRange(endNodeAncestorRange, cursor); + if (!inRange) { + return null; + } + + while (leaf.firstChild) { + leaf = leaf.firstChild; + } + + if (leaf.nodeType === GB.node.text) { + tailNodes = []; + return null; + } + return leaf; + }, + checkParentSpan = function (node) { + var len = spanNodes.length, i = 0; + for (; i < len; i++) { + if (spanNodes[i] === node) { + return true; + } + } + return false; + }; + + this.editAreaFocus(); + + backupRange = this.restoreRange(); + selectionType = this.getSelectionType(); + + if (this.W3CRange) { + range = this.doc; + } else { + range = (selectionType === GB.selection.none) ? this.doc : backupRange; + } + + try { + if (cmd === 'LineHeight') { + this.applyLineHeight(opt); + } else { + if (cmd === 'InsertOrderedList' || cmd === 'InsertUnOrderedList') { + if (checked !== true) { + range.execCommand(cmd, false, opt); + if (!GB.browser.msie) { + range = this.getRange(); + node = range.commonAncestorContainer; + found = isEmpty = false; + + if (node.nodeType === GB.node.element && node.lastChild && + node.lastChild.nodeName.toLowerCase() === 'br') { + node.lastChild.className = this.cheditor.bogusSpacerName; + isEmpty = true; + } + while (node) { + if (node.nodeName.toLowerCase() === 'ul' || node.nodeName.toLowerCase() === 'ol') { + found = true; + break; + } + node = node.parentNode; + } + + if (found) { + if (node.parentNode.nodeName.toLowerCase() === 'p' || + node.parentNode.nodeName.toLowerCase() === 'div') { + pNode = node.parentNode; + if (pNode.lastChild && pNode.lastChild.nodeName.toLowerCase() === 'br') { + pNode.removeChild(pNode.lastChild); + } + if (pNode.firstChild === node && pNode.lastChild === node) { + pNode.parentNode.insertBefore(node, pNode); + pNode.parentNode.removeChild(pNode); + this.placeCaretAt(node.lastChild, isEmpty); + } + } + } + } + } + cursor = this.getRange(); + pNode = this.W3CRange ? cursor.commonAncestorContainer : cursor.parentElement(); + if (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + while (pNode) { + if (pNode.nodeName.toLowerCase() === 'ol' || pNode.nodeName.toLowerCase() === 'ul') { + if (opt === 'desc' || opt === 'decimal') { + opt = ''; + } + pNode.style.listStyleType = opt; + break; + } + pNode = pNode.parentNode; + } + } else if (cmd === 'FontSize' || cmd === 'FontName' || cmd === 'ForeColor' || cmd === 'BackColor') { + if (cmd === 'ForeColor' || cmd === 'BackColor') { + opt = this.colorConvert(opt, 'hex'); + } else if (cmd === 'FontName' && opt === '맑은 고딕') { + opt += ', "Malgun Gothic"'; + } + + cmd = GB.fontStyle[cmd]; + + range = this.getRange(); + tempNodes = this.insertStartEndNode(range); + startNode = tempNodes.startNode; + endNode = tempNodes.endNode; + + cursor = this.createRange(); + startNodeRange = this.createRange(); + rangeSelectNode(startNodeRange, startNode); + + endNodeRange = this.createRange(); + endNodeAncestorRange = this.createRange(); + + if (!tempNodes.collapsed) { + tailNodes = []; + endNodeAncestor = null; + rangeSelectNode(endNodeRange, endNode); + node = endNode.parentNode; + + while (node && node.nodeName.toLowerCase() !== 'body') { + endNodeAncestor = node; + node = node.parentNode; + } + + if (endNodeAncestor) { + rangeSelectNode(endNodeAncestorRange, endNodeAncestor); + } + + node = endNode; + while (node) { + node = checkNextLeaf(node); + } + + for (i = 0; i < tailNodes.length; i++) { + this.clearCss(tailNodes[i], cmd); + } + + node = endNode; + while (node && node !== startNode) { + node = clearPreviousLeaf(node); + } + + if (headNodes.length) { + found = false; + node = startNode; + while (node) { + if (node.nodeType === GB.node.text) { + found = true; + break; + } + node = checkPreviousLeaf(node, endNodeAncestor); + } + if (!found) { + for (i = 0; i < headNodes.length; i++) { + self.clearCss(headNodes[i], cmd); + css = self.getCssValue(headNodes[i]); + if (!css && headNodes[i].nodeName.toLowerCase() === 'span') { + child = headNodes[i]; + while (child.firstChild) { + child.parentNode.insertBefore(child.firstChild, child); + } + child.parentNode.removeChild(child); + headNodes.splice(i); + } + } + } + } + + for (i = 0; i < removeNodes.length; i++) { + removeNodes[i].parentNode.removeChild(removeNodes[i]); + } + removeNodes = []; + + len = applyTextNodes.length; + if (rootNode) { + rangeSelectNode(startNodeRange, rootNode); + } + + for (i = 0; i < len; i++) { + tNode = applyTextNodes[i]; + + if (tNode.previousSibling && tNode.previousSibling.nodeType === GB.node.text) { + if (applyTextNodes[i + 1] && tNode.previousSibling === applyTextNodes[i + 1]) { + applyTextNodes[i + 1].nodeValue += tNode.nodeValue; + tNode.parentNode.removeChild(tNode); + } else { + tNode.nodeValue = tNode.previousSibling.nodeValue + tNode.nodeValue; + tNode.previousSibling.parentNode.removeChild(tNode.previousSibling); + i--; + } + continue; + } + + pNode = tNode.parentNode; + + if (rootNode) { + rangeSelectNode(cursor, pNode); + inRange = checkInRange(startNodeRange, cursor); + if (inRange) { + self.makeFontCss(cmd, '', pNode); + self.makeFontCss(cmd, opt, rootNode); + continue; + } + } + if (pNode.nodeName.toLowerCase() === 'span' + && (pNode.firstChild === tNode || pNode.firstChild === startNode) + && (pNode.lastChild === tNode || pNode.lastChild === endNode)) { + self.makeFontCss(cmd, opt, pNode); + spanNodes.push(pNode); + continue; + } + makeSpanText(tNode); + } + + len = spanNodes.length; + for (i = 0; i < len; i++) { + child = spanNodes[i]; + pNode = child.parentNode; + if (pNode.nodeName.toLowerCase() === 'span') { + if (checkParentSpan(pNode)) { + self.makeFontCss(cmd, '', child); + css = self.getCssValue(child); + if (!css) { + while (child.firstChild) { + pNode.insertBefore(child.firstChild, child); + } + pNode.removeChild(child); + continue; + } + } + while (pNode && pNode.nodeName.toLowerCase() === 'span') { + if (pNode.firstChild === child && pNode.lastChild === child) { + css = self.getCssValue(pNode); + if (css) { + self.makeFontCss(cmd, '', pNode); + css = self.getCssValue(pNode); + if (!css) { + pNode.parentNode.insertBefore(child, pNode); + pNode.parentNode.removeChild(pNode); + pNode = child; + continue; + } + } + } + pNode = pNode.parentNode; + } + } + } + + if (this.W3CRange) { + selection = this.getSelection(); + if (selection.rangeCount > 0) { + selection.removeAllRanges(); + } + range = this.createRange(); + range.setStartAfter(startNode); + range.setEndBefore(endNode); + selection.addRange(range); + } else { + startNodeRange = this.createRange(); + endNodeRange = startNodeRange.duplicate(); + startNodeRange.moveToElementText(startNode); + endNodeRange.moveToElementText(endNode); + startNodeRange.setEndPoint('StartToEnd', startNodeRange); + startNodeRange.setEndPoint('EndToStart', endNodeRange); + startNodeRange.select(); + } + } else { + pNode = startNode.parentNode; + found = false; + while (pNode && pNode.nodeName.toLowerCase() === 'span' && !found) { + css = self.getCssValue(pNode); + if (css) { + len = css.length; + for (i = 0; i < len; i++) { + if (css[i].name === cmd && css[i].value === opt) { + found = true; + break; + } + } + } + pNode = pNode.parentNode; + } + + if (!found) { + span = this.doc.createElement('span'); + this.makeFontCss(cmd, opt, span); + span.appendChild(zeroWidth); + endNode.parentNode.insertBefore(span, endNode); + + if (this.W3CRange) { + selection = this.getSelection(); + selection.collapse(zeroWidth, 1); + } else { + range = this.getRange(); + range.moveToElementText(span); + range.collapse(false); + range.select(); + } + } + } + this.removeStartEndNode(tempNodes); + } else { + range.execCommand(cmd, false, opt); + } + } + } catch (e) { + alert(e.toString()); + } + + this.toolbarUpdate(); + this.boxHideAll(); + }, + + modifyImage : function (img) { + var self = this, + idx, div, ico, inputCaption, wrapTextSpan, wrapTextCheckBox, wrapTextIcon, wrapTextChecked, + width = 0, height = 0, wrapElem, currentCaption = '', caption = null, inputAlt, inputTitle, cssFloat, + wrapperClassName = 'cheditor-caption-wrapper', + figureClassName = 'cheditor-caption', + figCaptionClassName = 'cheditor-caption-text', + imageWidthOpt = { + orig : { size: 'normal', desc: '원본 크기' }, + fitpage : { size: '100%', desc: '페이지 크기에 맞춤' }, + px160 : { size: 160, desc: '썸네일, 160 픽셀' }, + px320 : { size: 320, desc: '작은 크기, 320 픽셀' }, + px640 : { size: 640, desc: '중간 크기, 640 픽셀' }, + px1024 : { size: 1024, desc: '크게, 1024 픽셀' }, + px1600 : { size: 1600, desc: '아주 크게, 1600 픽셀' } + }, + captionAlignOpt = { left: '왼쪽', center: '가운데', right: '오른쪽' }, + imageFloatOpt = { + left : { + value : '왼쪽', + input : null + }, + right : { + value : '오른쪽', + input : null + } + }, + fmSelectWidth = document.createElement('select'), + fmSelectCaptionAlign = document.createElement('select'), + + onChangeEventHandler = function () { + if (self.editImages[img.src] && self.editImages[img.src].width) { + width = self.editImages[img.src].width; + if (self.editImages[img.src] && self.editImages[img.src].height) { + height = self.editImages[img.src].height; + } else { + height = img.height; + } + } else if (img.width) { + width = img.width; + } else { + return; + } + + switch (this.value) { + case 'orig' : + width = width + 'px'; + height = (height || img.height) + 'px'; + break; + case 'fitpage' : + width = '100%'; + height = 'auto'; + break; + default : + width = imageWidthOpt[this.value].size; + if (img.height) { + height = Math.round((img.height * width) / img.width) + 'px'; + } + width += 'px'; + } + + if (width) { + img.style.width = width; + if (caption && caption.figure) { + caption.figure.style.width = width; + } + } + if (height) { + img.style.height = height; + } + }, + setCssFloat = function (elem, css) { + if (typeof elem.style.styleFloat === 'undefined') { + elem.style.cssFloat = css; + } else { + elem.style.styleFloat = css; + } + }, + getCssFloat = function (elem) { + return (typeof elem.style.styleFloat === 'undefined') ? elem.style.cssFloat : elem.style.styleFloat; + }, + clearCssFloat = function (elem) { + setCssFloat(elem, ''); + elem.style.marginLeft = ''; + elem.style.marginRight = ''; + }, + createInputForm = function (type, name, value, classname) { + var input = document.createElement('input'); + input.setAttribute('type', type); + input.setAttribute('name', name); + input.setAttribute('value', value); + input.className = classname; + return input; + }, + applyWrapText = function (elem) { + if (!elem) { + return; + } + wrapElem = (caption && caption.wrapper) ? caption.wrapper : img; + if (elem.checked) { + imageFloatOpt[(elem.name === 'left' ? 'right' : 'left')].input.checked = false; + setCssFloat(wrapElem, elem.name); + if (elem.name === 'left') { + wrapElem.style.marginRight = '1em'; + wrapElem.style.marginLeft = ''; + } else { + wrapElem.style.marginLeft = '1em'; + wrapElem.style.marginRight = ''; + } + if (caption && caption.wrapper) { + clearCssFloat(img); + } + } else { + clearCssFloat(wrapElem); + } + }, + getCaptionNodes = function (img) { + var nodes = { figure: null, figCaption: [], captionText: '', img: null, wrapper: null}, + pNode, node; + pNode = img.parentNode; + if (!pNode || pNode.nodeName.toLowerCase() !== 'figure') { + return null; + } + nodes.figure = pNode; + nodes.figCaption = pNode.getElementsByTagName('figcaption'); + for (idx = 0; idx < nodes.figCaption.length; idx++) { + node = nodes.figCaption[idx].firstChild; + while (node) { + if (node.nodeType === GB.node.text) { + nodes.captionText += self.trimSpace(node.nodeValue); + } + node = node.nextSibling; + } + } + if (pNode.parentNode.nodeName.toLowerCase() === 'div' && pNode.parentNode.className === wrapperClassName) { + nodes.wrapper = pNode.parentNode; + } + nodes.img = img; + return nodes; + }, + applyAlt = function () { + var alt = self.trimSpace(inputAlt.value); + if (alt !== '') { + img.setAttribute('alt', alt); + } + self.removeEvent(inputAlt, 'blur', applyAlt); + self.cheditor.modifyState = false; + }, + applyTitle = function () { + var title = self.trimSpace(inputTitle.value); + if (title !== '') { + img.setAttribute('title', title); + } + self.removeEvent(inputTitle, 'blur', applyTitle); + self.cheditor.modifyState = false; + }, + applyCaption = function () { + var figure = self.doc.createElement('figure'), + figCaption = self.doc.createElement('figcaption'), + wrapper = self.doc.createElement('div'), + pNode = img.parentNode, i, para = self.doc.createElement('p'); + + self.removeEvent(inputCaption, 'blur', applyCaption); + + wrapper.className = wrapperClassName; + figure.className = figureClassName; + figCaption.className = figCaptionClassName; + + this.value = self.trimSpace(inputCaption.value); + if (!self.isTextVisible(this.value) && caption) { + caption.wrapper.parentNode.insertBefore(para, caption.wrapper); + para.appendChild(caption.img); + cssFloat = getCssFloat(caption.wrapper); + caption.wrapper.parentNode.removeChild(caption.wrapper); + caption = getCaptionNodes(img); + if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) { + applyWrapText(imageFloatOpt[cssFloat].input); + } + self.cheditor.modifyState = false; + return; + } + if (currentCaption === this.value) { + self.cheditor.modifyState = false; + return; + } + + if (caption && caption.figure) { + for (i = 0; i < caption.figCaption.length; i++) { + caption.figure.removeChild(caption.figCaption[i]); + } + figure = caption.figure; + } else { + if (pNode.nodeName.toLowerCase() !== 'body') { + pNode.parentNode.insertBefore(wrapper, pNode.nextSibling); + } else { + pNode.insertBefore(wrapper, img); + } + + if (self.config.imgCaptionWrapper !== '') { + wrapper.setAttribute('style', self.config.imgCaptionWrapper); + } + + wrapper.appendChild(figure); + figure.setAttribute('style', self.config.imgCaptionFigure); + figure.style.display = 'inline-block'; + figure.style.width = img.width; + figure.appendChild(img); + para.appendChild(self.createNbspTextNode()); + wrapper.parentNode.insertBefore(para, wrapper.nextSibling); + } + + figure.appendChild(figCaption); + figCaption.setAttribute('style', self.config.imgCaptionText); + figCaption.appendChild(self.doc.createTextNode(this.value)); + + if (!pNode.hasChildNodes()) { + pNode.parentNode.removeChild(pNode); + } + + caption = getCaptionNodes(img); + cssFloat = getCssFloat(img); + if (cssFloat && (cssFloat === 'left' || cssFloat === 'right')) { + applyWrapText(imageFloatOpt[cssFloat].input); + } + self.cheditor.modifyState = false; + }; + + for (idx in imageWidthOpt) { + if (imageWidthOpt.hasOwnProperty(idx)) { + fmSelectWidth.options[fmSelectWidth.options.length] = new Option(imageWidthOpt[idx].desc, idx); + } + } + + fmSelectWidth.onchange = onChangeEventHandler; + caption = getCaptionNodes(img); + + div = document.createElement('div'); + div.style.textAlign = 'left'; + ico = new Image(); + ico.src = this.config.iconPath + 'image_resize.png'; + ico.className = 'cheditor-ico'; + div.appendChild(ico); + div.appendChild(fmSelectWidth); + + wrapTextChecked = getCssFloat((caption && caption.wrapper) ? caption.wrapper : img); + + for (idx in imageFloatOpt) { + if (imageFloatOpt.hasOwnProperty(idx)) { + wrapTextCheckBox = createInputForm('checkbox', idx, '1', 'wrap-checked'); + wrapTextCheckBox.setAttribute('id', 'idWrapText-' + idx); + wrapTextCheckBox.onclick = function () { + applyWrapText(this); + }; + imageFloatOpt[idx].input = wrapTextCheckBox; + wrapTextSpan = document.createElement('span'); + wrapTextIcon = new Image(); + wrapTextSpan.className = 'wrap-text-desc'; + + if (idx === 'left') { + wrapTextSpan.style.marginLeft = '20px'; + } + if (wrapTextChecked === idx) { + wrapTextCheckBox.checked = 'checked'; + } + wrapTextSpan.appendChild(wrapTextCheckBox); + wrapTextIcon.className = 'cheditor-ico'; + wrapTextIcon.src = this.config.iconPath + 'image_align_' + idx + '_wt.png'; + wrapTextSpan.appendChild(wrapTextIcon); + div.appendChild(wrapTextSpan); + } + } + + if (self.undefined(self.editImages[img.src])) { + self.editImages[img.src] = { width: img.width, height: img.height }; + } + + div.appendChild(document.createTextNode('\u00a0\u00a0Alt:')); + inputAlt = createInputForm('text', 'inputAlt', '', 'user-input-alt'); + inputAlt.onfocus = function () { + self.cheditor.modifyState = true; + self.addEvent(inputAlt, 'blur', applyAlt); + }; + div.appendChild(inputAlt); + if (img.getAttribute('alt')) { + inputAlt.value = img.getAttribute('alt'); + } + + div.appendChild(document.createTextNode('타이틀:')); + inputTitle = createInputForm('text', 'inputTitle', '', 'user-input-alt'); + inputTitle.onfocus = function () { + self.cheditor.modifyState = true; + self.addEvent(inputTitle, 'blur', applyTitle); + }; + div.appendChild(inputTitle); + if (img.getAttribute('title')) { + inputTitle.value = img.getAttribute('title'); + } + + div.appendChild(document.createElement('br')); + div.appendChild(document.createTextNode('사진 캡션:')); + + inputCaption = createInputForm('text', 'inputCaption', '', 'user-input-caption'); + inputCaption.onfocus = function () { + caption = getCaptionNodes(img); + self.cheditor.modifyState = true; + self.addEvent(inputCaption, 'blur', applyCaption); + + }; + div.appendChild(inputCaption); + + div.appendChild(document.createTextNode('캡션 텍스트 정렬:')); + for (idx in captionAlignOpt) { + if (captionAlignOpt.hasOwnProperty(idx)) { + fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length] = new Option(captionAlignOpt[idx], idx); + if (caption && caption.figCaption[0] && caption.figCaption[0].style.textAlign) { + if (idx === caption.figCaption[0].style.textAlign) { + fmSelectCaptionAlign.options[fmSelectCaptionAlign.options.length - 1].selected = true; + } + } + } + } + + fmSelectCaptionAlign.className = 'caption-align'; + fmSelectCaptionAlign.onchange = function () { + caption = getCaptionNodes(img); + if (!caption) { + return; + } + for (idx = 0; idx < caption.figCaption.length; idx++) { + caption.figCaption[idx].style.textAlign = this.value; + } + }; + div.appendChild(fmSelectCaptionAlign); + + if (caption && caption.captionText) { + currentCaption = self.trimSpace(caption.captionText); + inputCaption.value = currentCaption; + } + + while (self.cheditor.editBlock.firstChild) { + self.cheditor.editBlock.removeChild(self.cheditor.editBlock.firstChild); + } + self.cheditor.editBlock.appendChild(div); + }, + + modifyCell : function (ctd) { + var self = this, + ctb = ctd, + ctr = ctb, + tm = [], i, jr, j, jh, jv, rowIndex = 0, realIndex = 0, newc, newr, nc, tempr, rows, span, icon, + div = document.createElement('div'), + + getCellMatrix = function () { + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + for (i = 0; i < rows.length; i++) { + tm[i] = []; + } + for (i = 0; i < rows.length; i++) { + jr = 0; + for (j = 0; j < rows[i].cells.length; j++) { + while (!(self.undefined(tm[i][jr]))) { + jr++; + } + for (jh = jr; jh < jr + (rows[i].cells[j].colSpan || 1); jh++) { + for (jv = i; jv < i + (rows[i].cells[j].rowSpan || 1); jv++) { + tm[jv][jh] = (jv === i) ? rows[i].cells[j].cellIndex : -1; + } + } + } + } + return tm; + }, + insertColumn = function () { + tm = getCellMatrix(); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + for (i = 0; i < rows.length; i++) { + if (tm[i][realIndex] !== -1) { + if (rows[i].cells[tm[i][realIndex]].colSpan > 1) { + rows[i].cells[tm[i][realIndex]].colSpan++; + } else { + newc = rows[i].insertCell(tm[i][realIndex] + 1); + nc = rows[i].cells[tm[i][realIndex]].cloneNode(false); + nc.innerHTML = ' '; + rows[i].replaceChild(nc, newc); + } + } + } + }, + insertRow = function (idx) { + newr = ctb.insertRow(ctr.rowIndex + 1); + for (i = 0; i < ctr.cells.length; i++) { + if (ctr.cells[i].rowSpan > 1) { + ctr.cells[i].rowSpan++; + } else { + newc = ctr.cells[i].cloneNode(false); + newc.innerHTML = ' '; + newr.appendChild(newc); + } + } + + for (i = 0; i < ctr.rowIndex; i++) { + if (ctb.rows && ctb.rows.length > 0) { + tempr = ctb.rows[i]; + } else { + tempr = ctb.getElementsByTagName('tr')[i]; + } + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (ctr.rowIndex - i)) { + tempr.cells[j].rowSpan++; + } + } + } + }, + deleteColumn = function () { + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; realIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + if (tm[0].length <= 1) { + ctb.parentNode.removeChild(ctb); + } else { + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + for (i = 0; i < rows.length; i++) { + if (tm[i][realIndex] !== -1) { + if (rows[i].cells[tm[i][realIndex]].colSpan > 1) { + rows[i].cells[tm[i][realIndex]].colSpan--; + } else { + rows[i].deleteCell(tm[i][realIndex]); + } + } + } + } + }, + deleteRow = function () { + var curCI = -1, prevCI, ni, nrCI, cs, nj; + + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + rowIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + if (rows.length <= 1) { + ctb.parentNode.removeChild(ctb); + } else { + for (i = 0; i < rowIndex; i++) { + tempr = rows[i]; + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (rowIndex - i)) { + tempr.cells[j].rowSpan--; + } + } + } + + for (i = 0; i < tm[rowIndex].length; i++) { + prevCI = curCI; + curCI = tm[rowIndex][i]; + + if (curCI !== -1 && curCI !== prevCI && ctr.cells[curCI].rowSpan > 1 && (rowIndex + 1) < rows.length) { + ni = i; + nrCI = tm[rowIndex + 1][ni]; + while (nrCI === -1) { + ni++; + nrCI = (ni < rows[rowIndex + 1].cells.length) ? tm[rowIndex + 1][ni] : rows[rowIndex + 1].cells.length; + } + + newc = rows[rowIndex + 1].insertCell(nrCI); + rows[rowIndex].cells[curCI].rowSpan--; + nc = rows[rowIndex].cells[curCI].cloneNode(false); + rows[rowIndex + 1].replaceChild(nc, newc); + + cs = (ctr.cells[curCI].colSpan > 1) ? ctr.cells[curCI].colSpan : 1; + nj = 0; + + for (j = i; j < (i + cs); j++) { + tm[rowIndex + 1][j] = nrCI; + nj = j; + } + for (j = nj; j < tm[rowIndex + 1].length; j++) { + if (tm[rowIndex + 1][j] !== -1) { + tm[rowIndex + 1][j]++; + } + } + } + } + + if (ctb.rows && ctb.rows.length > 0) { + ctb.deleteRow(rowIndex); + } else { + ctb.removeChild(rows[rowIndex]); + } + } + }, + mergeCellRight = function () { + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; realIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.cellIndex + 1 < ctr.cells.length) { + var ccrs = ctd.rowSpan || 1, + cccs = ctd.colSpan || 1, + ncrs = ctr.cells[ctd.cellIndex + 1].rowSpan || 1, + nccs = ctr.cells[ctd.cellIndex + 1].colSpan || 1, + html; + + j = realIndex; + + while (tm[rowIndex][j] === ctd.cellIndex) { + j++; + } + + if (tm[rowIndex][j] === ctd.cellIndex + 1) { + if (ccrs === ncrs) { + if (rows.length > 1) { + ctd.colSpan = cccs + nccs; + } + html = self.trimSpace(ctr.cells[ctd.cellIndex + 1].innerHTML); + html = html.replace(/^ /, ''); + ctd.innerHTML += html; + ctr.deleteCell(ctd.cellIndex + 1); + } + } + } + }, + mergeCellDown = function () { + var crealIndex = 0, + ccrs = ctd.rowSpan || 1, + cccs = ctd.colSpan || 1, + ncellIndex, html, ncrs, nccs; + + tm = getCellMatrix(ctb); + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('tr'); + rowIndex = 0; + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (i = 0; i < tm[rowIndex].length; i++) { + if (tm[rowIndex][i] === ctd.cellIndex) { + crealIndex = i; + break; + } + } + + if (rowIndex + ccrs < rows.length) { + ncellIndex = tm[rowIndex + ccrs][crealIndex]; + if (ncellIndex !== -1 && + (crealIndex === 0 || (crealIndex > 0 && + (tm[rowIndex + ccrs][crealIndex - 1] !== tm[rowIndex + ccrs][crealIndex])))) + { + ncrs = rows[rowIndex + ccrs].cells[ncellIndex].rowSpan || 1; + nccs = rows[rowIndex + ccrs].cells[ncellIndex].colSpan || 1; + if (cccs === nccs) { + html = self.trimSpace(rows[rowIndex + ccrs].cells[ncellIndex].innerHTML); + html = html.replace(/^ /, ''); + ctd.innerHTML += html; + rows[rowIndex + ccrs].deleteCell(ncellIndex); + ctd.rowSpan = ccrs + ncrs; + } + } + } + }, + splitCellVertical = function () { + var ri, cs; + tm = getCellMatrix(); + rowIndex = 0; realIndex = 0; + + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (ri = 0; ri < rows.length; ri++) { + if (rows[ri] === ctr) { + rowIndex = ri; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.colSpan > 1) { + newc = rows[rowIndex].insertCell(ctd.cellIndex + 1); + ctd.colSpan--; + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex].replaceChild(nc, newc); + ctd.colSpan = 1; + ctd.removeAttribute('colSpan'); + } else { + newc = rows[rowIndex].insertCell(ctd.cellIndex + 1); + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex].replaceChild(nc, newc); + for (i = 0; i < tm.length; i++) { + if (i !== rowIndex && tm[i][realIndex] !== -1) { + cs = (rows[i].cells[tm[i][realIndex]].colSpan > 1) ? rows[i].cells[tm[i][realIndex]].colSpan : 1; + rows[i].cells[tm[i][realIndex]].colSpan = cs + 1; + } + } + } + }, + splitCellHorizontal = function () { + var ni, rs; + tm = getCellMatrix(); + rowIndex = 0; realIndex = 0; + rows = (ctb.rows && ctb.rows.length > 0) ? ctb.rows : ctb.getElementsByTagName('TR'); + + if (ctr.rowIndex >= 0) { + rowIndex = ctr.rowIndex; + } else { + for (i = 0; i < rows.length; i++) { + if (rows[i] === ctr) { + rowIndex = i; + break; + } + } + } + + for (j = 0; j < tm[rowIndex].length; j++) { + if (tm[rowIndex][j] === ctd.cellIndex) { + realIndex = j; + break; + } + } + + if (ctd.rowSpan > 1) { + i = realIndex; + while (tm[rowIndex + 1][i] === -1) { + i++; + } + + ni = (i === tm[rowIndex + 1].length) ? rows[rowIndex + 1].cells.length : tm[rowIndex + 1][i]; + + newc = rows[rowIndex + 1].insertCell(ni); + ctd.rowSpan--; + + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex + 1].replaceChild(nc, newc); + ctd.rowSpan = 1; + } else { + if (ctb.rows && ctb.rows.length > 0) { + ctb.insertRow(rowIndex + 1); + } else { + if (rowIndex < (rows.length - 1)) { + ctb.insertBefore(document.createElement('TR'), rows[rowIndex + 1]); + } else { + ctb.appendChild(document.createElement('TR')); + } + } + for (i = 0; i < ctr.cells.length; i++) { + if (i !== ctd.cellIndex) { + rs = ctr.cells[i].rowSpan > 1 ? ctr.cells[i].rowSpan : 1; + ctr.cells[i].rowSpan = rs + 1; + } + } + + for (i = 0; i < rowIndex; i++) { + tempr = rows[i]; + for (j = 0; j < tempr.cells.length; j++) { + if (tempr.cells[j].rowSpan > (rowIndex - i)) { + tempr.cells[j].rowSpan++; + } + } + } + + newc = rows[rowIndex + 1].insertCell(0); + nc = ctd.cloneNode(false); + nc.innerHTML = ' '; + rows[rowIndex + 1].replaceChild(nc, newc); + } + }, + tblReflash = function () { + self.editAreaFocus(); self.doEditorEvent(); + }, + colorPickerEventHandler = function () { + GB.popupWindow.ColorPicker.argv = { + func: function (color) { + ctd.setAttribute('bgColor', color); + document.getElementById('fm_cell_bgcolor').value = color; + }, + selectedCell : ctd + }; + self.windowOpen('ColorPicker'); + }, + editSubmitEventHandler = function () { + var width = self.trimSpace(document.getElementById('fm_cell_width').value), + height = self.trimSpace(document.getElementById('fm_cell_height').value), + bgcolor = self.trimSpace(document.getElementById('fm_cell_bgcolor').value); + if (width) { + ctd.setAttribute('width', width); + } + if (height) { + ctd.setAttribute('height', height); + } + if (bgcolor) { + ctd.setAttribute('bgcolor', bgcolor); + } + }, + deleteSubmitEventHandler = function () { + ctb.parentNode.removeChild(ctb); + self.doEditorEvent(); + }, + funcs = { + add_cols_after: { icon: 'table_insert_column.png', title: '열 삽입', + func: function () { + insertColumn(ctd.cellIndex); tblReflash(); + }}, + add_rows_after: { icon: 'table_insert_row.png', title: '행 삽입', + func: function () { + insertRow(ctr.rowIndex); tblReflash(); + }}, + remove_cols: { icon: 'table_delete_column.png', title: '열 삭제', + func: function () { + deleteColumn(ctd.cellIndex); tblReflash(); + }}, + remove_rows: { icon: 'table_delete_row.png', title: '행 삭제', + func: function () { + deleteRow(); tblReflash(); + }}, + sp1: { icon: 'dot.gif' }, + merge_cell_right: { icon: 'table_join_row.png', title: '오른쪽 셀과 병합', + func: function () { + mergeCellRight(); tblReflash(); + }}, + merge_cell_down: { icon: 'table_join_column.png', title: '아래 셀과 병합', + func: function () { + mergeCellDown(); tblReflash(); + }}, + split_cell_v: { icon: 'table_split_row.png', title: '셀 열로 나누기', + func: function () { + splitCellVertical(); tblReflash(); + }}, + split_cell_h: { icon: 'table_split_column.png', title: '셀 행으로 나누기', + func: function () { + splitCellHorizontal(); tblReflash(); + }} + }, + attrFuncs = { + setWidth: { + txt: '가로폭', + id: 'fm_cell_width', + marginRight: '10px', + value: ctd.getAttribute('width') + }, + setHeight: { + txt: '세로폭', + id: 'fm_cell_height', + marginRight: '10px', + value: ctd.getAttribute('height') + }, + setBgcolor: { + txt: '배경색', + id: 'fm_cell_bgcolor', + marginRight: '2px', + value: ctd.getAttribute('bgcolor') + } + }, + deleteSubmit = new Image(), + spliter = document.createElement('div'), txt, input, + colorPicker = new Image(), + editSubmit = new Image(); + + + while (ctb && ctb.tagName.toLowerCase() !== 'table') { + ctb = ctb.parentNode; + } + while (ctr && ctr.tagName.toLowerCase() !== 'tr') { + ctr = ctr.parentNode; + } + + self.cheditor.editBlock.innerHTML = ''; + div.style.padding = '6px'; + + for (i in funcs) { + if (!funcs.hasOwnProperty(i)) { + continue; + } + span = document.createElement('span'); + icon = document.createElement('img'); + icon.src = self.config.iconPath + funcs[i].icon; + + if (i === 'sp1' || i === 'sp2') { + icon.className = 'edit-table-ico'; + } else { + icon.setAttribute('title', funcs[i].title); + icon.className = 'edit-table-ico'; + icon.setAttribute('alt', ''); + icon.onclick = funcs[i].func; + } + div.appendChild(span.appendChild(icon)); + } + + deleteSubmit.src = this.config.iconPath + 'delete_table.png'; + deleteSubmit.style.marginLeft = '22px'; + deleteSubmit.className = 'edit-table-ico'; + deleteSubmit.setAttribute('title', '테이블 삭제'); + deleteSubmit.onclick = deleteSubmitEventHandler; + div.appendChild(deleteSubmit); + + spliter.style.padding = '10px 0px 0px 0px'; + spliter.style.marginTop = '5px'; + spliter.style.borderTop = '1px solid #ccc'; + spliter.style.textAlign = 'center'; + + for (i in attrFuncs) { + if (!attrFuncs.hasOwnProperty(i)) { + continue; + } + txt = document.createTextNode(attrFuncs[i].txt + ' '); + spliter.appendChild(txt); + input = document.createElement('input'); + input.style.marginRight = attrFuncs[i].marginRight; + input.setAttribute('type', 'text'); + input.setAttribute('name', i); + input.setAttribute('id', attrFuncs[i].id); + input.setAttribute('size', 7); + input.setAttribute('value', attrFuncs[i].value || ''); + spliter.appendChild(input); + } + + colorPicker.src = this.config.iconPath + 'button/color_picker.gif'; + colorPicker.className = 'color-picker'; + colorPicker.onclick = colorPickerEventHandler; + spliter.appendChild(colorPicker); + + editSubmit.src = this.config.iconPath + 'button/edit_cell.gif'; + editSubmit.className = 'input-submit'; + editSubmit.style.verticalAlign = 'top'; + editSubmit.onclick = editSubmitEventHandler; + + spliter.appendChild(editSubmit); + div.appendChild(spliter); + self.cheditor.editBlock.appendChild(div); + }, + + doEditorEvent : function (evt) { + var self = this, + cmd = null, ancestors = [], node, el, pNode, range, sType, links, span, tag, remove, bText, + srcElement = evt.target || evt.srcElement, + block = self.cheditor.editBlock, + status = self.cheditor.tagPath, + linkOnClickEventHandler = function () { + if (bText) { + document.getElementById('removeSelected').style.display = 'inline'; + self.tagSelector(this.el); + } + }, + removeOnClickEventHandler = function () { + self.doc.execCommand('RemoveFormat', false, null); + remove.style.display = 'none'; + self.editAreaFocus(); + self.doEditorEvent(); + }; + + if (!this.undefined(srcElement) && srcElement.nodeType === GB.node.element) { + pNode = srcElement; + } else { + range = self.getRange(); + sType = self.getSelectionType(); + bText = sType === GB.selection.text; + + if (!self.W3CRange) { + switch (sType) { + case GB.selection.none : + case GB.selection.text : + pNode = range.parentElement(); + break; + case GB.selection.element : + pNode = range.item(0); + break; + default : + pNode = self.editArea.document.body; + } + } else { + pNode = range.commonAncestorContainer; + if (!range.collapsed && + range.startContainer === range.endContainer && + range.startOffset - range.endOffset < 2 && + range.startContainer.hasChildNodes()) + { + pNode = range.startContainer.childNodes[range.startOffset]; + } + while (pNode.nodeType === GB.node.text) { + pNode = pNode.parentNode; + } + } + } + + node = pNode; + while (pNode && pNode.nodeType === GB.node.element) { + if (pNode.tagName.toLowerCase() === 'body') { + break; + } + if (pNode.tagName.toLowerCase() === 'img') { + cmd = 'img'; break; + } + if (pNode.tagName.toLowerCase() === 'td' || pNode.tagName.toLowerCase() === 'th') { + cmd = 'cell'; break; + } + pNode = pNode.parentNode; + } + + if (!cmd) { + block.style.display = 'none'; + block.innerHTML = ''; + } else { + if (cmd === 'cell') { + block.style.display = 'block'; + self.modifyCell(pNode); + } + } + + if (self.config.showTagPath) { + while (node && node.nodeType === GB.node.element) { + ancestors.push(node); + if (node.tagName.toLowerCase() === 'body') { + break; + } + node = node.parentNode; + } + + status.innerHTML = ''; + status.appendChild(document.createTextNode(' ')); + el = ancestors.pop(); + + while (el) { + status.appendChild(document.createTextNode('<')); + tag = el.nodeName.toLowerCase(); + + links = document.createElement('a'); + links.el = el; + links.href = 'javascript:void%200'; + links.className = 'cheditor-tag-path-elem'; + links.title = el.style.cssText; + (function () { + links.onclick = linkOnClickEventHandler; + })(); + links.appendChild(document.createTextNode(tag)); + status.appendChild(links); + status.appendChild(document.createTextNode('> ')); + el = ancestors.pop(); + } + + if (bText) { + remove = document.createElement('a'); + remove.href = 'javascript:void%200'; + remove.id = 'removeSelected'; + remove.style.display = 'none'; + remove.className = 'cheditor-tag-path-elem'; + remove.style.color = '#cc3300'; + remove.appendChild(document.createTextNode('')); + (function () { + remove.onclick = removeOnClickEventHandler; + })(); + span = document.createElement('span'); + span.style.marginTop = '2px'; + span.appendChild(remove); + self.cheditor.tagPath.appendChild(span); + } + } + + self.toolbarUpdate(srcElement); + }, + + tagSelector : function (node) { + var rng, selection; + this.editAreaFocus(); + + if (this.W3CRange) { + selection = this.editArea.getSelection(); + if (this.undefined(selection)) { + return; + } + try { + rng = selection.getRangeAt(0); + } catch (e) { + return; + } + rng.selectNodeContents(node); + selection.removeAllRanges(); + selection.addRange(rng); + } else { + rng = this.doc.body.createTextRange(); + if (rng) { + rng.moveToElementText(node); + rng.select(); + } + } + }, + + getBrowser : function () { + return GB.browser; + }, + $ : function (id) { + return this.doc.getElementById(id); + } +}; + +(function () { + var dragWindow = { + obj: null, + init: function (o, oRoot, minX, maxX, minY, maxY) { + o.style.curser = 'default'; + o.onmousedown = dragWindow.start; + o.onmouseover = function () { + this.style.cursor = 'move'; + }; + o.hmode = true; + o.vmode = true; + o.root = (oRoot && oRoot !== null) ? oRoot : o; + o.transId = oRoot.id + '_Trans'; + + if (o.hmode && isNaN(parseInt(o.root.style.left, 10))) { + o.root.style.left = '0px'; + } + if (o.vmode && isNaN(parseInt(o.root.style.top, 10))) { + o.root.style.top = '0px'; + } + if (!o.hmode && isNaN(parseInt(o.root.style.right, 10))) { + o.root.style.right = '0px'; + } + if (!o.vmode && isNaN(parseInt(o.root.style.bottom, 10))) { + o.root.style.bottom = '0px'; + } + + o.minX = minX !== undefined ? minX : null; + o.minY = minY !== undefined ? minY : null; + o.maxX = maxX !== undefined ? maxX : null; + o.maxY = maxY !== undefined ? maxY : null; + o.root.onDragStart = new Function(); + o.root.onDragEnd = new Function(); + o.root.onDrag = new Function(); + }, + start: function (e) { + var o = dragWindow.obj = this, + dragTransBg = document.createElement('div'), + y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10), + x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10); + + e = dragWindow.fixEv(e); + o.root.onDragStart(x, y); + o.lastMouseX = e.clientX; + o.lastMouseY = e.clientY; + + document.onmousemove = dragWindow.drag; + document.onmouseup = dragWindow.end; + + if (o.root.lastChild.id === o.transId) { + return false; + } + + dragTransBg.className = 'cheditor-dragWindowTransparent'; + if (GB.browser.msie && GB.browser.version < 10) { + dragTransBg.style.filter = 'alpha(opacity=0)'; + } else { + dragTransBg.style.opacity = 0; + } + dragTransBg.id = o.transId; + dragTransBg.style.width = o.root.lastChild.firstChild.style.width; + dragTransBg.style.height = o.root.lastChild.firstChild.style.height; + o.root.appendChild(dragTransBg); + return false; + }, + drag: function (e) { + e = dragWindow.fixEv(e); + var o = dragWindow.obj, + ey = e.clientY, + ex = e.clientX, + y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10), + x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10), + nx, ny; + + nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1)); + ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1)); + + dragWindow.obj.root.style.left = nx + 'px'; + dragWindow.obj.root.style.top = ny + 'px'; + dragWindow.obj.lastMouseX = ex; + dragWindow.obj.lastMouseY = ey; + dragWindow.obj.root.onDrag(nx, ny); + return false; + }, + end: function () { + document.onmousemove = null; + document.onmouseup = null; + dragWindow.obj.root.onDragEnd(parseInt(dragWindow.obj.root.style[dragWindow.obj.hmode ? 'left' : 'right'], 10), + parseInt(dragWindow.obj.root.style[dragWindow.obj.vmode ? 'top' : 'bottom'], 10)); + + if (dragWindow.obj.root.lastChild.id === dragWindow.obj.transId) { + dragWindow.obj.root.removeChild(dragWindow.obj.root.lastChild); + } + dragWindow.obj = null; + }, + fixEv: function (e) { + if (e === undefined) { + e = window.event; + } + if (e.layerX === undefined) { + e.layerX = e.offsetX; + } + if (e.layerY === undefined) { + e.layerY = e.offsetY; + } + return e; + } + }; + GB.dragWindow = dragWindow; +})(); + +// -------------------------------------------------------------------------- +// W3C DOM Range +// + +// -------------------------------------------------------------------------- +// Table +// + +// -------------------------------------------------------------------------- +// Color Picker +// +(function () { + var colorDropper = { + images: {pad: [181, 101], sld: [16, 101], cross: [15, 15], arrow: [7, 11]}, + fetchElement: function (mixed) { + return typeof mixed === 'string' ? document.getElementById(mixed) : mixed; + }, + + addEvent: function (el, evnt, func) { + if (el.addEventListener) { + el.addEventListener(evnt, func, false); + } else if (el.attachEvent) { + el.attachEvent('on' + evnt, func); + } + }, + + fireEvent: function (el, evnt) { + if (!el) { + return; + } + var ev; + if (document.createEvent) { + ev = document.createEvent('HTMLEvents'); + ev.initEvent(evnt, true, true); + el.dispatchEvent(ev); + } else if (document.createEventObject) { + ev = document.createEventObject(); + el.fireEvent('on' + evnt, ev); + } else if (el['on' + evnt]) { + el['on' + evnt](); + } + }, + + getElementPos: function (e) { + var e1 = e, e2 = e, x = 0, y = 0; + if (e1.offsetParent) { + do { + x += e1.offsetLeft; + y += e1.offsetTop; + e1 = e1.offsetParent; + } while (e1); + } + + while (e2 && e2.nodeName.toLowerCase() !== 'body') { + x -= e2.scrollLeft; + y -= e2.scrollTop; + e2 = e2.parentNode; + } + return [x, y]; + }, + + getElementSize: function (e) { + return [e.offsetWidth, e.offsetHeight]; + }, + + getRelMousePos: function (e) { + var x = 0, y = 0; + if (!e) { + e = window.event; + } + if (typeof e.offsetX === 'number') { + x = e.offsetX; + y = e.offsetY; + } else if (typeof e.layerX === 'number') { + x = e.layerX; + y = e.layerY; + } + return {x: x, y: y}; + }, + + color: function (target, prop) { + this.required = true; + this.adjust = true; + this.hash = true; + this.caps = false; + this.valueElement = target; + this.styleElement = target; + this.onImmediateChange = null; + this.hsv = [0, 0, 1]; + this.rgb = [1, 1, 1]; + this.minH = 0; + this.maxH = 6; + this.minS = 0; + this.maxS = 1; + this.minV = 0; + this.maxV = 1; + + this.pickerOnfocus = true; + this.pickerMode = 'HSV'; + this.pickerFace = 3; + this.pickerFaceColor = '#fff'; + this.pickerInset = 1; + this.pickerInsetColor = '#999'; + this.pickerZIndex = 10003; + + var p, + self = this, + modeID = this.pickerMode.toLowerCase() === 'hvs' ? 1 : 0, + abortBlur = false, + valueElement = colorDropper.fetchElement(this.valueElement), styleElement = colorDropper.fetchElement(this.styleElement), + holdPad = false, holdSld = false, touchOffset = {}, + leaveValue = 1 << 0, leaveStyle = 1 << 1, leavePad = 1 << 2, leaveSld = 1 << 3, + updateFieldEventHandler = function () { + self.fromString(valueElement.value, leaveValue); + dispatchImmediateChange(); + }; + + colorDropper.addEvent(target, 'blur', function () { + if (!abortBlur) { + window.setTimeout(function () { + abortBlur || blurTarget(); + abortBlur = false; + }, 0); + } else { + abortBlur = false; + } + }); + + for (p in prop) { + if (prop.hasOwnProperty(p)) { + this[p] = prop[p]; + } + } + + this.hidePicker = function () { + if (isPickerOwner()) { + removePicker(); + } + }; + + this.showPicker = function () { + if (!isPickerOwner()) { + drawPicker(); + } + }; + + this.importColor = function () { + if (!valueElement) { + this.exportColor(); + } else { + if (!this.adjust) { + if (!this.fromString(valueElement.value, leaveValue)) { + styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage; + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + } + } else if (!this.required && /^\s*$/.test(valueElement.value)) { + valueElement.value = ''; + styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage; + styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor; + styleElement.style.color = styleElement.jscStyle.color; + this.exportColor(leaveValue | leaveStyle); + } else if (this.fromString(valueElement.value)) { + // ignore + } else { + this.exportColor(); + } + } + }; + + this.exportColor = function (flags) { + if (!(flags & leaveValue) && valueElement) { + var value = this.toString(); + if (this.caps) { + value = value.toUpperCase(); + } + if (this.hash) { + value = '#' + value; + } + valueElement.value = value; + } + if (!(flags & leaveStyle) && styleElement) { + styleElement.style.backgroundImage = 'none'; + styleElement.style.backgroundColor = '#' + this.toString(); + styleElement.style.color = 0.213 * this.rgb[0] + 0.715 * this.rgb[1] + 0.072 * this.rgb[2] < 0.5 ? '#FFF' : '#000'; + } + if (!(flags & leavePad) && isPickerOwner()) { + redrawPad(); + } + if (!(flags & leaveSld) && isPickerOwner()) { + redrawSld(); + } + }; + + this.fromHSV = function (h, s, v, flags) { + if (h) { + h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h)); + } + if (s) { + s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s)); + } + if (v) { + v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v)); + } + + this.rgb = this.HSV_RGB( + h === null ? this.hsv[0] : (this.hsv[0] = h), + s === null ? this.hsv[1] : (this.hsv[1] = s), + v === null ? this.hsv[2] : (this.hsv[2] = v) + ); + this.exportColor(flags); + }; + + this.fromRGB = function (r, g, b, flags) { + if (r) { + r = Math.max(0.0, Math.min(1.0, r)); + } + if (g) { + g = Math.max(0.0, Math.min(1.0, g)); + } + if (b) { + b = Math.max(0.0, Math.min(1.0, b)); + } + + var hsv = this.RGB_HSV( + r === null ? this.rgb[0] : r, + g === null ? this.rgb[1] : g, + b === null ? this.rgb[2] : b + ); + if (hsv[0] !== null) { + this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0])); + } + if (hsv[2] !== 0) { + this.hsv[1] = hsv[1] === null ? null : Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1])); + } + this.hsv[2] = hsv[2] === null ? null : Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2])); + + var rgb = this.HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]); + this.rgb[0] = rgb[0]; + this.rgb[1] = rgb[1]; + this.rgb[2] = rgb[2]; + + this.exportColor(flags); + }; + + this.fromString = function (hex, flags) { + var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i); + if (!m) { + return false; + } + if (m[1].length === 6) { + this.fromRGB( + parseInt(m[1].substr(0, 2), 16) / 255, + parseInt(m[1].substr(2, 2), 16) / 255, + parseInt(m[1].substr(4, 2), 16) / 255, + flags + ); + } else { + this.fromRGB( + parseInt(m[1].charAt(0) + m[1].charAt(0), 16) / 255, + parseInt(m[1].charAt(1) + m[1].charAt(1), 16) / 255, + parseInt(m[1].charAt(2) + m[1].charAt(2), 16) / 255, + flags + ); + } + return true; + }; + + this.toString = function () { + return ( + (0x100 | Math.round(255 * this.rgb[0])).toString(16).substr(1) + + (0x100 | Math.round(255 * this.rgb[1])).toString(16).substr(1) + + (0x100 | Math.round(255 * this.rgb[2])).toString(16).substr(1) + ); + }; + + this.RGB_HSV = function (r, g, b) { + var n = Math.min(Math.min(r, g), b), + v = Math.max(Math.max(r, g), b), + m = v - n, h; + + if (m === 0) { + return [null, 0, v]; + } + h = r === n ? 3 + (b - g) / m : (g === n ? 5 + (r - b) / m : 1 + (g - r) / m); + return [h === 6 ? 0 : h, m / v, v]; + }; + + this.HSV_RGB = function (h, s, v) { + if (h === null) { + return [v, v, v]; + } + var i = Math.floor(h), + f = i % 2 ? h - i : 1 - (h - i), + m = v * (1 - s), + n = v * (1 - s * f); + switch (i) { + case 6: + case 0: + return [v, n, m]; + case 1: + return [n, v, m]; + case 2: + return [m, v, n]; + case 3: + return [m, n, v]; + case 4: + return [n, m, v]; + case 5: + return [v, m, n]; + } + }; + + function removePicker() { + delete colorDropper.picker.owner; + colorDropper.picker.boxB.parentNode.removeChild(colorDropper.picker.boxB); + } + + function drawPicker() { + var touchMoveEventHandler = function (e) { + var event = { + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }; + if (holdPad || holdSld) { + holdPad && setPad(event); + holdSld && setSld(event); + dispatchImmediateChange(); + } + e.stopPropagation(); + e.preventDefault(); + }, + dims = getPickerDims(self), + padImg = modeID ? 'color_picker_hv.png' : 'color_picker_hs.png', + i, seg, segSize; + + if (!colorDropper.picker) { + colorDropper.picker = { + box: document.createElement('div'), + boxB: document.createElement('div'), + pad: document.createElement('div'), + padB: document.createElement('div'), + padM: document.createElement('div'), + sld: document.createElement('div'), + sldB: document.createElement('div'), + sldM: document.createElement('div') + }; + for (i = 0, segSize = 2; i < colorDropper.images.sld[1]; i += segSize) { + seg = document.createElement('div'); + seg.style.height = segSize + 'px'; + seg.style.fontSize = '1px'; + seg.style.lineHeight = '0px'; + colorDropper.picker.sld.appendChild(seg); + } + colorDropper.picker.sldB.appendChild(colorDropper.picker.sld); + colorDropper.picker.box.appendChild(colorDropper.picker.sldB); + colorDropper.picker.box.appendChild(colorDropper.picker.sldM); + colorDropper.picker.padB.appendChild(colorDropper.picker.pad); + colorDropper.picker.box.appendChild(colorDropper.picker.padB); + colorDropper.picker.box.appendChild(colorDropper.picker.padM); + colorDropper.picker.boxB.appendChild(colorDropper.picker.box); + } + + p = colorDropper.picker; + p.box.onmouseup = p.box.onmouseout = function () { + target.focus(); + }; + p.box.onmousedown = function () { + abortBlur = true; + }; + p.box.onmousemove = function (e) { + if (holdPad || holdSld) { + holdPad && setPad(e); + holdSld && setSld(e); + if (document.selection) { + document.selection.empty(); + } else if (window.getSelection) { + window.getSelection().removeAllRanges(); + } + dispatchImmediateChange(); + } + }; + + if ('ontouchstart' in window) { + p.box.removeEventListener('touchmove', touchMoveEventHandler, false); + p.box.addEventListener('touchmove', touchMoveEventHandler, false); + } + p.padM.onmouseup = p.padM.onmouseout = function () { + if (holdPad) { + holdPad = false; + colorDropper.fireEvent(valueElement, 'change'); + } + }; + p.padM.onmousedown = function (e) { + switch (modeID) { + case 0: + if (self.hsv[2] === 0) { + self.fromHSV(null, null, 1.0); + } + break; + case 1: + if (self.hsv[1] === 0) { + self.fromHSV(null, 1.0, null); + } + break; + } + holdSld = false; + holdPad = true; + setPad(e); + dispatchImmediateChange(); + }; + + if ('ontouchstart' in window) { + p.padM.addEventListener('touchstart', function (e) { + touchOffset = {'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top}; + this.onmousedown({ + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }); + }); + } + p.sldM.onmouseup = p.sldM.onmouseout = function () { + if (holdSld) { + holdSld = false; + colorDropper.fireEvent(valueElement, 'change'); + } + }; + p.sldM.onmousedown = function (e) { + holdPad = false; + holdSld = true; + setSld(e); + dispatchImmediateChange(); + }; + if ('ontouchstart' in window) { + p.sldM.addEventListener('touchstart', function (e) { + touchOffset = {'X': getOffsetParent(e.target).Left, 'Y': getOffsetParent(e.target).Top}; + this.onmousedown({ + 'offsetX': e.touches[0].pageX - touchOffset.X, + 'offsetY': e.touches[0].pageY - touchOffset.Y + }); + }); + } + + p.box.style.width = dims[0] + 'px'; + p.box.style.height = dims[1] + 'px'; + + p.boxB.style.position = 'relative'; + p.boxB.style.clear = 'both'; + p.boxB.style.border = 'none'; + p.boxB.style.background = self.pickerFaceColor; + + p.pad.style.width = colorDropper.images.pad[0] + 'px'; + p.pad.style.height = colorDropper.images.pad[1] + 'px'; + + p.padB.style.position = 'absolute'; + p.padB.style.left = self.pickerFace + 'px'; + p.padB.style.top = self.pickerFace + 'px'; + p.padB.style.border = self.pickerInset + 'px solid'; + p.padB.style.borderColor = self.pickerInsetColor; + + p.padM.style.position = 'absolute'; + p.padM.style.left = '0'; + p.padM.style.top = '0'; + p.padM.style.width = self.pickerFace + 2 * self.pickerInset + colorDropper.images.pad[0] + colorDropper.images.arrow[0] + 'px'; + p.padM.style.height = p.box.style.height; + p.padM.style.cursor = 'crosshair'; + + p.sld.style.overflow = 'hidden'; + p.sld.style.width = '13px'; + p.sld.style.height = colorDropper.images.sld[1] + 'px'; + + p.sldB.style.position = 'absolute'; + p.sldB.style.right = self.pickerFace + 'px'; + p.sldB.style.top = self.pickerFace + 'px'; + p.sldB.style.border = self.pickerInset + 'px solid'; + p.sldB.style.borderColor = self.pickerInsetColor; + + p.sldM.style.position = 'absolute'; + p.sldM.style.right = '0'; + p.sldM.style.top = '0'; + p.sldM.style.width = 14 + colorDropper.images.arrow[0] + self.pickerFace + 2 * self.pickerInset + 'px'; + p.sldM.style.height = p.box.style.height; + + try { + p.sldM.style.cursor = 'pointer'; + } catch (e) { + p.sldM.style.cursor = 'hand'; + } + + p.padM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_cross.gif")'; + p.padM.style.backgroundRepeat = 'no-repeat'; + p.sldM.style.backgroundImage = 'url("' + self.iconDir + '/color_picker_arrow.gif")'; + p.sldM.style.backgroundRepeat = 'no-repeat'; + p.pad.style.backgroundImage = 'url("' + self.iconDir + '/' + padImg + '")'; + p.pad.style.backgroundRepeat = 'no-repeat'; + p.pad.style.backgroundPosition = '0 0'; + redrawPad(); + redrawSld(); + colorDropper.picker.owner = self; + target.parentNode.parentNode.appendChild(p.boxB); + } + + function getPickerDims(o) { + return [2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[0] + + 2 * o.pickerInset + 2 * colorDropper.images.arrow[0] + colorDropper.images.sld[0], + 2 * o.pickerInset + 2 * o.pickerFace + colorDropper.images.pad[1]]; + } + + function redrawPad() { + var yComponent, x, y, i = 0, rgb, s, c, f, + seg = colorDropper.picker.sld.childNodes; + + switch (modeID) { + case 0: + yComponent = 1; + break; + case 1: + yComponent = 2; + break; + } + x = Math.round((self.hsv[0] / 6) * (colorDropper.images.pad[0] - 1)); + y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.pad[1] - 1)); + colorDropper.picker.padM.style.backgroundPosition = + (self.pickerFace + self.pickerInset + x - Math.floor(colorDropper.images.cross[0] / 2)) + 'px ' + + (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.cross[1] / 2)) + 'px'; + + switch (modeID) { + case 0: + rgb = self.HSV_RGB(self.hsv[0], self.hsv[1], 1); + if (window.File && window.FileReader) { + colorDropper.picker.sld.style.background = 'linear-gradient(rgb(' + + (rgb[0] * (1 - i / seg.length) * 100) + '%,' + + (rgb[1] * (1 - i / seg.length) * 100) + '%,' + + (rgb[2] * (1 - i / seg.length) * 100) + '%), black)'; + } else { + for (i = 0; i < seg.length; i += 1) { + seg[i].style.backgroundColor = 'rgb(' + + (rgb[0] * (1 - i / seg.length) * 100) + '%,' + + (rgb[1] * (1 - i / seg.length) * 100) + '%,' + + (rgb[2] * (1 - i / seg.length) * 100) + '%)'; + } + } + break; + case 1: + c = [self.hsv[2], 0, 0]; + i = Math.floor(self.hsv[0]); + f = i % 2 ? self.hsv[0] - i : 1 - (self.hsv[0] - i); + switch (i) { + case 6: + case 0: + rgb = [0, 1, 2]; + break; + case 1: + rgb = [1, 0, 2]; + break; + case 2: + rgb = [2, 0, 1]; + break; + case 3: + rgb = [2, 1, 0]; + break; + case 4: + rgb = [1, 2, 0]; + break; + case 5: + rgb = [0, 2, 1]; + break; + } + + for (i = 0; i < seg.length; i += 1) { + s = 1 - 1 / (seg.length - 1) * i; + c[1] = c[0] * (1 - s * f); + c[2] = c[0] * (1 - s); + seg[i].style.backgroundColor = 'rgb(' + + (c[rgb[0]] * 100) + '%,' + + (c[rgb[1]] * 100) + '%,' + + (c[rgb[2]] * 100) + '%)'; + } + break; + } + } + + function getOffsetParent(el) { + var parent = el.offsetParent, top = 0, left = 0; + while (parent) { + top += parent.offsetTop; + left += parent.offsetLeft; + parent = parent.offsetParent; + } + return {Left: left, Top: top}; + } + + function redrawSld() { + var yComponent, y; + switch (modeID) { + case 0: + yComponent = 2; + break; + case 1: + yComponent = 1; + break; + } + y = Math.round((1 - self.hsv[yComponent]) * (colorDropper.images.sld[1] - 1)); + colorDropper.picker.sldM.style.backgroundPosition = + '0 ' + (self.pickerFace + self.pickerInset + y - Math.floor(colorDropper.images.arrow[1] / 2)) + 'px'; + } + + function isPickerOwner() { + return colorDropper.picker && colorDropper.picker.owner === self; + } + + function blurTarget() { + if (valueElement === target) { + self.importColor(); + } + } + + function blurValue() { + if (valueElement !== target) { + self.importColor(); + } + } + + function setPad(e) { + var mpos = colorDropper.getRelMousePos(e), + x = mpos.x - self.pickerFace - self.pickerInset, + y = mpos.y - self.pickerFace - self.pickerInset; + switch (modeID) { + case 0: + self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), 1 - y / (colorDropper.images.pad[1] - 1), null, leaveSld); + break; + case 1: + self.fromHSV(x * (6 / (colorDropper.images.pad[0] - 1)), null, 1 - y / (colorDropper.images.pad[1] - 1), leaveSld); + break; + } + } + + function setSld(e) { + var mpos = colorDropper.getRelMousePos(e), + y = mpos.y - self.pickerFace - self.pickerInset; + switch (modeID) { + case 0: + self.fromHSV(null, null, 1 - y / (colorDropper.images.sld[1] - 1), leavePad); + break; + case 1: + self.fromHSV(null, 1 - y / (colorDropper.images.sld[1] - 1), null, leavePad); + break; + } + } + + function dispatchImmediateChange() { + if (self.onImmediateChange) { + var callback; + if (typeof self.onImmediateChange === 'string') { + callback = new Function(self.onImmediateChange); + } else { + callback = self.onImmediateChange; + } + callback.call(self); + } + } + + if (valueElement) { + colorDropper.addEvent(valueElement, 'keyup', updateFieldEventHandler); + colorDropper.addEvent(valueElement, 'input', updateFieldEventHandler); + colorDropper.addEvent(valueElement, 'blur', blurValue); + valueElement.setAttribute('autocomplete', 'off'); + } + + this.importColor(); + } + }; + GB.colorDropper = colorDropper.color; +})(); diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.eot b/AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.eot new file mode 100644 index 0000000000000000000000000000000000000000..2388fa2d76bdde454f2c1859d3f5621a49878bb0 GIT binary patch literal 83743 zcmb4qWl$VJyY()+xGnCmxVuYmcXxMpx8Uw98r6!U6)79Nn3P8Y|91wu;uYdsn00KH9DhLchKmY>)cffxHKvnY>0ssmU z`X~6`qZA0R{7)!NS?m12)c>j206G8KE90Y3jU9su`$89V?E02hG!-zf^v{O1q-7ypO( zPZ0$;{!{t>>+L^U|Nqy<0T2T4{cCmm=j!s$?>`#*e_5{oT&@4>$o~%s0C@kYxc=1u z!2j=^|9b;E3Y!1t(f=EQ5IFXLlqf(-3?Ql}{@hv0REVp?w3CmYZ(JaQ&v_Z&TRshr z)6eO$2x}s;PUv-vv^8~EDfjMp6v;wDjB1m6W9|yfe#sR$M3J=WS9;E>xU|?Em>M{6 zbuUW0!qnC2jh_MZi$k71u{l4;l*-+&7Fz?0i?BVDzJAU7oX5vGoST&&);krn$FJJ= z`9o}qZnNCzLaK7^;H08LVY;|TxYw4cB>Hw;z>k>Efixkou^S9bBIAx9!P(~v+^Wtk zZS$EHL+V?|fux`9c1;d5q@8Pkt%k%}e@Dey3YvE#5~dqTg<>12IVu2~Qa=3m4;!!G z=ntw5AC6>!uZMSp&$s8u#OWn{pMJx@{Y3Bhzh4M9mF7bpkD(BCoOLAHmx6+Aw&g#Q zmeMwg>1IesG+LqJ4wr?vGIBn`-dsXtt*={kU~+#kL^RHrIK;>pU+_h(3p0L=ST`p| zmtgP8@rcNT=R)o6}p|8?>xh&d8-dcw{!Oi@a%+2x9 z78CXEOb}gfEG)D_L^_!vz?cH`seW}lWqGwSRnVMDp;FZ4-BU?zGo)&%&t^so@(r)E zKgTJ5Q|a4nnWRLSvsjQWg-kRDz22G?RlsDn=JQR*8zRG_RW17K$)lI6Et^Q0+l0trg3ATJcl5 zPY9){*_16cxZ-*Ulw2C6N5}&G8Kz87<&R&7fB%sM-2nE&pF22AzJ*tcv97}z?by9{)~j)uS6Kj4v1X2H!!z;6i^PyykM4I{O}$FlSalm~@YrhSx2@>h_dSah?up zV!E+%e1i_(&MZZ^OoK(V{`6+D#FK^pg6fe$o1!V$79WDRM8Zx@_4DR7gPJmZ!DgB$ zduBXuJ5CE8#mf?oyE4+`B-^ZV(Aiy#h!>zAc)LH5bZQMJJwejBPN?Et$0#F&(~du|IJ{z52>jqf%7E-7a{nGBp1B=s4W`gg zv@z7t2tO*-tG+6oHxTG@x$lr+BYBHGjvb$&Bqek|e0@VE_84EU;8lxEtSANnC2>3t zpV$fHS{YvG)4(Q<_qJ4W#7;zma@RKrgRtC?Sep9`34+ znOQ}MG*y~(S%e@NwLt#{zlBg2FZ?$Zq%LVCNg=SH~p8QR@ znMP`P+X6X7gwBMeBCsbIm%%zkUH1(t&!myzH~B6k!EmLMrB*i#-G%nm8i08!n%3ZD zTK+XVySdke60hG*PdS2PteJyW4fye9=dnb+8~=T>4NLLQZ;buuhe~>r?E^HCXtIC7fk+<~NImi?CUBmV{ic5%H zUw4KRX|AF~?(H{K|B5#sXxL|59GLNuD_5dG)W+eCWi@BF)8WZ}v^qF?Jo zKUC&2wrs)CZMc$9GNeOTjud41em+q&dG1b|bPF25H2$h)^6dPwxsa?}9J7KavGcX= zFBIwAa%Q@MRSJ^{wrOGEB4pxP3)K;)>&7(m{hto?>zJhCKk#gXJ9`-eRtX3pJ{Acr zfn@q1_B^!DCKeyQ@LSuB}LIXP_#P#~s5;W<{4j}cDq>vJG^ z1MrB0QjGQYSc-5K=_3Mp>u8FDE!N$=^5kqy=~wi}`T6%=VbI20_Yd~S1v6MvM9~~v za407m2<ovbC|ODfS-0k?XXpM)J^XfksckpB#Z>*Kanhb)Zpq4 z((g3g5Ym#tWwSSgzVu={5_oiaT>zviB&0PV@{gQghH@J8-|w4`JcO-yLDcE+5QMU? zW8`rLRKZT4)P7isW*`(?CH3MTKboo|CwH6E86ZNlr09?Hp zr99cLuNlRmY?95SDjOskY#jMcHUJdacK_xG zY{34R0-|zVrTrHUR&wVN&f^=;I3EZ$%jRpK669ifP^DD^Tm#56p9riiRi3vd)KM(? zU@@@$n;ulYO#Wl4JaO7eFL_9&W##pZ8NIX9UnbPkG%r?sKF|H31HtS!;e63T{$DYd z@V6wAg+Mh4x(wj>vm0moB?*)ztT4bynB5*;xyofj4&73*3I>2IM3;I&(iX1BiF|XG zLiaZ-nI>N#SO+C3goV2tsr<&0$cBy4qb&%x9c$=JaSS+Defm6RHb4}d+oi`3v$V;%Y5QbA+R^5DJ2m3g)Bfkh?8 ziJAwoUS|Rn`_%^4k4tjt(k<5&{a-wUW_?}0)_2V!5lz3TuUw*ow{~UBu)^?2=YNM> z9P`vuQWlJ9^3Gv7E2*s{+iAo5_=-9<3Fa)Z8faw+R+rt;LJPw?H)}=m(*$$(v8;ZN zDaIIlM-Q|>`?M%PM$7P~_-M#4nR?DFw_5NQboBR6-xL4bTG7tOBXQ&x)*UaDJB0)! zfd^5EgXGI@+xOr{IT3Bx_h-r?8R66^w$23{T=63-MXAPjHBZY}(59RrJW^9V zxy`Ha2j}CKF-!89Pb?0Y7twU5Uim9wOZ>AO4brCByKU>AI1>^1MQ~N~RX*p94TC!$ z=67=JNE0t|OTX&r=JKj;*wb)q?d1ri5N&K~WlPX0{Xoqn2*L73zE4aZz<%UA5h-r% z{=Kq&qbtp(s$cwrMvh8}e;W-VHN{&JAt;GaI+cKl^ZB@kGHON`Tvd!NW9HhFqF!nn zqqwSJS57ca7Xg+Tv;U13XzHNdw{Zvi-00-2`;k$urV{EnR2}ktL2E6KHcquhu`=UU z{GguATu;hKZ_v5#y7=?OtOuuPn<2eA;a?EB7Ue6Qf%uD0tm136eUp7k@npO3J z)VSFt7L>tV2peb-4~|9|-^{Wg?B05knDw0vU6C|FQ{8grhN@cKxNa9TH+^V4b&Owk&o}3NA z*JL{}f@|Cy)$t*BqAhvO{02*hW&1l5;--4ANu6^=uOkfrHEWLtU9vN}JiZfgl5mxW zey$}Kn;yRtZwsmkPP(DXgL0Zh#OvcsiPV;xOG>j8Y4=xqRr80VM(G51r~WaHt|}#+ zYe;;y;!cu+kV6gYDl)ZzM0LzftdBnDqJdoNqRx{;#}F~M+9qA){s8oob(u^jQdy^1 zP-`27TPkatg!Tr0LyuzQHrd$o-pn$8smx2id6lX&Unw|48aFBA2Zbz$j4 z)(pRNQ}R;xGbjXzRST*@iH@aUbPhV?e^{G%Yf7vM*40leRSnn%>2R7Zg&-lMSZlrj z2Oh31)U?_7OBIB6bD3DaLg1-K?O(r!R88!P#a6D)qhy5+J|RM8I1t07o|?ZIRb%xa zd7fn;k97afnKV)V{5xD%IpQ1R2X;#Op|{$t<#|kFh3h6w`cgvEr!9J@NSl>(abp|k zTR*4|wcB84-dAhFPTqr0?VtG{O^lHGXiR5-K}oMV;&s|>3fUV@oYMjp)8EaTkoSXu zT7raM$Zn2&R%gylAB%d}?j;dBc;D(EZmxi^Ht^~pBrsS&ZGDtMU`NQgV+4Gd8(sQIBBujA`ayE^OAU5$#ZWyHUri}d=8oO$D4=N|N1Il) zldh6d1E4rU2Ii{7#->(yWP?++6~11BK@t?~+@T@x^r7#7R^${qK~Z?}#s#vwf-0~8 z-|`$@0WiLC$9O^eklMq}vWlwfEQS!{Yx$$js=q->AGJLxV=hG}n$J1{6)U+SuZW;G z$5S0S9z03b#v&?gsS*)<5YSmY8o{)R_oh!*(P>|cl0+BB@-!hCXibBHkbnYx5|dLN z5|TQ5T|`)6NFZdP6*)_aOC+;&~<^J638W-*v)D&ZUR8OF+PG?47Fkd|%=Z;fpAltw`L9T_@VKTY4}edXuZye3YX#ho3=w%%YNC!mE1yr-PZy2r;=S z3QS}hwaYO89@V){(AP#y{9!mMw1%0C^||-~`D61i(B>OHk(ONZjRLWapZ|pb+kkW! zyM_(EUE*ix4`%sad$@m8(jK})*ENlBtk2a|2z#^e@FKdnjB>ga8T zop11cX4o}<_i%(ehOrZ}rg(m-{G2rjqXLaNkaWHzQND%(uR)$R$5yh#0!1#rWA&Gi zJ85e<8w=AEY2pEOC!B!^#@Gw{ZC$m-;(WpuSXCvj^a8swD9ir~2|;<_u5DZO>;$wc zT10Vcis7D$c4*x!O)!q^$_{kbAj3=PP|g@}`63DlMc|5yYe)h1lS0<*!CCye+-)C+ ze|uEjZkYSWyyCmE1}tTN@@-{pINQH6>g4}wh#Z| zaGy=^viA9gOJTJn-W}+rCGZmrQd|PUrMY|;iVV5l$9m#zqvD}WMAVbK;o2|4Rnj96 zl7)IhCdvn%zpVnL4ov2+(B|HXJs0@xrMGQirN-(c(QjGyD3KH|MfE1? zm#6IuCcBxbwBKrTHWsBq(s)3p$~$vcCjlle_bvMUXtr$QW1UtVF3$ zLOh$p6-BPlG-YPB#Y502$<$N=6=2hLfG5`%k=yyP5fbe|KX0k_Dq#zX{a{ALp+OzO-NV8r7|e-+DlxGaq9I&78Ayu)tCmmVA|F9Lt+0 z#U3jh5YV30&D#}x!tGp8&Grf5_h=YK-!%>yeM;0);*_1S@{=QVSs%i0sV3A`3&bis z%^3P2N4*E4-zzQppO4%iGMQ-tpX;3(+%dJIp+^)O`*}zUK|Z&1{2ymrJ>>k2kd2ORuAwfzFUZP>g%+3X+s3z*dvojH~lY` z_AA?!vkWptz+9AIDZ9+AEtTuNCtI@gmCyz^UW4<55sxlYb0e|>sk4PuMXI^6(MuWs zU21*TuM5Fw8N`VWjM~j*(Rgq&yt5TpP}8x&Rj;_1YS%4aSXNkwLuyD1HH+e0_Y}*~ z)EZ%5%%<};f}jf)QIrs`K^77ck{{sfwz8`BdELK(9SnXemzal`#T+6UX1`SMFS5ug z17Z5M`oVaT(R;O9S_@emO2NfZr1HXATIuQVB zS9?}(VRbivMN$+Qf~<#>5tOWb)4Av3?z+> zHU$EJeC>+9PJVsk9iqFc`bU6rcevhOu^y)9Lt#8(%oPPsk0Ef?!(dO(_BHB>N!Pi8 z71%N}%KB6gNoSH}bxkGblBehcZM<(oa_=$#n_klVQhNtW)DWE{#9N|j_VQ$&Cx@Og zb}#BWkOG`9c03=t$CrUt*J29!q?D)|;BSc72*r|_#)gJth%iLls8q72^y-J|6^)Gd z{izZVaRS@H31M!N+12N~PsoFR3g=ZALnn+}M~8Hh)#v*IcIn?5Au({4qdAv`Frj& zup#S@+{+SmEb&;LQPP?Z^DL#v+Tk|JYQqy^7x;*_BNAfSqv&s}Wg3rUgs zMa=X3+k-zeqp$rw@3AqQfx(ka>v(aG7w9<5_i2t*KrKe*Lbd`^!K_RBYM1GR^3&9w(81+{wwtQr&6@}*g@R0$>r(s0VT&et(gr^g7s z<)2qtwfl_6f2tEy9tN^1zyb0pJ8i;-a6hmP z|5nAI(2JEG1g!V8z&Ic4cKc`$`YitA#C7wQ@{diZxGL-|M^6nEf)gkOchlS!4N1|^ z|6tr!$Pm|Pputb#)zX$=bZ5o7Ofv{nvqn~Tw+r~Br)<*@u7sBLTlI#xidS5emqUcO z4no2JPAAx5RNmkBUaRbENbFv$sM&PqwR4+)JoNrZ;*kj)`x#8AA15K_l(^Tlx2Df< z&PwB%lbts$KV8khm!VwjWDZV2f=%+L%29!1RNPBV^q5ihtLrK^H4m-m`DG7w)zRKj z4AjhXDlIOLfmts$Xbv}&UfDHbr1!RE2o7(a!!R40UKkP&oL&{_rxP>igpHRk862XZ z;n4HFQA(cP@(P`NS;ihqf&A=1`8X{sZ|1M#4B8wbM}*j#Ij0ppIxJ=^e09!=XvzY= zyEo-=_Btru2c_^Kwasz#VdB(KBi+B!Qej7F{FN1~0CSvdfnSm^`7g9vKmbeYjvEK{ z?BI+g56P_*8PzSVGwqsOCl#>L2QK{aj5XuE_SH3zvshWX`X>xrah}+JW9XLx)%#u5 zarCr7?nNw9KMlRJDV<5msROshb^i1$LJ$j>NYV7loM-VJV792yx@v3y7c^bBd95{FmfM0VcB z)bt`vz^*;-TJ=5e+OufE0wI@$V7dH~h&tFk;gokMxcf4^ z+J8U{V>P4I@5RPC$Sk>-^!T#dmu=-0o02vWGrjSp_}jDIGpu3l5N;~3q zp%~t@Em~FEKrnKdS+x|j87gSX&&&Tr9AVthl$ZIJIp^;eXk`p%DE~c1C4xmaC6QoV z#N&K`p3qF^9YExSw^hlJ*2Xf7BVy~71{DtnN zI#3l>jZ^#8u_XV+JV^Fw-Z0dI2u! zXcOa7;Yvf)7sy0WJwRvf(M!>*$OsrPR2XD~T|0>auo9=7OT^-P7 z*7D5@s#4F=VBmd>$ctNDCW}KEM?ey^C-e5E__1%UStFc+IxP-sX5vZyG_P8&>fZHO=x6 zUKH&W_-oH@9Ml#1T^c3}jmE({2yPdVWDru%h_%cEGD-XUc)yxCS%Pg55|AyFNrNRG7BIS%f@-y|oAwB@Dh3qjj?7S>sgetWJ&>g$dX$%)~o=n1erX`tyI_KQ=dMfA-?bM!k1A>((duoiiVc6$2{nQNe?&<)88)1)`{ z=hI~P{-|tI-uaW<8+XfJu_y{%L#cW%5A4w;@&sIEK8)%i2!tQ|4d^aDvYFZo9G zrSeMZR0U^A-kb*LzxNYNmXEn;5G@-ocbS*&FqTnlF@frwB6OMEqL?_7rpS_`EJ$36OIS2Hv(4XSpbS*6?H{KiN){>o5(n}D z>g(KaBPC0o=^5zvpOrG7tTX+{?@IXm>;|xy5iGZ5T2-oII~qGAUviOh z>A9;(L&;wEb}Eq#UX-neoZYrq7otBsQ#YaKTGpc`{)O9*0YB7oBwT`GQM_OP5fikh zgWHPm4y6jsRhWyRE~X1di$5aiESqK)>8-+updLtbA`H3LOQS>*wdYeNuenAPwTP!~ zBn@+1S<``#nK*2ivBU|Ngg}hyMl=|9qd}KJ=ZRB3sF;#J14F5Fhw;moN=*|<6{vmh zr6>DrbDj{ziV=r_MJ!^9gb6W>98Swt?M0lo%C)BY4gItaDv4osE~`$6*yX{^MqyKe z-h-oAD=?Y?)a~4%pCUj1u3B|RZusrbw-A?s~+e^Jd>P)9#aV*>b-I{hK*Vk1@hc+{c$=$CK3=BHx#ZIYMJBY>eDJUm^e1 zsNZ|3ze4Y(e*~~Icqo}}b->aKtu<|U23J!vkBtq74Vhv{d-2ZA7Lmm zQTeF40Is%RrZg(|O^7CrU(#@sp?J{r&fKR4y{r1bz^ipu6ekkX;w5iu&Sjb!tNMZ| z(!VXI0vIf+s3o=lVRLHMuuXGCm?NJ{pq67WNVdY`dWp66@Jv@>SlE(gwCHp2D zyzgWiM~CJ{(m~=-?7zgI1L|m$jUh7}r>LMIWT6~=C)SWOh6K;$6+em?5Zw_0^c(d8 zCI;>&f+cWV{>h_@2tIPTP=dy!78!XPv~OC1iFg>Azq_80V^xxeW~@!?qo!RqMr|11 zv4V)Jd$X^klPfJ!#8Xj!znxS&7Rpa*0D*<^EM8}3Ls{u>sllFwG`6S^iA)}uFfHHy zI!rlBns7lj_(-Sakb|S5>`F}(l00qg+#qUIJW5KLJlZwdiP$;ZH=)&RsST+hQcC`e zpxkQcVVb2I=B>|aVg+Uerysc^(G7U24H#@FB_no3Hn57Z+aaiS{eDHe3iO0c~ zb@UCKVZ#-jt|XL_P2IE85U&{H55^3T)%mN95@L1Uo7Qwl$aF#Sp_{7EO+1l!cNMvK z^8Q>PePmyqeYh9Fv9GPeJ1M_u!mkE1kSURXKdD3kNNyPCTc;gLvu}Xu7@RVpn}ybm zR@P>WgS?0W!BVBDv<<`gP{C0?10K?Js2{_A5OW^%r19sPtVD10hUxuDN|~Z95LHGW zVS!QzWz>(4ND3-^IZ+l$qCxv3L!p+6NOvgk6`n}b^K__hBRihXvxj9+XW1Y7hV$n3 z)n5Wl+yYl1|0fNVh|2HkgHz1i`{`pAj?R3AU$fQTu%El#a)L6M3C0|$OR;k>SvPpb zs$_HdN~lOzYA1qR1t3(U@QsM^7gNRbID@EtM*8_PGK@C+i^u5ZyX071Qg8UVp(A3( z?=%DFw9p_YZsP6{Ew*S3L>X0r5odPS=J>6EoL7k~?T%te>)q?&9G+mNxMj6uuT-8t zu*Oezzb{gooh!Mx9QtcoA{fM3vD%Dh8P4S?{4DlVjiAqN9Aj(2Rk#KWp*NE&0VKhZ zRegNG7q?o8>c+>*j@bjrcKqX88Vfy~z%SSU>3&wC# zXQ^pgt?;Uv(@7L4mm^{PDjOf{)bp)}#r8q!U7>zWlC`{ZzxX(v(Z21O5ZIs<7$X+<@V*Djj%qjse z!0zuY)N`DE*1o%)r#BGL%+l%l@*`sxS0`H`{Z_R7iR}JYA5+Vm`mMfKQ7OCW}|5}1^GKocAjfEmS z|Fwp-@!`YE(&fc2fmuf zr)+ZyzgUR>^}Od1&M;uqy^$Yewk=g!Rl1mw@&C$mN@0__6%h)SHwrkh{J zT#z+OhL5r_uW`)TdQK46Pk^oAs@X(*uW7=i2TKW=$U3A-S{T4cQBy;dt`eB6)<+7jgt-NpopP zdy40u0%M`r=F{)Sd!AFLzp#NJ5wHB5jTKqW!(DZ|?Uu2VOIlidh*y`}5ta<(tUPuq z^TNf4U9cs>g3Vti27m8|ocs&y5#Z7RJ2sk`)I zj{lTnIOaW2@Fde8x}FSj`+#Y#-{+Y5#q{S^l-#+R~#p}~+qGo5T?(Yf_WE!ps^`PZr_n-3q8g0om<}kVv z$VV|H#EM^>e!=kc*7H3X+2yBZ1OZ;73cJkBw9I)Opr%BUP5sTE{|0D1ZY z9i97>cYb0&(JpZ7hu;YOn6u=P$v$EDPNi?nF-_=rQ;z5<$`4jSQKN_8OqcyeG`9_9 zo1j+7CzBj^n-3h*OdViee68*vN+MIOL1#_VeY*@)v#~{)Ld|W;Sq$$W&Mym(iwd@P zY9!~NOSXI-yOCvvuUr#kqDN)Y8)~`8RhxWHkl|!(Xj8%HR+p|ly(FsbaVijdU1vwIOSBzxmfht`Hs0{#+!RnN_dK0 zO1&WJ)I*Vk135u}kM=g|Atovj3>;z3-p?AqEkoU6zxQ~GC^6OUuQ0#?I%Rl zR2n2rrPtlK!N0xr>r=xc#eWGXHMRUJMC=?8cB)9_tRVHO+Q@45+vr~S5hOfwk~*>t zw}|4p_gj=r;1uwi-*{+A+nO$BXx|{!c5Pw>;jF*7O!|JyZ_6Wyy>~NZANQ%GmwMkR}OkZ`VE)L8TR=+1jv5?kG1 z+z1$34uEz4uW1o#UYc$YP+wF-ZjJ$UshqndA4kjuQ@b#74w*TXG=z18*;c&;kY0g) zduDZ4k{O8i3EL5m|CgwgMCDz(afJ{&Kf=ygl9TaOIUI+9HVoyooji0qeKY0zO_Og4 z9{0OB0P%v08f^@fCq*lENU?_(!q&^TYZ`xbl;azMVzGOI?WBywPQv5aU%#a^K0tBOuzV zOcNoBrh7e&dfP%$Tb$>BylZuIDHh{>V>#aUQ#Q2A*M8rrxnvq|Uxh!+sZGL|RHcljvS`ZmzLhCWKOPZ55@|3QMaP)Z?FC$yiD4sns1#wK<< zi4pocgqk)PaFCn%+)I*OFy3jJrInDLco7wV*48jJ2NV4wwD62vyTnH7riU`wlb~h? zr<HEb${vJ`FIySm>A_!QB)!l85!XzX~2v#Bs z3>u2;9+5G%d)=|u5$}}sw~hVVcjmWSf%i;Th4##FB!HxLo}S*e*aD z7_S9F=t2`*;!Pf><_j0QiU@-@qsfmyuSkUTIUV zhH)uZL*nVRZwQ7sXr^?h^(S?gW)gIr85DIB!Y?snR@TjT(LS{1=RX%ZIW(u{S)D9B z^!-9NYdga&F20DS%8>HQ)X(5^>kmJRXVl)E9&sibxLWn*lQaIn@BW@9!tx zG#E`!u1E9`)EUHdR!0!fy+iDJ=ee|~{X@5CucoerwR)9%!(EW<~yu2Qp zRc;7J3Z;WUO0V7PR{^RrOZ}&8z+<=Y=ajv?TPeND=^1AD3zP6ffCCP6aqDV&d5Fr6 zSl=QmL{5)Pk)`s%6&1n&4{i{Z+cad)w9J-ik=;~)z0t$}tS4C$rkfDlsPnZbh%-ZB z2Y#ek0*=JT>dFKa`}BsNq!J)?d&24dX8Tv~281$w;dxbi)gbjR4T~6u!g~04cSkp=Jo9?; zY%vU!N{P&hIKhqPJj48YfNVWYLKqm&HOF9WCZXK%N8)A_b!pVU%OaO7(Ev`T4p`a@ z%dTHedyFiS6sVh6ZiJ08lurZRw1(2N$)X`9q|ti-l*^;q0h~N=q*(?);x4U;CE7{n zGF6Tvy!Z;grU$@e7J#wY0^jic?9?`nhDVk}zr!^)6yay3#pvq2Kfy6hQJE~XIS zTg*rQ(Md51pA70WmYY+VvCd8i<9v{VT(u-4woo2!2_*zw5*vAv@!}m)Zrr!eGL!Tx z>0m{sGDu294edjI1Q36(8tj0B0LQ3Ivl0Habv3!^KIr)&&Xqivvs1fQb^~0|xb>Q7 zN+_8hnlaA!UixlvG{#8s=6Eqm$M8V9z=1nt->Azm({c+alsB|mV6w|&C1<_eU5c0u zL86j*zhs6tS<<*E^u}8^`$OqyiOCb{;gsg{2^CMg!JGSEfc=`X>&p#rS9d%Yk&tH` zP29d(*lTz#Pb9c$);sD@o<}MdC38!tvN?$jLZN#Y)y;h@+hUn1^zpHlQs@p~D&s4h zmckU}$9d=Ji78O)qmeNpJCrZ#vo-iCbwA@EBg96)lABPG1`G9$C`X=X?M_B9tYen9!@pj-iXhs0H+E;A z9Ey5o(}20>%UcU$C_|*i?{|F;hx{Ac+T{bMQBbo*fdf$c(x&=_FFFyL@gghyStt6_ zsk!u%Z=u@gb?}bJuakO@hS+6vOu3R5Rb7)E9O2aD8FCTWw_|(Je`3zw2ImcieHa+f z?_11z@i0IM!0q%rKua)sNc?<-;`O7Yas`29EAYj0po~Pqy>@}ryQLZi+;IZd6wLr@93b2^DnCn=IJhJY<*0#?7aI4?&pj#IGOn zKPzkAWTNlN%AnIc)Kt=z$p@tPL<>bP>}GZccvZANlT(wCX&BoTif=*k5e?Wym8s89 ztUNDbRU*ho|Lx8THI=jo{@`Xf-NfM-Ja$s9ArTxoC^$Zrr&m@298vXrUJR_Dx5v$0O|0hycxI`R9$fLOA((0+ZWoR6;JAb|T2g|~K@B4$l zkx>Q-RA7biXvXEA=9U-*muE~xdbGvpq3Cn5{Zv}4t$laAmh2xn z143cNjokvEhX|67@`1^_6~?c5?_Kowz(FvkGmaAfI}EH7q~5#lm%ZP5T9?y$!n8vt zn+0)tGCM<7oqh5Wu(5f&lMB5!gHmfccP}%mX1=6S^yKt*(otFooLZhvNkz#>$OBae ziLKZrI6GD!@#Gd~_=u?3JG4Wb|KKbouhr^>G;^6*yvwIJ^k4(KdnW1~D(LMVc>i#u zrIHsD3;}JYtv;-CdBc(9&L{JYomaZP*f=k6lm!yWQj{420HlbXbwsXsi}YPJ11LO@ z;udU(5+$fUo-QqgWL^+zBQ&ZxT5eiVKUTBu60uBh%1p^zrL9hBneQ4+e<*_FOZqGgl3IiWpw5`(Ut&{g-=EE%b@I?pF&F-EGxV{PDqiXl zBW>HCkUqFSPhR2>+$kLhJ`)|T?UkAfq2F7N-ktHFyXhkze>%I3+IaF@_mM#`p~@ul ztLq#ltTXz8*H?|phi4U3eVK@isYSe$c5Jw5mWU5MLqN8X+2i07+u>h4S{Nt(dhnMr zyx=94JxjH2u~OYj_veq**gJ)*=}VUROY9oe)m+~;sd56`P8yh4@?sv1uxf`@HbP)7 zPJ#HByro+mrYpn6KBKkO=Hc=2kGwCTwizh7Ac4sARS8Dsu>d{%iZKAwswbM8R*psk zLEWY^8i}rPDZZT+?uuSTJE9nSvqr-cJGC7BNPSFwHTp_$B}=;QuvXRzK})Y+20LQ7 zONAybMYeI;3XB#hb@Y`wk$=)%l~gq2K7XH}QOVjBrz{;z4>it_4PD?+@)pz4&zBvg z*W*uEmZGObZBQ8I&$Lfnvex90J9k|yEL@>q5LLxRtk+Y^!pz{5oZ_9N)ljB_D60w& zVzyX4#m_g2F;JuKYw)+y>uelX_+MeSS92%b| zbmShvY~*AerYI-w8olnNn&!J#78=d;QL~+RM<`EnM;q}nlF;5$J7?WVhDK&;{B zQf6qV;YxOj&w{-@9e>|X)>-jsz0|B4BfL(;Kkx0u*DRzQhqb?}H^Wsgl10Hya=Y#7 z6tUZvRj%Keus?9VZ*{qaCBJX!ahJ-&sU_Mm=@WS(z2WA(&zYP0G_Y#+i{bg3wv|G5 zwMTuX0=4uWV}}Zbg`h*vYQb*ZJ{` zt#qiI9Z%F9XD@4F*3gf*!d@Y0PR$kG@LIf|2b){@Q}xPrvX!v?!S{UC*>Aft@T#m{5V8i$$0adoBBdH;e7i z*mA||JFdFDk;~?UUU&N6QoUpCKiqm|4Ho|cJV3+0fokAruOcCxRTBTL7QGRAi3VtM zG_OQW!Obb)b3qBEKRRs!NF@;wZ)H0LT4e=<{1%MBNe-lqB;ZK*30^Wt{sflfk=?;0 zJBt(>g%}u%XCY=|I77J$-x%8+$WfGFggcP3_{qFgNed&47sqlHRT;~Q+#OJnk&(Q0 zAVNsSanwzU-oXOF!gCwih+6-oP@#{0H6+3wxow&_k1D=ZEr?G``>pn~zN;yz#= zg6-#|;9P4m-2sk3@GeN8IMyLLOx*kLISP5kv)R%_=gt_^N9P*I6J(9AUh7s5Tx$WX zoHo69XmkDRg&-Or>A$^wN?N{m<5=j~XKTMiu?pXdWUHr%V#Jj3!x+~z+VWXUO7Vpb{cT};K$tCc(%JRtWj1kXDc7V8pDw*3r7{h2akJ&FOj6Xh!o)6? z&)o@Ho-H{f5E2wD%~;+)5fsLlpG?u@jK1gM(?BsMnV+qUmCVn>hFp{P`c0NPPw$3K zGjTy7nD`9M`wYM4;!Sr4R@AVb8Z&QkL$4+%{plDwc1tK6PfvN0DF;kYs{ z>{ZStD>mN_mthMCi+*}k2uRkTbdd<(gOMG#!>6`F4sV3Fq7s=FzATODt`=g%CZa6% zDG{Zf6((^Cn2S6+Bhw;9u_C1+Bwkv@6C5INgd+(SI8NJ0i5W%Wph87Ih(RoHlz2j; zBF9z{GT7kfMne}OugaAojiDA9%PYajG-Ns&HO&Yg<#-g+LMJHK4B_QhflW|mM5iih zbqa7Pe+-ibsmkG^Qk)7yp`W4rp=*gdfk=F0f_ElZ;*Q``PZ?qjJK+X~XMfVA8O4n| ztA_n2bn1+O!$!EF0nTszJ!2wJ(XH#_5Z~%q10+Gbm&9Ri^Uby7_;B3=35N!VoY)Ko`XT8~`zZB)}o1{~HtFHEDl= zYXg0i_!4k7$gjW>2c#?TF#*8J`wB=N5CtP)-2;|@#%wYGVZmQuNcM1mdu#)cGUfVY zt=Jh1ub{?(){6QHC>pS@pm72HiTVX_9dMtZJAt^#`T*z+rcclm1{D+Z2HFn^HVdn6y^2p;2)@(>Sn!+eDw+=$;G z|Mox|;37W79(daFC`fOBmG7u;fRXk)8{i9{3k~oEvrLBg3jec!zX2cKU|)bLn9wh{ z6y7ou+yulQ2QC!Pc0VRJ2QRpop5bbCi#PNxk6@RO3jsXCK|O-hZn!3^1)xQ+FJL3Q z-^qP}ZR}nbux#ey3)C|6-UaFc{M-Wd4ZP@hTRsb@`E)N(rgJ=n*OQ{;LU6dL2TX9i zK*7wQ7pPHlngi1jVpP>Es!u3O%<2!QTY1w#^#^`q*gl~@&o~dLLHU?`9_j&}Z_XZ} zDJz+XA5bH6ri1DaoYMRo)dB_3AbmqQ&fCS4ewya}2hr9mhWpO6&bM!Q*KgMG?>fx7<-O-yr&JFwFJ^RAVwO81>+?Pjj|)>~^H`{!7PSx>%oy0z7N&Y`S0KYZ(@Ysq)c zwAQhQe5;vjIrql62D^`ZYc2J=`{P-wS&N=E!FAO+<5}-nC!RI3HJIG-t=FyP&k$X9 zu6T!^S@WJCDUILH5I|$9b3`WNV!5IKb~rxtKtmnVS|JCI)dX(wUXc@siUrvmQS*%&ca{TTIH|nD@^nu%8&b@@qR= z_dJ@-_Rgo1Tm8P&@@ppT(WjGGa^4nsHIr?jCzD$xvqbW1s9P#eCb1o{eDZ68+cHZc zxLvUvvMUSQbW0+!9kcYZD>qwO%ObivW*KBhpSE$9M0!@wQpk=GY>O<2%C_;5$c@Qt zzm7y=b+XKIBXZkY$09sMwA^wd`djTsA~Jf`ZaEP{t!pEZ5?0a9IT3d)I>#a@<)GAZ zB63&|jzkXI7*WWB!C*Tahyr#e2hzrV81Q2( z6k(46e_>+`csrI7@W+BRV84bu8!HotW56=8`+htTOBc7(!EvBFx}FWK1dFNQmC*e< zo(0_lW2xXMs1DAjgI7S%>UA#A7+p@d`W@#}fJ5)|snoeZ%<6ucs9>E>(B%i~so>F2 zoI0Kb#RS3B@F3_#9Zv!phSk*Y45%2_PXd01J#_FO=oyz!0ak^{bns&6B^OTtx`DL1 zcm%WwOQ(U&K%-qe6KW6DQ^DJzk5xPbstBc1z>%R8RXi8!2Srms;-TYJG!AMPHB&(v zpouD)4UG>1si63wHdQnps6W+B0Lq2&RL~btzN(r9T@AWvpzA{TnrJq(H0h>*T7#uD z&|uID(@h7;4y4mS4UyzcGzd~1siuOqL~S(CY~(-FO$Ky@MKsV>WNcGS1=2urnrH*E z6=|k{dm~VqXagw=B-222NYtj91KfbkG|&%Zev?fGIz?eLun*EU$)$k}BD$Jb9uhX` zrGPn*XH6^^86Tw5z<`mrO)Lnh81&M?<&a8EEDsqLw9>$Ckf}{98@U{`Qoy2-phYYe zIS&+4z+}jDqLu@uKzNE+2~r2BrGt?o{EApFvJwcTf{i1{idZPpG)Sd@hF!WTU|q;{ zqLu<3|A?i4=OX-ySO)hpQA-63tA2iWP2GT>t6p$D;#8F8E zVny*3kQguiqLK%cjj|~q5#RcXNEXrsD5Qf^B2-bhoQQ%cAV=Gxk_McN3Mn8Cl+r~c z0WNhq$zi);fo4S_oSS0qECp06=;*{6M0fjYFse=xjq&$^z8%Y8}AUo{fFb5iqvKzeo$S(JE!ZE4Se; zb-)z#Oa9`DcqJ&fU%KsWcLkkhzX6AaOa!*J2nT{&I|Rmc!X*;GfOsWau)rP(Tr4ll zs)VZ60As-tVz5!33%nKvBf%@#f++AxxL{N~68)HKj|4~&h5IC7cZk3QWf&zR*l>>p z*`ou)HQtYnOcKUuLS4HALEySVz}|QzM6i0E1#m1VhJjVv2ctURuK9)p&?~-SOEe0< zm?upFsU`zsK&T4Bn#wpUV__F*YB0Ud82=?dw9qIiL2W@Dm31TPu^cIpR> z0K5eiW`J8Ficz2y7^5_31sN10%>cBDE#-hys)~7F6`G-fK#G`v0xPxq1dnr?obj{ybIO{?k^SrcuEn4fK$SRQnjRw zZPXB}QwKwCXxL?X);OUhAByd5lEnwLR1DhGCW`>1`h;4k@OR#z(5@sMm8g9yw6&7e z80A|4p}3*4SPB7`#l2l?;&nw$TrfI;P@Y$Y4&IbC72N`Zx`wf5&~m-1S?VxQG!}ZY z)HI7dL6sU}&ry<%LeEj9M+mdl@Sx6FUR0us(P#CNq0UM4Rfs>(ikpy@^%fFOR*6Q1 zTFyuDlB=u-0Ns@Z()D@C?@YFYwdZ&~Pi9K107>e*cYWaQ)Nj+~W z6J(sFT7W4hD>*}fT*MF5hZw#|%8#f6s_^Bj)VuzzMH=$jhH9x^P#T8dT&>NwnbG;BAPh_M6ojj7Z+H~Dby~;7TM$vBaop64*egaN@NCi60+O>k7 ze5Fhl%-Q(o4=8>jVqyy@K254scemvYyrThb()6=Y2ZLZoH6XBi>~rbVD&#Yzy z{JU{phRe*|f{C$^pAZW}Zr}k4j7JDq81@25jjo6dnC|U1$=&M#JH(7!N+1q6v-R=( zVU)k~%U->uCX-ROfMmAt+>GlBl2aD_U*I?02>;9w_u!e9x3t?*>nqM*Gq%mshTgD_ z?8-`V-cv-jjr+(I-~*7ufw1k=YQ0zet2Atc1PS2SFFr@%#l>%<8(jx44eiNxadZHp z^ZWf88#+sI-_LIFH+u-coMTxa$~Xr{?vet=xiBR96VLQ=NN*>Uhr8jJ^bA3nI2I4Z zQ;)1n&ITM2Stt=R?+9FRYwjmzaA6Cx7$}+XH=Dkjav{tBa4Ez?1DV(`_@L~ip`DI{ z9q3Ml2ufRgLbh|)GP1a>6O4=+{A~*7 zF=Pp@fTJp0a{Gb9HBHsJ@wG2kYB>p9hA1g&E5>vA=!+L~_=gP!8U=gL!9fJ)^?7eV z6}w6c3TE!<4`5lXkQ2#^3#GLf1II%iR5&nf-|M0ReNqx#mjf>iEo3rjm|@9Wsuw|keNi)PS~D{SD{vEJiId?%ZEj5F!%=Y zQ-FXWTIfc)?iHsymCO+VT!q!BZ>Ft)9-uT#idM654I0LiO_>PDSzS)dW$nrrruR-^ z;DiUIH;2iAq?L<@&rm`!6EHe^HuFQ7txarMAiZJtJR>fjVWoUG-%7kGu%LS^8ptU(#IYy6FJ}9_#cOj3k zbMB$=EFFNZ?Bcf9I%=yaik&hK6l5+mE=l$pd#p&bhMs=DYTM422UO|RP?YTIN1&4$ z9K9Vo_CpjahZ1@XHfuqKE^3r?&8~?*mfEBChKp8#1kmmUkwW~D5ZgpG`B+GbIC_gq zm_mc$;5|IXsd)04X)?cF9(`iLK~X}EYHtYAGP^X&>6IU>ZfWHZ_pS(QEaIn0y(I_m zMvp28dm>nl;F7TgtH!wx4IcFiK~%*bTk5b)4ulrQp38vOZPm(yWc2u(I&}o?Kn3Aq zT*#uj$C@AsddPB}-vG`ms(?#H!adr5)zKg64l>AG0H+b=K*$>U>NcvvNgJ>0c_Ot5~;= zW;C%U7r>JfY5-#drAZgD3aRR`z6HB-L^JkXU_{dAHgqw2C%PGZ!?nnX&tyq#zPr8I zd*W-p_){b}s^Pu+#sC18cnah2E8V4+i|UVY0-aEl;^#y!&Y34pk*&45lxLx%?F4}ksjh8ia`H1d1uk!{0#bjeWlChK zq;Ig88)y^%LHswb2lcuv+LLv9q-kxsR@7UulB0F|Dx&gHo*HTo*wf~&)=!1(Yzh@Y zh=0AkZD4Dt1=s9IuG*^Z8D|sJ?v}{(eOs^eyTY^=iapPK_^D|$*JsVsutbwz)OQU# zFu)@avuHODdO2n(pS0}0OF2ALEb3a9E%8?a?XoRQ+A9qm1&7agUB)B|CM>a7R)%T@ z6E_@#BONJ7IAPcCjCJg!i>)?HOl#Zx>q*-PN&u4&u@>4#&=9!s(74(bO?VVyjHBw@ zR*=ODG*S(AnZM5`AA{S(LG;NXYXcnG?h;ipU(#0_%T^Ex8SW%0Ov86vRdEK9fk&hC3B#FKa%#3%>pR!*|mj#W+~@j0nB? zGAj8Xh}siN>d{6jo0KgvVj<2&=OV>_x(Ch62yNL-(y1wdoX^~8DM}ta`Si$xQLg* zh8gXY*JX9sLLIe*yK$gJNbMQRqLpvLJyP~&j2#!|wEA>|T#KggZnSg)Q!uZ=pys5m zv!?Wp{m2%i+0#FYVX^plQsRkTxf63^OgnZl#5tsI5g-gEX~zD|PSJ#i2=Y|VNBF%nT^ek2lvkX}YW^@9nS5P(l9_KqjtWNM^4tX}cJNA8FbTEM{$HENL31Pdiwel_6GrcAc5S+=bYFLUnvhn&M10)v<^mF}X6 zrn6n``D&mf7o&~T!RsY%8P4Br!a~U~VYXr^;||S`*D)so z4&CW5Ckflgv}OQEvH0$*R zer&`M0)904@L7m?lCYPbWjG#z{#fKWn31#QVCv7zQBKs$`TP+$*)6S#T|9jQy=Q7I zvmiRcD|O*@-nq<7uz{Ht6&>$mBsU(xrIk6;W5Rn_ZNGrVQ%=UX3&nc3$Rt)R(TkKn zabu}TfDx;|%a)ihaj(rD0Yf(d({9)*`ihg7+N*SPfjhqd~ z-ICCsFP)nk_iXeT4+dBzlMUyrK}Wu`QEx_m8^L$3ziYH2k&>)#CR^a1LNZQzk7JiOvo z_$z?&D>UO&<0k4d5=dJ0$7E2L!m$uCe4(b9eND&cAht(4atoW&l^|FS>z>TEk!g3uV#i3-jKIMF&&_4kE0z7*!+(&?}4sA6?S5nq6)m=nhK2 zv9_j^$^nG(rY$!#mZ9L2=U$8Zv;PmwOJb$)^)gS zYVpV}IUYKMcYY~4{!?(}KOOgnhro0s;o2JUB6!Y(0#gVdD~zp29I%|YXP-P*q+YC6 z0#fGFBH^7fG#riv^04utl(O~=t|~UXh7IOk z!+QJAqsv=Ba0|4A^A2NmG!a%o&0Q@ErbzsiTFcMhAy)Y*gv!Qg_r?WMdu09{O~}x& zHHSHJGzRx#G2q(%Q)#Ve3;@nWK1O{RjXxVGMvkAU#Lzzf-nyFx6$3F6-F%|f-qX-i z8Sf0`d)%9)rwKWlfbmlpSoaIOVUYxWu%|yhdkS;#zvO5};b`ogBp#nyB|KuJ_ogwC z0y_vJ+GVr}47urJO_5zMUj*AqVgx*<3_P71i%^$I-!TNJv?kg|Q$5CmX&71M1nk%a zw$@n9k$A+p=MWP!Z0_Pghr*agNrYvX`2m_?Ff=KRgX*(Hf<&364QR!|avwuZr)lzbXpES(k%yk`HqLT)| z?5uqg;DTWZBzhe2gDY^2gMtV#J!uLm%KQ2IRYaZ8_B@BSJ`&>(uKURMf*3anWj^i; zeUGqDOCe2Cq#{B70nLo*Px1f3N-6HA`2VFwnEOROq=Yb1?aGcoR%G;RqmEUYF|=v@ z$2zpGLvCh6ZzDLRG6Nr}pu;@EU8FlQ4XH@CoLQsS;ac~k;%6NN4~9E&+X)6^ z^j-=3ZbiWxE57pT$UAuVH%-UBW4mfIbT@Pr8br!_Uam7Q#74bhr5v_qu{ zVN>R`x}UXRNnIwo*OrUN~m zl9dcG*_wQZqU#+r2-9Ko2$@(PTfA&y-fss{F?mnz?+xH0fcVf7KLUwwKdYnyj8et1 zxT80Dk^4_f&eH;zYJ))cZv0n(U^~iS$GGv0B>)(? z_t%`ofu%oAoCk9lcd_8T(mOba(Lxl4gSMF(4wX2VW>!zMz?MxjlaW-3@lwHm zJhq8j(Kb#8QdklCL0dVd5lJ{n#Btu}$C5mPLs&p@N(qQC)Fj(R&cI0EG)jB*5v3NsBZ{u5Y@hwxrtjS4xG z)h7&kd>nRa{@b;sca&44jMnA^9jo{bYS7_U%;R9zb{t5%&KXnR1%L>v21Ly~(3wY# zG(g{&sgp+oSu_A6S@EDIG`i7T`cYIkZbah|j8mUNk|$$IoMQe8r0u$*9-kYYS978S zBd-*68x=Oj)s;G(2FM2m1p(qMp#Hb`)v=;C%TY2;m>{DYTo}kV#KR&xfA`&T%Y6S6 zQ$U^#w!=gkFh(UgOf`EoRj7aQRjnR76K80`QII(8aSODyX(+Fte-?Qk3yt6M zW{XBX;0r~J0jW)Z$WnZLz!Zv{165MS+yMBDz#WY$ksN*)0UtAQeX z9tF)w=Q!fw{FMwj04Qc5wJypDQcdZ+7vt&v%xy&AaS%pyA}FbDDpzrA_f0qsY8V2i z#{VD4jr1r@s-M~rSsAeuA!>w$=rFnJXwHs_-A!S@%W?2J*ed2j3=LEM`m9HcC8XihOWW{Z*)qPYEI!3O^}=lIUhAll=cCo5D_uTUyl6UtI?N5Fx^ z1ux}Fno;9uRjFo9a0)ahrPKgVgb-(h5Fa#s>R2s6U!#hpH~p}@O9gFSe{_{kt3T0G z-Jlfh9|_Vv-J_GqnsDd6W4;Me21!JR)S9UED3Jxk58ME%qeQ>NppjK5!rELXKzHh+ zz84fQ?}kWjC^+Sy{B`_`s@P)xWC#K~@4U#w`MU`kz1RaOhv4%Y;ShFg~DE$J5Gj%t+o2q&a7YOwJ?#OZ5p_PTK>a@ozxogn}xD4WtJ8dr83{b{aU&1Z7yu;p!AdN!^gA z$C>JEM7!QWq7li|y{W12WaCc6CPL!`o+0Tr)4ecw3yChRGJMb{K*vi3$jb|wVG#`{ zs0oF9ic*l1O3!~Dr8H(r6&K94AAKoK;{^m9hoY2FHiAAe28*U|B=DdbE}6SRJ6kiF z3mhm3(!I7pb+gKqSRg@j%x@$P2nH^Bjif2TAWRoPL%75OFlaJU+)9$U zr{rh2*Ab=Udx|c3JHy0;spINmTxxTm&`pY$%(}XPDOo&?$1*sA;%W70mJ9>lb@%K> zoLP+Ul#zho(WlC9LR112vTH{2r70>pi_hN>a^LumW!tM9S@>jaOF%~rEjq8UEd~=) zi;+kIS~M`eFkCPYmGufB^FC`UH^#n$Dg!E<=sXVF{N%Xy zKubh%C9w-R&GalZ)?M`NE|d@zCZ|7P9txY6_`gA@wqmrHS}Tgf`=RJ}KK^fh*^Eph z@MKBfhCatJ#_&5V!JDo*$V<1T?eauFl!&ug%hQ{ae| zp`^13?O2P%7Gsf+1eMgp{viOm+;DsNoxw2FPcCas;p?3&ig^E&NRy{Rj5$1pkYK7J z_~sU5PG4U4!;p+<(S?yXJ~?bdgX2025Egkxa#zKTHxnQg=rO@TwS0r$$TNs$V%2ft z@(_BP-U0&-RGh~m&)0MW86r$3jmGsTzOMGo#?BWLJLK_GLA z9T*^xi;5j1Ak%v;5Og$p`OyM8GCd;(^f@FRiP9C`3d=ozdu60_6a&sI^-Uy|eETv; z!4tj*DNZO~#xH>*gU0x3nIg(bs04VWB@j-f)pMv+bc{g0eEfPrQ z@4~Wz(Z@2$R(_tVqRj-Eq-?2EgqmY}il(+eGL-A^4P<;HAEb%swag2h5LQGkl)M5% ze=(@P!z-?qSHa0F)R0FDVjyHmNT{~If)x+RLXLrM!m;Tbe&QUnn5~w0z6i}!eu&2)8l?N>vJ*OG-B{5M6Ypf=Y zbWFJ{mdHbfDQHhYkisn;o;2VjGYPSh#a0IaJ!b?$trMGABxYzxu1XC^Qv_0d!Zrb6 z5rf{GODGw>NvUZcotT^!pl=dJh5_Xh_oGMlsQ#MT5;PGU9`B+oA2HJX=}D4dV^ZOYsh#m*J<*Y`(sJG+eSjCHdV;kf{LrM1(@*wEp7^Eu-TB;|#)N z!Vxtt-H4{=h{cs)k5pb5flET*9LJi3L+AuN6K1cVkq9Yi^|rz25sgE{ub7AlD+$ZA zK|S{|DPTk%>|~r#C$qGI)`lcT1UlZ(|63UK5ea{eEvT1A;#Pb=#7L%_GnRAZoTi-p z*bHCvuj9i3>(7opm*yY^)PM$lwaYCCdB^1ApU?xQsQO+d{w7l}Byn;OvP@KXAwE~0 z%Y(k_zHse}Z9HZd_ZZTJXvDZ;6MHy^F6m^GX&w%XA48-G#++cs9R1>= z>_IwtJdzs+pwd3mM^XbwEE!T^w0#cwieu7Mut;pqpuSBxO9lobX9rOE9RCE6#h?`^ zZkIiQg9S@YOP;^{29>IiIHUs8XoWwX^K<~EQ#~CP0Et5|gk^%nZWzYQ~a#0G}8+38}BNXKl{-w!*nsUVuOvGXX7>HvlrWA3%!2lJ? zm(&yi6gxUd?x=$4xk!Rcz~18tXJ%0oVTy8z<^ePiF(5NiACm&oGr~+Kkv0J@%oGAr z0)7qQQ@|@GpM-$E*!&8IO}|Jt-97zjf&R4R>cmj^Bw!;uAMvKZcbWi5n&R-`Qbu;a z=klKPrw#MO!AlM|nTu`zwh-I~=MpwJfR(AKV2BBr0x|*vcY>8dX#)ZZc#X5JC;VUG z$R3C#)U3p%za)RZGHGjMQW_d@`=<&ucpxiYj!uL9v2h)qx#nyJ@P>6G@g!g}#C9#J<+FHZcRD z7S2wtc-j?`G%Ls5fO2}-FxW2o^g*XnawI5pR5p_6RXmHjmc(f_FUY3Ev63BqUhC{K(vbpT(A?Z^9sJ>DZn4Wa1<%pXe z97FjY3nT_cW90fl;Z2!KDHT0|T95{C7anPZ8 z%e>HU^FA5C?aIv4{w?(rAk(UOn5sKAk}oGz#z(1mM3{!qW<6>HL!3LmN%> z#+Q3+XZG>~o@p6_f&LmlfX7eapuK>T5X=RFymu7MEZ@%y1hXIE67g-WmFCGQ&EYrI z5>R{~do)dyf|-MaTNMD|m}f65u#e>4>2j>5){eHiKXoJuMUGgA9mZvvYgwy5YwY+t zHVrWV9McbQI3W9qod}vgfRIZ*rR4`>rS!Um9*V!JMdY%g_ry?ehp3I?4PxXxU=m{6Qf_-1&>BwOL z5hKVC@ucTGQ+GTnkds%iq7r*TvcMkNq%odvpdlz5vks93C}!%Zp;5H>D1h8`(+4eo zcs$_5|1#$<0Tr-w?&u$&92WHt&eM;vdwKw*YI|N9j-Fp38>A@-x!C~!6;?I2XaP0 zQ^}y{4+d)ot)|7r>!r~Ap00M(RuMf<*n?h!En-9l^Q%U#ly;&YS2coU^(A}aaw?jnU4hJ=#XqAC5sy zQy3ODzPF*1seXv@BfN$$a)2A)46$!p%vsYA0o3slxH)V5&U=298YV391azNiiO~=P zz@-IF-};ofi~w_-fL`cR76oL!w}hdQdfp=MrR#K1a1*y?`Uebs@KhrA+jB&7Oag}x z$~FsCBj3OP`nh@|s+DJq^<9CmB7rak`0g?$2@x$AnoCAGLDws!QvJmH(6-MH^oel) zh?0ykaALS-oGDhw8Xx6O0Q7i}SfTNm=upB!4g!16F=DtoHdF?+R0oj zeSe}<7~%sA;z{Wi*xe-;!@KL=ZIx{c&o%_}sAQqm=Zko5h-UGmn(50n#(&cEPS%@PpMwkFq zH!UGyQ99VbkMEwjt@YO{DAR?VY*9H`yf{$`uYzM9dY&|2XXuAQZ=urWx8?7Y;#=}_ zrEy~O&<$ElLGErBvV0Qz+5`1VFS@ww>i_c8x=h@BnV+_Yttln**&P z48Vbq7&095FO0&+N};VaVpQ9_?1&u|EuF<=(t%aHE;%s)^jA4)mQCntb6nlLG14o# z5)US?bCyB$Wb=!SPH6%Iz_iAatVfZPh(Oe=@R1!!8LVFYp>+PCD}co__F!RGPwpWu z;{tGlk4jI){vkkKm^5c%1++w%@=HK<3yL(IlCPEzDi0-ji~+3a_Q}@7-Z+VtH=rFZ z0TW8FkGKqP!xK~vIcgKIY$y%W2(7H;;6T&!FIb8D98IbV#rY$Dg8~z9qG?f26iiMY z5S%l?Ed0)oEfi5d+102W-cMvClp38TH825XnUW8O5fSKGRFuKf=7O;1S@(rneAnA` z>dA-`5dqFpFfl9&VcoBKsSAO{w8+r|sHdk3fd;^!-YuD9_71aiR<>J-dn)p=DBZFH z#p=rlLK5H&Cne$IV3?$8sD>a7B#h;Be9`}eOm>{Z>rv(oQ=FxN!lZVJMjbm0Jc7n? zmAhcWI9$NdOwIiP(TDiK+*L|z;)bvOGvU2P8(@RYVthq5mT=1oqt$7!J%`uPef0*I zr-&E>u}~PpKnn-O!aUzYdcPn}LHq0a(wR!Lvw;bM6Ihy^!f5nuDKfIgW>f>b^$oL< zC~v48)ZQYC{#V@0%?j?eDD?UQLQ8QHqYA@r`=Hlj5Awb=IsKCXcIa7Lefhax&38jh zfl?8FU_B1Qxw<{Pf(MMv)~YVvDX?VHEjpNkcuq3xyM)=|u-Zx?ll)nfLO8=a#S8DP z)|BYF_cj|%>ZUPl-C;6xxBH8U2(rQuExtnQ)w!8RqRuaQhDN*?bsoCy-)?ZPN(N+D zQ}2f*@NLPZV5>2;xQ!yk_3i;1Dm`6$Y#izsf97$i&5s1_8E;>LH4_%Mtp$mK#M%ul z4{}VupuLNQj}>UO2$yJvVvj{Nq{$ihv8ADmF2y9n{|bnrqQLJL#tPBNLk^;SK8Lgo z>@Yi>H6$Gk7+b->J|#K4?yzv0goN_oJts2sDgp_2&ds? zL-sBTfD7~A_n1c@jIpQy`eWDN8D*S(gSVP%gDo@TrNZlu1Q5n176h*6A2&515Y3qk zc)_P@gnWWJd#3OlR1$zfp9R(sUmNG+{DBmNLAH#8oxVP$jzWJ$RX?F zUoMDE2uU64uk}19UlHzF7k#U~PFDSesGfx11@dM|)+pkE*5B?b=C=n$T9%MU>#afWsv-^gM_oi8%zF&-V=eQo<)7+#eafp z{$V0Y%lm|oo-hB!iLU?YAC-Fosy)P`kknlFmHZ?sTymSFA>U$st)gx`vP4WJ=H6^t zhEYryO|EzZ!kkb!xN{#JS0q7r*ot#$#5_XWF~O%pX6t!#+!{Jr3zypw8u2#heWA#j zCGqq&7?1@Uw@@_-q_9RJH@An{FX}`+?Y$>@N+KTovkDL0ce~ev1Mh2kV*)_I#$8h- z_m6M~9pvP>`DMNV?L2wI5LrUJ;i6w@>m-1$NlbyCe&+DQrWObde&Zm-9yL=Ai8ake zhy;`M7ZOerXx$chLgY}n7oA0AeIK8`Hievtb7otTiTrTe)>mL`Qeln!>3f{d&A>sU zLpE^kPjl?|%fnb!iHg|_;9YouY6pQI1w~&O5-pEL->y(*Yk!=9EPjN40KqPtljdF_ z;Z+2|&!{YEkPfjxP&Qi+GsM3y&BR2I1UT#RpG;=a;|=<2eDvIIZxO5ELxwrxXvTyE1}{wvoAL!H_*)%B8Dx3 zC}MewHM=$K_wvq3Q&sE1I5R1=AkSpUW?!1oug0j`$l+5gF+#i@$%@ZkGK=wS*&o{= zlm;jpFKCo0at79csBS@qNOk-LrWnC|LaE+YBMp;u7aH)&QsH^V{%20qu(bA`eGXpt zuM|1Q&J=iCELKFqeUi_MV#ol`m2H%locyMO=J8@r*^$3ZlECN5s}r5mV%T@iHjR&$ zC=_%KR2WsV*PUDFkdOs6jF=Pj(qv$eu|2j!W&iE|OXv?b^PT zykMc}j*H}z);gXU5VK}~(R(2gC_ zKq8@*d}QGs7m4nP7q;`;aGBtpWa}K69)(yU7!6?F=I>o zVY-ZzbyP$Qal)S&nFz-nMvcDv;gSw-RsBIuv;CA#z!f} zJl+t#jK!GHE1J-GxPEw0;#q_gm?7{*u%uFqvm!|n4{ChK7JQFW%J;Vl-g)NL)<3$K5*{i67byM6$&*h?xjgUzt8U~?(OObf=)C{SsgXc&Plk#4FI;|n*ivd z0%*sQ>I|Xs5TPA$d=GJ@568m^x-6q3@z{C1V@Y!&+4^yd*gk(+Q($LjA~;Anb?2=t z6{d!A)p?o3x<#i0AQ^3t8rf=8gVpzgSG3;n)JEZ#Wm%SWp$4SAESJQ47~DvJEZz9- z)1XPwe67J7)nqmn4XGcD$}NQM&a5mn&QSMbjUR_$%yOR@ea;D@c<;nAzUb~05&#pB ztAq;xKTsvvQ>%2mnqhGT_7jxD?G@Vsh4F&q5xoSD`po|7)5_ z;uOkV!^z%Sf1Kt?h-2-{!leEdF#;so4rx-CwKHNHATDG*c1 zF$Ry8drdcQ`?-Fd?J~-CGp400?o)_l<0(3B}7)~$`cjhE}KM3 z$TY(UvNh7bB@jun(_%z)m^O^Q2t>LUMD*h4@)cS?-$86;@9EF^30XtQOYNQWZVni9Cv^oHal$PSq3s%Hh-ztd%vKa) zS@O&qOMekPxum-Cnv?fJD5U?Y^Xr-l;4{Iei7rJ7(m*S|1XEa!WN2vj08v1$zr&Vf z#!MJ-!6>2OXpVBz%1}om_bf2}9A5Z0HNI`|N8(-|^5H}$1v=5y-sLrHJ8>{C!zK0_ zWC+L@@~F-}Q^pTom3Cxh9fo3!V_qT=Z=Ok#|q z={0Ue?L!`ip$a~wL3DsW>F`xCyON$qzeS$^i(L{Gk2}QEdCH`f((~~o9jH0mNO@FTQRTZ4qC7hRj$T@P5D6R ztLaNR(dGuE|5miVdhQuWw{kMS^|Z=qG_dG7dm4odE;4VQAUkbSH2LP(Xm^>avD|c1 z)4rcFh!j`z^7@LT=h+iJ{*E3bltV*7Vl@wF%_eCo`kxQUe9QlO%E$dNU!zUvIizQJ zi8v;V9U4hw=rV;*@w41#E>==E+lwsU7?u7KD>?e{W7Znm6+~2z_!u8tR)u zGuoi$%CyWigJV?tVSf24g{BI7roY5Sl``cZhPI?7EH(J=w)t3iR1JEigv1D+sEB)` zI+gbJN>c0Xs%joPYF9DjW$woDv4}L|R!Ct)+>N9(r7D3*Y41WVGb|5Xi?oB{F~rD7 zX{TUF=K=9)n})mY6u}ZF!#oYz`D7)Asq4OYsUuHY%ZBhhM)G#F{;>r;1RbNCSv;xA zH@yZ^uc)NTqrIK)99)BBVr1?Q6^Z|ct@DPAR ziBM*#R-wXHs&d!DAY5o-q`~Y%pym*Wd)oo2lJ@WDnf#~)T;NQi6Eip0?VJu|0quMJ zdc5{;fC<#;1h6pt;gkShsLYtDXR>A3)Tu}5RR0(P7E)4vpBpAt6B$Ux z8yg8@JvRIhdT3w=P{r#f|O!p=wTKZp^UjhFLX9Isi?`DY^Igc zJ|7F8W!G~ufMh$#g@jlWK?Z9MY)<`%Zozwgdx0j;#?Yr{=D8cIcXCn|UrQ;l019TesGu3IW;^5km)Ou#`V0>@Uf#+zgiJ8fY5J0ge(SiPyhRNBPl)&{!k&^oX+ z{aZ;%I-^(B`k|@~y4UI>T{?fo%j4N*m`u3?a<5o57!?DGAx0GX=Bo}GF-#JF#mJ1O#41Da)Sh^Sqd&T+?YMz# zZZ5Mqc!e4@FZtdplv@N^#rP`ot_)iO5ZiJpcj}i~`Lsy>02J1r>%dBZvT8Ab(4ET4}I3#z&yZFOoBC0U9O^ z6g0jm&|}HO$z_zAKv*XuY?mL9PxdTfLAq%gC{cu({?5dClA@k6N&;xfqxf0K(nU%N z<(nC#PZC8QtD|2|Zoh1-F4$}*Hz9VX?&9rF(gSsl>LDG;#CI^v(G(9v)YJ~QV2*PF z0PGBEv?B{TSiaXyw4x1r;>~MboUd58FUytz8ReE2KJ6#KJ1wG2nC*fDMo8DsRqDKr zHg%14RZta%sYF{RQ}yKb9SJjDHLg~mF$);zykv&Xg6tz*hh~ZO){zuNNDU~j+7vnd z<>tygAnoZm60O2}2H;t0s*rBR$;T!%ThK}PZGXJcZ)Rbj2wUMZ*UeKHx`WAc0yE^yo(;+Dr+vR)qyN5~IVu$4%(Dx(& z9=|Q40%rZv$q>r$pr6FWmfoynV+xF_P=5&7goTrxHwOdZB;(H-f?V6+(^tfi34%-{ zl0e`dSiSPd5>d5>BC#+m@~1wO4$|ENm~)`4{Hh%wAk!?)c>rrWEDFl^26dbcFxtk$t^A$ zInRYs>dtCKhYQ$4UXsYNFE#1uBEQElsK!O!2yZL31pxZ#WDa88GNz)fZc--!Y_u4agDep3+8X z0c%IY4u(8{c7b`L6Ty*tPz;@$VBQTe1nPWQDtHKOLk#jlhN-jHQKrjrXiJ?QUcMQ5 zZ3u|V2avd*K>e(#9c0rRj_=_?v>BTV0-O^{?~K5G#O=Q~8{y%n~2N`hKTJyw1?djpT(LwRnXsLie z2;dmdVCesO$4q4Zyx0t3pIdy*0AArPIlx3j=BSjvmXb4^kLoSv5gU&Nh1xe1X%Im{gMzB`;M8@$U@gcRVsOR_PaY}y z07T^3hZAH(mI`B1!2S$9jerOU-+w|B@Fe6aY|SG{X~55)CRrB^7?K@EH5|!eK5H<| zvI#wTE>JLH-$*JurV_9PME%sUGYzJb`AYd*#fdAB{wfj*kfjd`hA;2oLK97;ov=Xj zgLWD4r|;kofRwqUE^jej^4Kv1!4gwxG#u(rg6&jf0f9KVM*!h0{hnyY_gCme|mh2-OnLIiYx6o*On*`QNrSQpk= zQ|B{q>25m_Kzlq~&J==4F0Zd2`Ma*q@ z4=$x5aY-hETZKw71zyl%P-ro=X=my*MJs$L zTWTqvsap=R2AMoVbs}6;JwVz9E%J!Di$-f=)iWq2(yZ|r%cLag>gUH)vb3dG10N46 zbK6EtgU*YUernZ7AtjI>xU$xIMR|iU2~_rKb(yMOA>Df`yRU8q#*rOsID@k83V}~h zZDhfx9pVg(qs6iHPoK$SBw;h&2o60vVZfG%ws2plQaX9M8*@00F_GboQ22*XxJu52)Uj!bvheIudRPF{9B5dXLaAwhcI@Pp6#80LZN_5}HqXCF2Eg?8dWGc? z2^%q$VGv}PN#_Z>1+N1E{;>u4umPaHodKZ|_&RohBhtI}p-$AK#_)DrIJcRKhLStZ znw!RYs5NMOTs95CD7AyY-S(5POfqkODLSXBnruljiAnpPPJTHOuH^WMe z3b>Iah#F}v&GHBj>69`qebgQdhy$fW(W^U4fy~%rIF83jq`EqvXzHK9z2 z!*UuM^lw@pe|F(++qYrF+w0`66YMY&aG*L#XpeQy^Sj|7VM0xa0qn_`j<^8pucj`s z9GSOjRHAsBsK%-+lMqJTaT}`2(YpQII!!>m9OKr&ZMYB@{6@`tsQsXY1P6{lGwnv? z(X816Uw_dRMt55DQ}>bC0lLz_Inkjk$6p*;)a62E7ar;CS#)3{KX$rk6I$J>8bB_<54aZ~r}Ih=gl9sK@Y1n)Q2p9_R?3a=pHQdTW8$ z?q_-k2)$74P@ToWu{!*{Rjn>j;>lll);Oy+DwQmsP=T9nh{ypoAgomF#y4-4hw3^E z;{ynB-iK*P_gWJ+fqNB9bh*~Vd6|pL+Y9uYBc}*ZNEibR3afw$wr)0;9;PYXbOZcP z=$YoL;qK(`127lEE>#o`F{>t6%KtP>s0VUkbDf07G?w~!EeOeavstxH40{~m2LSzyuuX5rxR|XGtDP)ZKKQR~G#UT=PDTwaLTi|@%m~`$8$}@*Y*=fR!ZVA6C=wcDuB%TGZqom2g|+UnC_edhI|iwo4C# zY${;S{%f$4$DTTKg!D;6!?8p~eL!AU)mH4Fdduxl3mtPVUdBPHo6BCD(bWc9m z(74Qc9(FtRZl_fxfNr(8;Nscu2hv487#`B2Au)!!j!_C}@+HQw)&T8s7_bii!5A?Q z=Kz2y#$yTG^RLkrPAi}J@iR7I)rz+ViLh4V?|KLu6LH|VS5Q+bql?QSwvgvuY%{CTl#RS?7}Lf$}U(&-LQd#>&P#RP1Rp$FRc{8E#-qC zb1?hE#>$ef7=;#-@AM^r0-{z@)jv^IQR^fR$Pi*w=GVQtTm(19G}P-3it6=;5CxO8 zi?lv{3nW_1qW$yuO}A#k>(T>3j*Tm3k5oo8+Q@DVAyA&Jn4^f<_fj^ z?SzDd=>c{j+!bXhX%R!9ks~D`sRqTIcI>I#80`mKzt^Y|jL0c$;i{PYl zf-)}3#L_H}>lJ4TE2I+h7h3u8+Mu_m)y+!ym>3KWEn(G6CoxD}N}2aJlukYBb8h@f zM|F%S+yKq`bRuq_#!^Q3^b0xD#g=Nr`2&D{M$0LM$dTpb0^h(&rdSodYC=d0$q~+O zDs9;9>P{AT@=RBlCmzZ=J-iPHTsi}4S6p-e1qrtJWeDg?06#~F6b9|6YU;r4l|Huv zUh3N~KzSp_k+EdMc&XT|ETYKXIB4*^oc3O&z;$emw;k(crKYK$or*mf7O5emLQvSR za=|!4)iR(8ORq>a)-mko$;ObTKZF&|!xztGwa_fYHd_wxQVcXmDz+1e!!qi@ev-xH ztD#XbRR|mlV2xLn7a0zzsFW24$JWL&FR1}ZE9a`Qr;zbg2rb^^rMQe)(3tq+ix}=S z#VD6CqR-mBUkxuvc@3*y3X-u|rl0PDBUv#O#vJn`KX&;-WfMH3(tGMWsUg2)5auCX}S z!0778`KzV8n-SEtAf7iMBccJQwKDh%1faa870giSU?=5tMlN>q)>TZPJZ|(be84e}Cx{r#$G- z*=T!-w^~2`TNmHeU604&k^9jFZWn*@JG;vUEB&KvCJhqF zp%YFSr8>)Vu_CksB9q=dzM`b935sH;Vyz7C+$5hRXz-qj(A%Q)Y|wELR0 z6Cs3t9b`f%60V!?^K9eZJMD#)<;w0X#1XGVI?q#-dc+aV$dGw~lhbwHj_RuYd0EN}&&ZQEw-S6;%7`uR-c56hgQJX9%6s zBy6X@L5vJa<`HaDGgqwL@Xb>o`mTEX=4W=Cxq2N!3L$rJ$aez|kbp&CH9?37+!@h{ zv^Ii2zO|U`nUt1;?CKiF5fhN&CAiruSUPRH3BWt#j#|b_C{Xf7hN4#Tinu?+PRd_d zDNiEeQOJe3$;AvpKDld#1%e zPSeD9vNNCG+-lJp--teX#{6J#Hz=V<5_QYPSD}WK!myR`bp>t z1u!Hf5D=wId9k%+!ifC|b|*Of#sQi<^=b;8FiSlEL6xH5lPHF6FddM{^!Mw?2!WF@l&Si^)poA#Ckc!07frL={?m!P*EIPq^}cCTdw z%Y@a&E@WPnRH_#xkrmJ(l#uyqNPV(+-5D`<_v}&!kaWE!CL6T2A;cn=>4=;Qro=C# z)IuQ>Ih|(P5hZ2+mEKRfKnM)#A%sIvlMw4fuX)gP;|0ocqWG$iC+opj%GTF7fB^A9 zz!<_WKUp`qK-ps1U6+Lt2o*+S74`SD`C${$6>rqKnF|N@+6w8(sEID;PO>c0APX;= z0s|}IVNd~lC^3%=6rV=UxWxKGNSPs%kSZ~ck6xuDCH7m^1Qu&54Q7=P=yBV8*{Ljr z7!(eN0FAh60v=^^40$`v8r?C08&N=k1_75q6VsEC7BXqfz8NEgIPk^X?2cXcyls0) zh{ZLq01G9(5Htt!1o^3zv;{H%%?p7_1+$>}z+j?(fReMtD9LfWIey=Eke|DPOg-rO zQE|X0j4+U@^)xVFMP8{VUU%WX%l8qZ0+G0|p&&2a&a$Cb-1Gk48?fFuB{3DDo? zQuhJNRAylt;Czj}sd1}B2Z2$yt^haDAe9q?;sXuRZz15f3liORVA7$6K)$4t16pXc zoyMR~v6#F542Z*op^8QJ9jVeSa{p(VxuUL%>bafO>oz>i$mfUz&7WF9mOUd8v`(zp zunRfOd8R`-_`}73xaRGx0(Y}@YgUX6c*2l z=7t0bWQWN2gLzWygIypJdut*mAM(gIB805I=59m_z#38FgQN)(C0V*Gb7?v^HbAt%-in@dGNsYBq0 z1HyZrMXiMF%Yb**F56(8%c-yMrnn7!#|P3gRGfJ35s%U93wNRIaop1;O#p(ZVx%Rk zB#IO$Pi+(Lh1svsQ6JKJw3J(^fqL1nZ9LHgQHMlv2|!+|j5(kH3RWV z*hRZw$H1@#xeo?IeoBo}2hSQ}iU5yd^^H>F3;5i$BT^UcI#@0{Brl(d*iTql#KpcX z-t?z%st~E4ew2o0;3WwrQi67Y*A_XKFbo&vrU%{qr|ftmvI|%ks|Ylt=iT%DRH0xj zgDW1~t5sM?kA%{ESO`^w8>oj0j$1bNa|5`T&z0^Jh82WmsLkl+3NyFrXDal!Q|E)f zJl2gcdYk0Fg+Ho~n{G=!V50_Xw5>_O1ORoVvu()WK(W<1(WFbezAj~Kqq zUXI_5k<%HN`WGi#jfij=>>sg}fsF}mw02M^`f)$*6xsm8`Y^y-3AWy9*h12)OOOUG z{@nb?CKW|L=al$??rPyg zPihHNcz){A0e=$v?p6vT^~J&!PT@6c$gC+t2PFu#uC4H*Tpf4LBCiFXh#oh|l^n$i zOwgu^!-|VZ{qf|E7#U}Dl}DD8u;_JHbSSLf^@YyiCw&2MqD2v=_GGQdg&W9uGLZDb zTrf!SXegc6DPVN%AJ*cc!tR9w+&g>HLAbHjK?$l<&w>sp4l+mv29u_1SAE8flWq2< zpius8XGxGmNDxqpf4HU&X^&l0h&`|@MQJ*t`&=D_3o>6wO+~b}Yr0v!;~Str$6k25 z(B$PQTi|$LZkT8&SOHATWx9oyg%#RLB+D}n8lnPca{C?G85pcN+0`gb<7O1J$xxP1 zJy#DDp)ADIBm_z^((*?5WjolbjG$uyS3W!If-+aHXee_a2wMJy6q(LzJgI{kdfr)8Hs{0+_G9dGOCm152P&ooRq4)-Xh)*iS0;XJn*wvv9 zxKdaqt9tY}_P2Nr88V^x_!#JNV1E{&3NB3bAgF3UFPQK@$O{jR9@MP<2S^1XsiGn( zAy`aI@S$=Xn}fr=Jy{9uwlGVNJxq4%7Om)fg?{%EY&%IiiW>W<{u4q1v}Z`U?EAYB zF{&ynng|yj5e!3><*SGqVOgHRVQK*xPw^b$+IRrZ(XZ_C8}B1a)^z-W>m43iGp36o zwl~*Xm*~Pb`A4i|+DMLr`~iU6fW%!j@W=VL)FIT;krB;foj;WJLKAfv<^XVT6_^05 z!mL^=0Z)j8)5}@u>Cgm*2eo2=CJ07{xB+#FR2k<7yE&1gPGrpXfxoq5a4fm52q8@- z9!!0)MY)sr!-B4+eyeJ$1)Z+*OD!J81?A&`(ea)kprL@=2-7VP-((RuRWAZf`qoMt zf)gPGL0Bu*)Lqd5)Ob11)5G+Iba-KJ%Ef+?dl6*IJjlSWkyj-g3f2VW(2B>BDUT9F z^TgcSY$p_gHdV1A@DG29=?2FmfalbYOQ>kT5jw$#HGGtXW=rx6AO@rLh!h=qZ}emT z=D~Mv>7@0Fux%Ybk`|t!4 zRMhE!LzHP@>ab*(;MU22Q}xDrRudo)wa0ZdnE@`9Jr$7)2-v46_J@$ezYBUZznW~0 z*s=km2zHw^Mnd?dqkIBFE!Lc@@JN~!)!w(K6ZquZ=h#%4hze7Kugri%zc6XMLh9RX z&3;lNp>}I;<=G)*lsgf14_kw_UhgsY9InszZ^B8Ra zMporcwoODXm`c zHhGeO*ZHrI4deZ+Llkz#{;_WTw}%rB3` zM>D4lS?hRD;lV8GsXvDC?PRct47>)R`9y9nCBMzjy2qD{8XVvDSk%gq0@sl^M2aU> zai2E@v()P^>Ka*elr{%NV;EM_-t}fPiC*y_T5-s zB?18AZpio6_}xc=cV%_mpMym?VsRes?dZIO$FQ9^c_}zxB%{u>^R^~PR&0qr zPcGjPz_f5tE#O*AUo98*HraavzA&KMmnV$d#|R{s>uR;GK@-;c!~vF;IySQ()YI zYcB-O2~h7#&pzE*?=jv z;n}nmzt1Iq=y2fNNOOibI1gq^$JO4crL$(xDg`^}Ee3@8eENEt&|*8TUC<}qO2`a_ z4tc>L!tO&Q65ZUv5X(;aksNafPCUg7XyuRRN#SiQSOgiP-ao7u_RuPNG7--8LL>d3EUsj!TaA+Y?8Nh(_ z#Nl9tXA^Kzw1LFKaM5}0)U3o@o^H3;qxX(Omfbk80FR=Tl1Z!+s&uCwgu$fHWx{a| z45-W{7I2G28*XP5UKX}WEF(W zFzhqN5qP3I|NnYy&;z27^t$#^ixahv&XWW!0OW?UO5E~?_k*G)W+X-^;2PeOQ7ezM z4qWK88kUk~L4dvmdq_jQJ6r_``>I@p1$1@Y0g_OfhI82H5YZXeBk~={*41a4L(*?n z8OXu{iRU1j65gbnr?6LD9ZPTFE(ZSn@%d=cqzi8BN0zxk>YxX92Z9vp1q0TZFwVc) z^hQ5AIm#+pH-C%KG#?lga1FI8@NsYKmpzO{6{c7vv0VZgh6F@|Nb*7>Ko^)`B>AG2 zc5N?h>QDOfzfUq~9$7b2HrB>me== z2j|Y=k6LUic z68r7~fhB`zP1rZWMr=3tO!~hMGo&a^znN?J zMM2nYqm+us05nlma0rcT2#_Vf@F7VRpbFbA^6qlYJFLGb;M&`U@!fE#&q}cu89V98 z0-EgQxUJsXHdi7VTOu60s(u}KxABWQ6PBjQP$rT&@-l^RZHBRz0u6|OLpA>1#Av!D^(UaCfb)O@TMo(?$SPGA`f&V{v?$M#JQR>eecSMH4u7hFb`&|mk$0Q|XpwJ_$i!3pX zDxuD~V{j+DR6#>j5q%=Lyl6bBxvi~fI}$`ybBiyUs*OkgjlDaK{s;vPUugz#>MzSHobX z8Hj}tiMxWe3>ujFhFM99AzOm29A;0c7zZ*afjW?<2%-hXG!zZ-q$q{BTgJ#fiio)O z`$UgoD1n>?nT$SR^h71$Jr5ClFXrckc0?QWB+Cf%p1O1>x;4EW83tgiQq$WO`A7sy zy!4KZz-sb&bK6PWzez_T#fYHy`wbq??!e)zeo#LnOL8{DsHuJ}Z{a2r3^&^uXW>1VIsT3^VV@S|hBBy2|k4c5aIQ@-^KTe?YGbf>UTd>WSercwJQX z`bajV7iA4tuua>v3mx~nZ|Knv7mqAID(2C%nf9R6#TIJTh|!u~!20wfBiH{kUL`-- zSk3$iRaPE=-L}rC(Vdbgg6o?)xN>lN+cD_ynA;jtF&BN~yFeia2GCfNpzONlg|ea> zo;SY!LU%@phh0Z$4>hXM#QD2G*GZrpb)&~o+b+@6SUfSyoW5%HqGk1sgR-*k$vT14 z|0_fj>mpY7g=3e(PL%Ete(DCo(w+xs4$JZEljQCv3QgZpS!vS;l(yjqEYNi|LCdok z-;E1&*$3jx?Sx|TLsLd~B%90avte6)c-XPZAZvK?3V~>l`pdf8>a<04gP1mr&xI9e zAX>{(*jaGdc%^Pt{ka|tXwlvNHBA-YwJURzBID0!i`Xq4nKGFJyGd`YJHn1(t4c2_=4VRFlhmiO5swb%cZA}cCK-Gy&<+Ch*#9KM^5bu z!`H2PjRd%YX3{P*;*QwxC@7CeegXmRZ0Tl(iYIckYf_Rp_gnbU0;9lCUDXj9BUSi4 znFyZwFnz^;w#>>4yM*E}z;Y)W4a9)x2>WzmJGFIL9sXgk%O2kmMhbn%mFLm0nkFWz;XEMCF3G*Y ziMk|LToB=zI|-CyrFbV}men!JZ-b!Bu>J2iKoBS{xqObk2@FJ#S6Rd^T2%|2NdP3e|$qwtXlR&OI8q(unE^o3xjHD0P^p!2s5E=+qG1BV8Eao zuZv|DQ5Ex$27xs?lq-}JabqAeU+CmZE_7?vG$ z_O(whvCT(XR9A;gs+NRrIfMrA7vZQ!3^d7tE{~-@>U$jEJWKCfug)w2Lr{-~4r7*6 zBQ;I(q(vmY-CF-;!0V8%S(H~Udq3GA{#oCtOI>65>k=I!No7h9IfW3gTZ56sZ$u@~ zX%L4w>h0vp-r0R3=={|6LF78<`wxkmbO0vwi)b=tw}hj0f5MYFLzg#K{5C>d(9;53 zJOXfT18NS5w`ss*9%g2Vh7&hw{aWJYSOZ6CW+uz4og8B6EVpW+d$E;Bik{KA=`E{K zsoRwlqJGFrzW2=e#+dDqrx&VrgnYpVVOaMC8=muwSdnymZ0SmI4+IEjNymzKNpf$5W>Bu z!UK=%7{^dFIY5p3m=-&wvuxv??N8WR6&Q~?&Or7O?3i(sad)4c%qZ=dfn3AM!y`*r z>>>;z2ngZ_8Gub+@R~LzBeo+Lu&Md^H?q>P1VI3na3jie?e>gknZB-Qk69H-utg;9 zH(@AS>P$2D`znHi4p6}ntP3GAh&Y7e%b6hq#1M!2g<PSyH&Vsfa72epBHDnUz1RQQ zf~pI?P<5`kq)`8_l>HYqL$E!0|7&ECDu3WcZp`pik=S_CyS(<|ST`t4@|KWx2bmTj zEAIHiFu%6O~HXBeP7Y6%A1AQ!79{#b2tKVY@7e zBXW>kE_r`>6f*R=8&qx+v_Y3J*6UYusNyGvR$S=$%7`e0JVx;dF=}sB=Sjx0TP1LR zE|cPN1}%t2zA&aluu+6(xM^T9uSv5DBVrK;8K#;BB)HGWQGoww)Kh(7o-`!e6B{lc9S`=7O;O_&n8` ze9r^Su+b)x&k4_2Mo2E9&B!$PruBQSxZfZzhJ>Py@071vvHZ~R+5Zz86X{K{-S5xJGJiizKC``K`h zvMlVM=ZXP1#co_=&1g)QRzwhbu+ib5!7(gy!Ijs5AvJaY!J8%)2=r-d^vyZ-6-+aJ z%NQUTC}k<70SK~H=CP!eBTcZ|N(U7-_YD=kUK0So8+AL>Z+cRIN0AKxjlEQspbs+y z2P&}!Pzq31kN5tiRkd8s#o-cwrm+T+CuC-$A!RS>kP%wMxtO>*2ox7E*FK5A zL0Of=dyW<)S2;?nkmX}80ltPCD1tYDt0#FC*M@~xlzEX$04nw%S&frL^#2`Kq4kpp zB047lx@sJsADWJkg$`+}scLigfxy!;sd$nTRwag0 z9tp3lY2Y|!6v4t`T*$~g;#9D}Mx^3<3BAfC7mLiyYD@$Qo~3J@98r_^-8Iq-dWQ9E zFuw9(ss;_26|6FKC_=#Ty4+y^vWaZ^G`VIn88eu^(WuNYo@wGCO*KniYTlGj`y>Mm z%7ySG8c4!BTo>Fjj4Hl__W# z;)yA9b8zu2)8pf*7()d-pv%1xvON zX43=;$#&u@&}Q$2S=24J!&MV-L;TcOQGD9N6(Jv~Bk~hBak;XIC>KNd^Kw0BqskDb zSK@1`)e>^vl?v~yX76H)#g;vBDHh9^29rqwYSfSwhiiOSSPsRbLM8Fy&wG!ehFbo= z+SEJNAz6)}Q9^`-}BYW^RKU+P1J@hN?H*GQMs>5Rrpoaf-j%5Xv z2+3vpBv@;k=s_@vi=H+newxe*KsUx9NUBK~5FBwbtq8)xv?B&bWRpuBzPffNRs($z zj@}0YddN)cI1#b2?XigWw<{cV#6w^G^gh0|Z7_LuN;aE{P87$}lE(siNGFI~o(w52 zGQ5UCn4}a8;-Y^ur1(ti#B#H3KBc`cpdcS@6o{7&KT3W8&rbmA$28=hbks!2iN>f! z1Otl1Gl-V&Hg-L!vKE2cy*9F>sw4J?kZ(g3K8KE7rO^VluMuFnkQTS)@^L8=F(F$R z79Hx1KopLuH;EP0WdUPa#2nF7L`9I_+EzKl-$c#^tB<{cH$tOf875a9fK0%%c90N8 z2j!A~&~mgSs{07{+Nhtle<%34*Xh5UZ&001N^v)*7$C_mEF6^I+TCw~d%yEU$-2np zcXDf$HGf8uI(}3*{A$d%0S_+jLNqL3TNo4`JEy(hJqHyxP(+(=2iK5~8gWY&*<92~ zu`5U5Qw_i-e5nMG_lU9Ts_6SA3{6jX1~iJ|J07%m;Kr7C6dd3n7}uYfKXpsa995+W z_jC+z=ZN?E0t_FdUPzT{O)6yo?b7zyguH94o40ny@`BlHw+9A7@y#+^od#Ua zEbA~Z0fCv!Qw(Kc3lyp<6wZomcVAu;GKZPN!e=0nDjDGb7r=m`8ogI7UiYmj#eRX^`g#ij>Sw^};S zGC@Wp@PsH&IBmqHzpWFjAWa3*-kj|;I*HyAlr-amnK$%ov|uBZKBb)c1~k-Mnkfw6 zIpkFwP{kPEz*hSft*=+V1lNOaqg{}GD{sxDfKi8LCS6gv|54fWAizZ835Q6;6>Lip zJVb&hwm_sY73r_r&$oYK)NN4Db-q!K(qAYL4JnR5QdHG4M2+;potM8s{E-qQR~=gC z!f*J~>AMsCLUhzCHoF8Wzy-v0T7D@UmY9DL?{LBtWQwLti~XDrz)39I}^1f-1#; z?A{}^2|Q==bVr}9*12sF^`FR^AfpUr=5aqWzNc4eIfH`{cFAKzc#CGGZQL-`@_tg| z%5?}W*fu5L(uLf2j}c@K3nb*Br6A8>|$XZ5Ygd-g87>hE$V15IX4sgG6^S92gW7 z^_)2?*x52nw(A;vl^QFt>EYgie|0=VM!!BfFu?I`V1usK@R9jVeg&R=AcxF+Jc;!~EH5158z}D^x0sz6KWCX-{ zHI<{rl| zbUJ0p1=ho9ELJcSv=1j>3^`z$ZnMPMxqGw(6pJVU7DjI03_G|JX7G z6$hZ{R*zd%V#w0^;r1>b_Zx9~ zZ*G!EMfd`n<%?$uZK)1gl^UPuE0|dUnuEDclx<~Pp z1LQGZ2P`?fa>wmgG}NEr>rApgu_K0>HFZ&J%DtVU)62`XDTscOolF6Z*%3Yn)itnC zZ%X_PQ>M(Uza7|*why!D8%5-s$|w~7MrNP9yru|~Nxz=2u!71A^mA!WIwxCwVvKyY zb7&$R#uW8sGz2Ut*hF2tdcHI;BPO}4n;B}IEPKj*)SwP$tHgw)4<9^7a`KDf=F?@3 z@1Y6bfR)U*ZJIOBds5 z4Ns1=dF%ox5gI;MkFoMiiy#rW0;!qx;6`QA3nmuvnP4DDFfBI$c5f#21*hRMRcr2j z&5z<+WX=F(_7^~L$Uhgd7`SV5OjiQ0jZ&~w0M5fO@L0J0ki>^cz?KYvPS6A+gQa-| z_If>Aip@6wouKvMPz|iFv&w2#t2%A{$sJSOS*T_MHIb&-+o(-CjO;c^zE7u7^@AHN z>L<;#Nswb&{R$3sJV>k0YFmOOSVGU!AAyZubsAk3^D6=yR_IdB+A>4yIu?h0A;6!0 z#LEOUCQ72Eeoo)HCj>NI>L5PE{oIo>VtYGo}xVo_qe{x1Ua11y;Lr}{= zYWTSlGhyXnjGlre36$ZUk|Sqd?h0PE(XkRfcNYg_`e0sP63g*17&>4TkIqh_0%2wT zKBHVOtvAy+=8OvC%HgenRU~&O~1WxY;R9m-3l6 z<}+^)wz6EK%;J?`ew3frjyj0;i7h9kWPRPv*aHSDG0MicK-YupA*W&#hlKKE2S6}3 z3`^H>G4G)gp2KkQ(jE!u5BaSU6auj-E;S~mfc3#;xrBlSR%w7M!o_|9PLvo>2s}!F zg*u5jMuq4QzTgm(YwGo=E5VeAoXy`DrTO~FE)5!i$%o~I4;jo@2t&x3i|E;9r13EK zEN6xlGLCzeq`G{9+29Dwz-U>G2{&q=zy*Cbl`mLW`Y!}CnJE~ry}OmmA!8Pmn=2Z_ zU4}};K?}5dXPmgSAAp`qW_Byh|0S48Ic9>Y-Crn6VQs{{^j@`PD^R0?2)%K zH1G>UZi7z;7EksQ_2XIt<-ufipfd=URJ(-1@zVXf;cPzLqq0{)iDuSQwZ0`gck|_> zQ-G_6*Bq++U#vE!1VaITz%}-+;5~UY@6sxG&Nd2^VJ}FVVdoe0T~S1s1o1})#rbrR zCR@DZ21&A2Xn4v`76~p2=z7*~{{Q`d6-zlIe1Au1DNxW3XHGa_d+C5!Pm6xxGT}2e z5YkB#D@0}#P>IVI48C4hhJ^NweV8UKOZ(ugKXp9QfEj=$oc{E?M(DN4GuKe6y#gBq zs(4tSZvfA@Q9%PqkbeJFs?`J%p32l1X5xLfCRVDofk#hC=4b?1)U~ zacu-E2<(MU@g*1_3S&)(YU~gVNT{EX;T{@2+*LtSHlX7DU>}~#>$$ZqP+;G{PLi_% z0b(S?N8DOi;b10sa1rYt3YC5w=g|HwSwaC12oWr3c|rB*aVO3WI?)*k=ojrL`m>?F zO;2e+(Dfot!$dF_*mgn@T$4_sMitn0VB91&r#$CS7}J#3m=X!61-ivJJk1JR5Jgum zuc@{*t*EbAF?c!$4{Im*|w@tMqQ=$RMCF)b8==W`|jTNR!;Sh!hqX5DI zi$@8)C+^%$Fz^k(gbQNyP;#2=uKi39xNVvZnMk4`TO_CBX7b&EFb24@Md4GL&?{IA z^?EsC^v!4~urv1=$01=yb)UguS8RTSOjAWz{9B%19{Fcrh{#9cCg(>FJMPJQU7_s! z14d)TZ0Hk$f3rj3;1I^+am(6rHN7)KMun~XHx(dZ*&vnLO_MtFsz@k`8MdBPxb;z;M;AUsp^Zyp*na2A*)w@iIFR6hD$*QkuvPny z0xd_?hb-HO@BAx}qT>{h{?0OQ0(JxggUNzMVy|jU$j?+>$}a9{04~I(NquQqj+^W4 zijw&u79%T<%uncI<8Zq}?F>UPUeKWr34b%uuUfj&NyKZh1{Df~LV_wI2STdXP^&R} zNZ1B5%|z&?VdlcW#*=ogrM^1=lebR3A;4JkJL@|8a_U9fzd=-MLRHOKp*)3epRDCj zx*U45Vyaf~cs201I4=ZDTv3LK+%_1@W>$s6H#^hA2uW6j0vY(Qx{8TvhH*$xk3X8| z&}OjM9viS@A1m8~qt=C0Ya|bEjtv+#*lg$wQ5Rj9aO8AN;o1#2#+Nce636dm!3UNa zWX6D!hHyHkhfUawN4Np6NF9NRv9IOA_U7|xPak4&2M>>2NQe*)NQ>68%7`#Cj5F@& zHLJHc*u$qIYJ~!Wu2&|CQ308ibSPW!klKM~g9r%~S(35^1HogWT9Lm!ZZjl@?%VUP zd6SsfPy<=sqXOBW+7@XIzF7ahqo+D_a^x?D1tN}}0l;{c6a!rDu{nE-R_nK+%7~2) zPlEvbOj-IuUB-QuiXKY^6LIJ^cERIYnDyu?qp``2obc9%7Y+#JKV8-rvHm=g^TNF# zQ=%6@b%t{V{KvcxFg!re!YGD7(sJx2od1j z2fPR`=}u{^fp?*YYy}_Y91^ty5EzRA7zR4XR#l&8Ohuhts9VC5%Oia7o)~(SV&@sP zmIHPyQzI+ib(`ER&~u}4 zx?$o+9qh+Q6qodgL@v89ucEYBCq21KDCV^uz1HGE3-40HF;06?kTcNE3<9e`mUT8! zDE6k`$3O%$2(2R<+wC;Jot>!&^?6dx$Xl28i#@*HR?*cH$Pc(ft^O43>V4HPBL=HN z;3Nf)I-ruurD0^5;^u%=D@H6R!>w>-p$3QyJ%8W9<4%JgD{JHVmgdz5+~8WaL&(iN zen#f3dX^cwo;nEIHhDE#sxn`Jq&5?HZCKc%p-$n011OP=G&y9cagetH% z3qRUNKQ?O9IDnw4_WMl1JQTRI;EzRM1%QEG3wZ>xB<%=q&@HrRkr3Hxsg#Sp`0eM3 zf)+J*$kgIFoEH;n+~g3+3Dp)^E^=6rt*CFfe?27tB9E{KDD^g5{6&!ijmeB!TL{Cu z=%6kt!cdV;%iixxJP~gEQMuNMf*=A+XqwlnG!0Q`1s04R#!$fhsvezRWyGspga?(w z;oJ(^WLmM8Y5^OhaL`fv)g~YKYT3z2s;J zIm5UyAU$0D1QRYfl9}?eT^cS6>_q@p>pt*iLm3FKdn7_5D^0!lx-M_djq!DfEqkko znB1R|8Xa2YBHv{afdS>1BDeg)pB(s}dil6535ZP-aUzo%^R|=AH9}@~VrRGVYldeH zW50mq)m}C*oRvX>Dlm!If|Ah|cHfZG3=pt#O#<~;ejjNp&`g1O78&n9Zv*A#uoRHz zW04CLc{^Tx>fnp5q#USPnBh)-a&=(*ld~IJZ&yo;e9#}F`eYk(Rwykv@iw5AW<8mX zB2obFVo(haFaRQKBjkSB95Nt}x8+$SfH_V&Y~D3cwMnl^4iF zQx9duJkG0v49jpLRF2YhxJX(ZGoj%Gny=^f?ExfpZ;%NJsgI|3Hm!jWuKI0|w^4U( z+tk>q5^Nq;kyUCY%$ZKd;;EIJgz_v%Kn!wh3(5A;8o{~6gpkY_Z~CLx=|e?IF$WJt zu#w5#DrT9;HRH7(ki>G>W8$~)2(POQ!yNS*ST0J~_a$+Jkr{JQMvd{SS{se+P%1!q zs??f%+%SiBtWgUD&M0YeODG$MB@sH5)o`@q4Zv!_5Zk!HAU?_>9&#K?fKxVInxTE> z5zXymuB0fO+iziA^o(q!rR0&p@tCCY7s zX}h_JDXQ3WU=0tTr+_%JC{{0FC5gZyv$JKG;d5=K0Qm{>^KOz>H_E`DD;TBQAh zi`N803N(HBF`8&%-N#oYzA7t2JNeHpHdrej?q*MViw0!bT~z?c;EMPKeUFHH#Z)*F zRe?{low&;qivcM51YyApb-q*MOdb+Mp2%AURQQS=6wvLMuMced18IMKe(B@`*xQAw zi6!yycQbAf*;M`G)*u3Z-KFRcy0TlC337U%^cbV1l&%Iyhm<;sHu4mbaDr5hw@PVM zo(I*YMZaB`YJ4|lAqFUCbI-w16>Wo&_j#yc=>MXY&}uC z-zVN6P)hq&VSv?{YPJY~Qdf4ak0KzCJ8N?6lPfmrW-I^8X=`pk49M1xNZt zGG^jL3hHTJ5`_`KvNlh745Ubo2FhtSmG(BvCbw-pl9vnEu~JY+FmiKss0HfjLxCWP zNFyW`&Ivi|mm0Ddmwpq(vI*HxMq`e`i~x#esWlyw*oAYXlZ;9PuMsYutee3^^b=Zq zC1(ek53ju9y<%wqBFCv+vivfuGo7{2#nPdW^w4XrqXPOW%<9W~%sACU?j@|N*RaY} zl#Q+3R0@XN^8e3C05ozz;!#{`AbO)%EpU^lR&BTE0%{mq5}#r85b%c9&1>(Q0Po$r zKtfgSZn6!Bzz`no2?47$M4w&E+~RzCUUxENJS_l_fXgEgH|gQwwc^gv5(+?iRFf=s8NqtF2O>+bwZb<9nz!>-XHm?Zu(Glra__Sz0>VVPFfO72Bv+BRA(yXj=LqR| z7_w>HkFixo!G~S*S03S40rpXP7Z#z_ zh#kB_kA#(Bw2Zy?%=)ZP08Jb=kku1WH}JWEcAV$MF? z-1bgXg-Pbxg4m zadAG|8CcUB+H5=CPhe4oX@>Av=uXME(6Vm-K_~CPeE~f_z1oF0EbYW4t^n)2cr=u1 zSTk05CKL&7^wQWuZ1_M_Jwh=Hu<)?C^NA&`Mmoprti5CNQnup?eSpBqtr}x(oivR=%DFe_j0I@_s zG(pCrvJ&MqvTD7H)`;fD~~oZVQ*7rLV<) z_^_`1qsS2ec9za9Vj{&p#F>f=6QWxJ-P&Zk2Qgv7TGO`CA{+Ru1^I1OUKQ7{engG( zR8%K5u&h9o(1u)Mo*5e*3}wa@?%Wc4qkKdjI}Sx4wyUnP%+XkBW!UHA6ByXHPh8o9 zL^=pfYXrr^>L{+XFfRi1MvCQO#6lo-cS}7HM0ywJ8N8Yo zF8wiW+}7Q0kF+cyh$!)9Fz!XOuptKnazzU7f2xB7GOUbGU28kmppnnUO4B!J4=&M_ zT}WkAK_5cT71kR;flsI=4Cxf292EeBc#9`6nuHO7;ZQsf^ziA>)Hz^wR(NOpJmbi; zI1WVN;WE~_mq7p!RseXgaZ_shaq{X`@UA z4Qy!e4D2i<3=AN2z1}jzTreXG22ddkm%HGwnmln1L-`uxI1A)qKx709%azbDU$Dn2 z@&pFJO~j{6o7AcU9xUi)yJ8Hy-S=84HJ%py<#m<6# z4z#koU^7N^aBMmZj9jF+;;>&y4Q+&&sFW$`0k}y_&>wdRF%NwYP_=brv=s30I##~Z zO+r5ogMd<$Of>?ON@x#9L|R%7fP)uGCb&;{vuTV)&Ccg#N2l`>_uRo$i21$UF=Z&? zD`dLGKSsR56L6}_TK#?qWilYdgjv`~v6OkTfvM%M?-p_~D6?+a1Iz}ef*@$!w)@zJ z3&SQSMCRXQH*n3NuOk5F4%l`YGXjNmT$s1GUJ^{qI=FApovUtDx?ckNRtlUIghv*P zwS%q6yhP}646AO^P`-HR zA_GB8N9k0*zD`SO+Xi(ioB{=&azEw{6WLgr%39=ePj?$Kgwj?r4zr21q4{Q%NvB;PzgqA;s97uP_Fk17~* zr`(Tjly#8KX(W{96Qq==uCq35SMHVvs`@n$rRvk-`33Jt($nE0eigDKuRM8JA z#|op1)_LbD1FpLV8Yv6J0iY7Vd0Iklk@x9vL`BJDQk!tHhpeZALm#s+RqgV?)8D8@ zu&00&$0IV`8WG@S2V1Vim2$_@X&;2v)p(w_nO`s`J6|3XMSt)C zBq%C1(_FTrNdK%X#A7AvD`3?$N%W{47H+FQ>fZFCD(I{r0%6|pIxMocO(UE{=S5cq zQVG!4tje(`kCDJc<*HCsS7B9q&ZS6xu?V$SD@eWwC-OKRQI}O?==OH(5c#mqi>QA9 zN{e$Jn`@Ejd9m9CESa$SICaozbo5y-1=zZ@kr#1xKvnZVJ3wSdIWW{vFC|CAYeG<%c<^Q3wvp|`wqUvFgZl7-+jv6a{BX#F z!Fh{lf{t|!)qLN{N5Ip*{d>vOtE*huaX~K+sYY2GKqg&I_QJTZ;ZfL1cf|TRAz_*} zH~|KA)(;VI8VpO(c$t)vBBviIO0g6d5Iub;ifUo37s&*E5!nNl=Lt$3%cJJgCOVfA zq5`K zPy|G=tJ8ni;%; z%A&PI92^^r@gTU3B0PmOx~_UJ=W1-&XkkajH!#z|oW%ozIy|VXQizC26hlG^f`K_x zr!p#m-$5sbfI;L8W(dh5ofC|U-4}VRrbbIAkh7jjMtUtmKhMb*OZwgkk!W-xf(O+$ zR$_~1S1iTtFnS9Z(Yb)YWSo)43!#oDi1sy&j3coKZaKjtwgJdkAsja)5pqfEC`qzR zNoGq7E=aChc4+7BGEc3z=Ky^HZ9X-O%ND^88rtvzLK|p>ivToyijjwwJws}saJzfItwp4w}?~;(8^W_sJ73gsMUslPwPq2t`UjK3`VJc;(gW>*^e3 z%qP?EtlpSUqv58sZOT7e4_bCK?bs6 zFJvvDTm@+xWCK72ZBeXQF!RY*XJKvSCnir(!`}#ciw{mU~iaLz0@JHk?DI*aR=XpU`dFCHSLZXl)$?;T`9K(HbB5) zzN!ke{MelgB8-5hZ8~%K#l_MKL+JLz#Gh2@B;l7*qbAp!K|oaBm}FFQ7L`)SOW|S& zv*GDsrv^8~gP)!?W383L$?33G6C^R@&*hba4@L_$#wUp)njPKr35f~&oVpxF2^-Cp zmlx<2JN&aDx4$BH;+JcnZOaD?&gm zQ_qna6No<}M7pKz+Gd$=DKc~t2u0U&7_+bd9a$jzl33U987LAdRf!Pudj*}kZUMl_ zTIRG5QpEACE98O~9_L z&&Jb3M;M|fo|CU}^%7 zY&|Ahkb!o<`FsH^={mH7i@x{h07mzu{F>2{j7XO{;&ak`C(`aFig|#^FDd(9bGcS2 zbO^UHG73{N-5!5LL`PINFqD6)41a!? z%`{9zHfE?H3>rP}We>r!QQD0cF0BcnS)=H3p@qLD@A3-@ksXZb#f$*Auov_(#1TX`Z?_q=(;-?1UddL7|E_^Qv18r=@Vt-sx zZHy}A9S>qcn;z^?is>UQ6~^^oq(AkkGY{W+77K_jVN|OJX7nl)lsK$OoE+vnDhdYE z)KMaW51+LdIw))+2?|;|9T`hn6hP5OniS-x{H+BOh%8wI*)&4{ATAPySwrfJl-ppU zZCDO#Hm^+tMGAsa-n8d3otmanzjh@@*5`Rj)hC0dgD`Msg~KNzIx+X6k6aKhJIT=X zFv66r&IbZFnFfc*l7$HaHX46#dz8J(I@ldJi$Vk@Cde?G6g;FV2>``YQPPAT@vvRT zohrVkj-XFGHbI+`I$NRLZvrayhSvh>RK3z);xR2CYfkEMkGfT33>d1SJ`cW^g+gOM zGh+xbgd`O#zK_096@~x?hfW8qjU*#_Q3&K~WS+wWqvHPRF_CF$iYOpXoM84N&&U!| za8>@VEE>$=b~xIe{SvqiLU?~wR6m{vAnYrOyNT~wJhTy^WNSv2)VS+6j{Bh8f+8#L z@IdvpI+cw+f}G|V@O}oAfELHc)J+k{V@b0Ocy>&I$=nct+?o_!8fM}a;629Vp`ql) zlO+X+>_KR*Q5n8>5Lx2HiN2@0dQdgyX44<<#MVwO<{(&1fDLP5Po);Vm0oLr0N(}^ zb*g>+G=0uxi!{g4t65lxjn1e$vsNHEOwWZq9#2>1g7s6rbl5;UtD zE^_A6^@^sHSY_e@(y;`!fRrXnqE?8Jy_pI6|FmJnPyk+^0dG8t<1=FOj&d?54B{o1 z9hC__rZtwm*d+3!M6Y*L*Jg3tAMMAU&MbHWDdBW z29H?AAj_q`)e7?k)j=4eL))kc#NggBAjf4&h){71ZG?6aPMiX^G&zsp2+C8fi$XhG zSycTa^emHAY`V5b444!29%mm>_C*41&#ovfjPLgoHSn;K<}!-S52d4!h;hK%dhp>$ULr9EP1YNgW<)QEYvMmpNp*I6=*ku0d`PTc53 z=$60sg+J_@4ngF3uvN!-C?h)bOm4d!s^pn!8dAa@rk;%WiySic3r^xda5fftJz9&Y zh$iCVkzAZ8CnPLTiz2<+mW;N-j`ov0WizUJjZHGs@ily8C|`u>6Y>%TQ3}fwVg$@l zBJmjW8wnzEknFEJS`xUw9k3FFN_x78hgQE5`(VQjGIa}~Yx~*AlwT_0mliZ`=a_JHhAz8Xz=A$Y2P#dq#ZtY+hBhWcf6B*Bx&nlIDRY z+*AT6&C=3toK2^^Lg4yiqh_#21YqLRR|A;X%&Tt`#m0upL&70q<}*9cX;qv3!dZAt zLQWQ`L%%=B+XK9WSid~jO6L)GxTc4_i`Zz4A4fBNuvl{Uo`oD>K=dYL%Ubu4&2Etq zG7`{=gozK_s-DlHL#G#bu>eTXFz`8lA#-tepcq!XD(~w}zZn6_j|)t8p3|3~>v}Q4 z0!GK~mdD{;Pu=xcwF1qT+zz=*MUEl)#2^GKU^VEhAQ)f)^&q1GrwAH)6(9TYc4`l} zq@#Nuz>NvU7a|k0i~WLgH{-ut94Rp3;sgh#E#sPR}NL8M>= zorSOl7%));-+(X-oeYIcS+RYbC{d_S(FL#*&!X<*~m5`#6frJdh z$#RD4gcmC+Pt*GQE}5S|Q*@s1dYZ1nt}~mMm!8#v(gXl-M|d!+>|R8o=Kl@Ug5;3^ zq!F!Ka-G{gth%?Z)qvc($t{3q9#&68W_+#WWK9MhZwBh;py5o?SmQ)0zf}SOR_EQ^ z4JP@QNq=|QWV!5puz#@tk>sBw`n%@v7Y;pfo*glmUE)QIqIMMC&vEWjcPSVE+{`XBJ^Nra%r2RZdq z@qHW~8UN7Zlq<@0n22_USRL@-^DJf=C9V1BFV#5Gbw?1PIYn>#I@a0pGRO3 za%gXDb3a5!ieJJ23Q=g)khcgPPIC?9{@wLAhd`Gbg&lq6Yqg6Ba{^+O#|+FGE6|OM z#@VF-izAIfA`wq57lsQy`W$csZgX33*Gcu<>sZg0QA!o9=R`|cmh{ABexz-yr5hu$ zk`ra`NLJOw)PchOhkF7ybSm4*>(TAOdI&cH2dgG9t>wr{P1w9I_OcFq4uZ zO4w$RB#Ml5kWQ!Yg2>g*<`vH7YeytlTui#$Zv<&1C1G9{wh}1PSwRyhB&KfuUSIUH zK-M(molz9u2Jg4gbiE5LVwBDt#93Ib?X+l?`yBZ{gNc(cF7TIywZlr=7}st z8w5xQAjj=E4!K1|Ta&H3A?P=iq{brZu0#GF#9dXC&v91ycV{_B-AmQ6FL|3>o9u8Y zqnf4VB@*@c=22R+hT^lHwZLi>B59l~5RQ6W|$+Z3LI>#bQohl}w0Jr`rT0qi2IFp_wpu8>0I)!-dy5E}OO z%BFs>Xl%ZKZ)vST1#|0R2>P$8384xSyQ4fjf`cx@m0nGd0^1-PVO=*6!@KJ82(p%;(jX9b(xzm|5CgL3K-)1_f#Pae`ekid!_v9`p-fy)px3z z_<|aPb>C`$ni{p+tr{JN0(Gb-k^{-SgH*gSyLQNU=a6cbh8zY9p*2bO{t}b~@|}#7 zkYpk2h}?eSy^NHQELj4?m(R)lc7OlpFUk1`GWGfc?|YY|{6rb)p%0|{WtJ|jf1FW2 z#C+z1Ev?WFP|?M6?HL3gVQ!;M-#?H-Yj`{!+tj z^NQkRQA!Ii47C|<&cFnyU3!I>0}UWB=0wExzd3Lsktsyc@I?@?BnvPDZD??76?xk2 zFUT!yj&aFtc9J9ux3ga1wcPmHXc%z0-OPf_GmH*-#zPH!Nds#1nZ`re@m331v5p|> zVj2d*x2Ob|OLRkg*yJ-zu(zhhg3T!vw{1mckfOE^YiS55iyER6vxM^}+T`F+m|e5W z@F}4p4;yzEa!q9Z1R#=LmYS^GQ4KuM3M$^`7>QjezJi(}5In(wAOsLqojARcHfkF0 ziKjF+O0(lqWd)E5)B?pb)X^a&sgzyC8g0*L0po+fj6@?Ulj1_IsD&$@iqw%LCx1M7 z!`$`BeuxF`1krp#3htqz#dc3+Jnlw2T5Bli1p^^vKHy?`BH&jw&uk;r^0hR3D%7K+ zBJvb{3n>KKq<~p(|pa9+GmTs4L0FB#rGi^-0(%)A|1IOY*Xk$zyLzRXOE%QD` z=}j-y!Q8$cjhp^~1g}zJ%LPW*IjKaGjHP2ym6qtl9@`5;{odK9}317cC zI3xk|B{kcH!o%^;kP?uyVRXK5Pn7zHmdW_O1-OA`Ca~{=*vS@Lr9gmwh;^`Xg7bD! z7FlC9m9g5aIN{youGmMRy+UvYXC3oMN(SRqbRPEFy+B=22nkaNXBzpm+dF)Q4aaC( znS>)u09X-PS}|~|b&ZTx{w5oFrxw%pQ$x^48mbM-^DzW)m9tTxkKo}a_&UV(_91Rm zn3Mn@uzw368m}SNV0#z}Hi__HEqZ2ET6z*{{tU!YPNyYgCnKXKfRQ{Iu-%Ex2#6^R4hoDyjz@E)$YLH5zw%-L zB|r!SAOK-umj$L;`N1Rr;Kq1u`xw7x{?~U6Led8S?F>4!Od!WyB$-o*`?bVXvPt{nfyNi0 z$9y(yq1Jb4bv;*Uq7Kt2exti9_bl77jECcN%MQ)i+ph~uta>GQ;f1W zW-=w%%jei*&CuTwBD^#_UIsQsM3)#J5pYkgGvz{7PcY<(;JB7eWV<3Hc@j8@2P43T z)+|C6K!+BfYYQ94VR0A2#OUa`fp}a+A#r(-rv9)|1wvZu@-(b&CwDC%JZM3Sb7)|b zJq>OsIfZ5DiiWTX6QaVR)Iy;ng&=B$AHJ&YHfH{+Gk6SbQOgsJC(MO9SsnElGtl-B zh{OXUKQ=`RfXwqC16&8GAmQr!YakZEf{;r@Ovd`dC>-*Aw8W8`W#1=|K%gavOiaC8 z#=a1Ri6BFsUgAST|CwEe2#dk~>y`}X=p_@$4unzCxr4|hx|Sdyx+@aT1hdS!g8D;N zE=<@r(xZuP4y;g|R`U;A5#=dY3_KDgwcC8o!VqVb7xz-<(zcQi!?vPexVdsRsAXi=-ztxkFYf7GFsa_Dx|MKLx zmgy23iys?lCZ{Tx+MDreJB>KVwfG)IxNR~iahoQS*^;eZ1y3Xg zQ+un??e@}NX9+GNb9&V!OMpyF-TaYLjt@1Z3vnim3Nw0((Cz9PX(UY?k!a8zKY9ou zxC7iR!_StO&}v^hdB!7ox#ILknyvk~TSlBIKBnl)>X+VMH+ab?Kt^9Tcon{C0+@qh z8>Q<*K*nD%SuN&NWXy%&CiE(d(U->*X22n5_c&tWS9o_!kMj7UPa8|(FZ*vB9T(-h zl9L)k+;ZHcGzzk$#F%^h@`aAhtQp~5J=SIWkT9n$4+!WS=lzsJ4mC6@Cf zlP_++z`dAb{gaInJD`etFi~L=cFX%q*yN}Q4wJAD$bH#Qp*pAuoHK-L*RT?;CvJ@D zo$GOY@``~aj0n`V4aN?%MU3uGLbwr#7-!~v0G&{;iqTK@*C$wij(trB)X*ve@5$4j zo`9>kN7G-Nl3(ByeW*tepe$fDSY{|u=@D$+;V_Cb=~w@-25izrmpVC%LKY%XMUJ{F z`CT{9S6xP;$&_@WiqsTpCXb7#6rmTOO+v}bHB(9e1JxcEjQ({Mi7KB<&>6E^g`>Z zaj^4_rX5D@Sz4$kRa2&ER5{L`i=ZsG(VYEIqCiDEQtzT9+Ltv$YUz)llS%O>dlWEH zM1ze+tohYA@_JQMX;4&1Ebe-0s+#>di<@HR0q#^Oba&~<=CCBG^iqMuMHj+4rnKg# z;0IP>HQp2xqO=Y%5v)oT%$*HSb;}&1DCynhL8LPcMM7`%;DfN zN5KID_*Q^1DV1EEMW==YOBaEprMZ%vkuRhxL`FT7U37*M6NU$s%)xn$J;xaT9u>gE z=a3*h{sMKw3|33Z#Yj|``1ge+96F(dQm~_r6UL+kkcfrTy7VNEDv~z7cYIZxk{Dy^{4>ly%r1;MEHWG+p%%e| z9|kaS7KXNVZcgD0Q0yK@*=vAI-fJk`RoO7IMxK5%0QPQz23KC z;0%yh0LJLb4)zHhF0gw9$LgRAk;=+3+K8wi08Is)OCz8W;G;VH_C~4Nfmke^Y^`(? ztI z7BKT)01DWzI_%vp1`=VT2wMmc%GpG+$^hL&vms^5%0#n5XGG>yB#R>ru0@#Q!LKekIg9) zAJT#1zh)+tM}!|A!2)m+#Q&PQpO%%^xF&oxWz5}NXzdpE17|$ZLzaOzf);4}iOljX z1Cq2>Yl>a7nX~b;zhtA*{zB6E6U6;UDcja6BCLIP{yo_gPxz%^#dafy;}GD$C5wzH z@o(`T=ln#$j0$U?fCrcxsJ2m5c8=1^A+f9B7t{`-o06MEMU!ZGLARXTW#vB2i)5!P6!NH*_h>${SdL< zK6|P1{Z}xK1yKrw7|hG3Rc4; z47=RltQ8J%2DP&a2W{w>*@Xl65}ri^Ve9yX!64${_dnPq9oMg2L=p(?{TFou!UG^g zx8Vk}ZtUbZBLZJwaAy$WBk>6#0>K&&p`m3BEye&aCNSb$%7cbh3l|k2;m&|^)x;b- zP;T1A0|)W}-J5_gMHn4age>1wxhvA|m(-h5QkWiGahnAcHM%AoIXh%fJvv zeI%p@1^X6=5PX%s+0qc%2?|l4pb)?kATYDc_8!hL8NgKr$j5z#2p;1tJqBbpuy`X{fquU979~YXUU|LxdJJpY zHUQoObow5!&$x9SgYtpgF9}&4gH7e1GJc`Fur2I;^$yG7F4%Mk>FyU7T>=7qC9mQR zqQS+Rub5y7cD%zdS9O=5@C4m&04C#f0X4gT38~ruO-6_UYBN9+O_%_h zOmGCyV*n<92mv#=012DB08G`$0%iXPsOKrXjG}TVHV*>E0B5}RC{!w7tJ_i{thn8Q zQpT`rhOH~^1c06Rl&B^7R5+z07%Fi$-Z z>x9k{L>)Fo;}f^>(pAbe0t z5l{gU6;U6b@AdrjJ=gns|8V|+bIyJ4`}L;BM$z0{ewDWH8ale)HR1H6Z81m!80m9s z0aWa_VB)6mq7+u|uS}ViK4mr)RFEnfZ6H=`|th) zGCco~{0cv@7xa|&!%F*}k%=vI`h44-pZRU7%4rtH<3j+@&~ph1y~n8WzD-BmsC@D! ztTP@E15qMFgw&G784n{+TnNtCqaGcZ9a{A9qWw+}sV5s<5H1!y5}4jBy_fMHpODn& zNaR7mt2%-&b#<&p*2?ZnIT~(4kFhyT& z2o*I0q*X|bV#i!`NecY$H-4)z(0u*oZfFw0dwI*HXMLzD?q_Y;#aB}&6Ibz^x!^+V z`*usDBoz}V;xw6)C9j#B*W{}+^6uDZAt^3CiRGNb*eR3bjjd}-N;9yClArQXMZGd@ zIoj!=M3@YVOKjVQjjc?5kR`B*1^+3O>H}0HJwYEwOQzZ8Lxy$y#8h~~wP7vBS^@(s z>Qa40b65-Z;}Ha+WwqG&%-?~=;Da}zv5n3V(8sCcSLDZukG8^B8mTGt6QI|&B%cDk zp6NvWKGz;M1w83Q(Kc|ACq1Kh2*tcJCFP6IBs4<3Q7D6j{P?RN>COx?8G%p-s0W>481#>uOSxH4`cgBy`Ey+vL?-} z8mGSp5Q(+vYT)_xJi-~%HQ{Rg?Ro5!(j%K7)Y<3f;u0y)NQJrJL#|AEo)e<~6vgw6 zd*y{to@v6!0eGr-Z%Y_f;fKlnU9;c6s1RS@f89S97ab4E1|{ns*h}V+h!K;4HMzbo zBylg{lWT*A1WjX3G+=Lu%o7>z^U(=bp|jiab?s|RgRqiW&)fi2Ci$*-Q}j9~gS0W9 zS)mT4UQeT}j^{9#%NUs|h5>_2O>k_FSh)!g=x5_zuYZMc_;WcrxCk+Eb5x8T0Ab9815xr#_Ixzgi`Pl6TYTCJ)bW@VnwlTd zoq1B0Z-Cb?0zi0b;=sjv0J2Sd?~aL9iY#LfA|vANx&vUFK1sk%Tb@-e6+J@}V?v@C zti;*R92i{^l|19!Y{I>jvKdKbtrNT>{zg1SvC$-a8j$!P59=z`5JngNK`UFPn+IZH zOC%sUG0`o8~Oo|?VRjdU-QDD(W%#*?OXm@ zBJGix?g~%Yo2NZIBE2 zLRO=Psj#AnPCg2JamUYcsOewEU;X!+^%&s!hUJAEE{ltZ#xD*tHXV@3%M#+CRZeu(gbWeLP@JJQBBB#;8z8C2K|BAUI}(Xfe4lXkl2pE< zx^VM^n2F(*WNryK(b5%k*8!F>a$mMl(_`;WCz36paNM^huKqEr5341?B0z~FFVJT0 zrDtaBi`5<@L3XW*KXx=JLR6vhu)p18G4#7tl>&o+^|8DMU(KcOaBYhG*5enjQ%H!t z$y@5xg*d!|u4a&Hr+nMv;J|F88ttzAe(~a8cAQ7U^TGp;7ql@1%L`2?92D3A4j>8$5y@{I|NQ~^=;VHJeoO=(yoY_t^6RG z6aSq*=2fUFq)vX}pj0Dwes?)oY&Hh|{AM9uZm2g;3|u@HhP*ubMFuf{rgqLqY1@ES z2ZgM5*y?9Fxb;x^4W7> zjSfS3N%R0&8;PoaF~xcIUh>Jr3ABHBof9MHi5QEO9k07`ynqjSDlqtr zCdu`IJ&F?xytYJL2eUV{EdRK*XKOvQ%yeqNNekFy)~asBy65j(#PRTsqvi{q!KEewLGTh-heTj&D&S>+|S7y%wC#+-@ z*pcn1Fqc1?%CO>eq+ChwJGx1icdi#mr%AJ?!y2boEjtPHK0H01)YM#kMT z7`Z}NEDB<#jy)c30WIl$0ev8wW!8mW{8=`Fh{tIXLEgNdQFvjZlh|Zu;})84XcmqI zeWf$hM{&U{W`0+1mYZ1W4)78^6(EYufH=DeWbz6ZUV1eo;(y5D#H)D=ogHTS>(t6} z+#xf(i1JxS-I6+srwT4!Z)=^)o$VT)^I1Q2ew@q=lj4iWy5P(GZ^nc7EKh=KR1cob z{{yB?_(Hg+L7ADt)P<_fj(G?cTHZrf;}(c>z#vf4Pl6=+eG(O*AGD^$7g<_K8ccSq zPx}xpn&O2FW6l9nC`1=ss2))d&qSZ9&?|7GVs#fsH8TX7el66=H z$ zF1=-=6ow^te?28_wXJ?Mqhc)qWKuEF0Ne>FY~5SQyi{XJO#YQbEOVOuROa~H<;;k+ zmOq&4H+|Y0b(h?~<8oQ}^+4dd{*peyxZXP92kYB(4qQK*b4V_p+9a~`plmomVs(m{ zy&(8vvJQEXr7hFzAG~jxlcA(I|FQEq&7KlxQj9yb!1mOAHZuh)@?(u#+O>-*)zIJR zyP3gqwhElKky~S?nZKloZGPzyGL*hZ{a$QlO`Cd{^r}pnJ2b)d@aG=cZ~2t!B`UeU zRR`1-x@ELH59=y9_#f(i_o&QP#10=gt%A6?NIe-4IV8R3o%n+|C=l~u!io*B)3;7Y z+K*Cw^`x0cHl&gjWcBJI;Q{!VnG`{XMx;s{fvgtDRfSkpxJE-T^a;ns;?6%~N&So8 zcxSiO)|WVY_Yo2nJ)xQz=-pUts!{3jH=PRU2C`AR#E}N-Ot!MqBL|vkdy+fr>g?_m z2HH%Cck;&f$~z(NgBH%DsPfTre&bVI{RuQ_QcnwPSku&t*zR-|^u5Q(Qe_2IVRPB?`LQnpYa}p7DwV4n4^CsrF$9ge~kyk}nW1 zULBPwamk(+ml(pyyn6wOn(Jq(a-h{8+guxKZ+uWXYGZ5KlxB<_*!_tZA8 z%*U1}Dyf+H9P9jHWxSMmiV5@r>}|jggVZ0~@-<}zyTSWR-^OCrs#5+aMKDvxm2KD= z)zfIvi%m!fCr@Vs7T{2?48|H^f9!F$&at}=X7=c$e)p2E{8`(()2@m5#Azve^YjW&19j+HazhMF4pQfZTT&-1;@qAL!UgIxDU9 zq{S!gU;@Y8!7dim?UyJRmDZ?~*2o+8bW#*@wEgOL=_Fa!6(C!q!RjqnrRlU;T~744 zr&zn=R0M*3df#+<-^fGt-Vkka;)!^FAouaz#L>AAd(PYfMM?=SS#CD{?_d>j<{v01 z_iU7x`8zd=&aD}QC~?y2?^A4--${9#n>CgIT!Uq1*`QPZ;98`vX|GepX%xiGJX+YK zg^!`?6{>p!wC>5$?W$o(YF)LQGgaIEMwf}9;iIUZqaR$^DZA|9{WaNxNNEA{QmcYc zy{8(>OpS^~AdND2V}#D*II^MK#MK5h2Y%Bd^6Co5Jd~tXg3f!93VVQV7!dUil*dG# zL58E5^St`&U-6&Oj7K~TDpfA*^+V`yRb(g|socZ%f4Ag`-F{z5Nn%Y^%Or(d^ctL2zY=mkg(53)g7A;Pd!8E^;s-yG;uf(a zm20a+E_r0b+0?B2nRUH4)R{KF1N`C@A`r($i~rl@PsCe z-_etQ&Xa%kn195Rf0$vD?G#I3*vM&UM6WiglUOqyi|8#`=jY9u_J{=f)sTZmtmEsA zGv}k8a&V2>Fum1?pC~N~V%Pr4uH7jGUn@>8e749`bCJ^+ARLzD1bfzC2djk{+u3v= zN25Sv#ff~j!kzH{)6=kV?|uG-Q9;*Iu3kL}F9nHCRp%;JdV}t%cKG7F){3U&il*Q{ zjcRg?YO;)KQjdmEj|tMdnz4+-$>Yq(<4k80`OK+}yxGdkj0H zMC(v}`i(jCspwkB8>JU6uYEf{ka_G9cYXoRe2;loc_gdtU_h~W@CjYTV*g0= z;^Zo$#)J8Z!lKhyi}=WrdW)yRAY_C?Lt56*h|YNR?}UJwT5zSHHwn5p$XFuu0?NIXDrgT4W{p!foc-@=t~!Wp>1_EfC_Rh(D>iT&ZboGC(Av$WgFt~P+@-4dj-#vQc_bOZ ztaW>tLw8h}(xz2FY2B|di{@)p`AA4e{isR$3om9-CGTxYXHq{qfq1Fc)z}x3m!Z%* zk~|S9ax5pIH$MB(p@Cu0^qXK-v(wexrFrfOoh6~03eu+@&0b4FTB)I+`FIu-e;&oM z+nT$?bZ$<4$4IoikvvIsdJ1Hk_5Q^pS)-`6WMC^KG78Vyh~LU~QlipST| zR#)Ql>{e1GjT`jU7H70DpbiYE6$5I-fGYo=N-&@T3@GQHB>qp)5}<#IkO2LcljaPm zgc?Heo^f;Kv);<2V@UaFrvST3g|xSInn@kd21&vILe&Av54PR-~h>-h|^M#Y43DU5%BoL!xl~k9sMRP&v1o>NHD!V@8R(FQ$8Mv3pNQ?aBi6#j7_)W+L+RV_v@gW-SR{m>IM&>?UzTrRERTeOq}{h-l4;dTOB*!o34E zux{Euk*^A4J!6M0G%o~+uY3daYC0D2DHL-+$@x@;gg zFTX6^=Ri>Aw68zTPphnCm8);PbUMJN1XU(m*OeIh%qzip)8O-0UPN*i}m zg3HlFMNY3}$CjC-7Irm`J|Ig}wAs^+B+USZ;>ejoyT7u8Sh$r5#(NxAaQ5?L3Avkk80~oHKwS4Orjj17Na2o7Du*+RYLAu4S8B3Hc=C-|X z-izOhzN-;?>t)6LCyd}Vi*rDIcR)?I&U6SdbB3g4c1&t7`{YqtNUGdtroT0J-6G?m zI}B_eM$P2@ke7`97HD#^S5T3)h@JKjJnY0XlQSZ+o}J;<@0(jmziZX^aD_2X45jpJ zoT<&3&-jqsL$$$w2srt#t5C?RP)OWE712y%dw&RSOpV+>Y2q!SpSgb)#o*+--_ZRG z+PofUjWeHdr;uo~i2JEzxQTteHrb7>Y3d^{8hmH3va1jEzDjHvK8YURp+^%vZQ_1 zkVGw-39pIWTO`_zx%U1wjj$`m8*;^AZGpfEz=%RQzy-B1!YN`fX9`i&$ayM3FIJ$a1qbhb#%uh;a#S$mqq!3PFf?fai8SLw27 zX*0Y*5lK1s#bu`(8)?;V&FSY^5#wt5&=t~PIH8`Kl|wazYqfzj+?sddxw-~ zi*@P)>P>ICwMjt@dTju+lMc?$6da#kIGceB9^hfHA#M-a2OfjZq6(&l>Lx>BaL18tC5 zyjnwt|CqUzcS`xaBoS6S7zRhIsGzuI`7Xjq$*_T5_>Eef+P^b_4VBGNF z1*(n$voZXw{P_$O1>*?e#%g(wdipExYje=(&&uELE|klXm(gjc3_W0ov*HI2=L$6B zZhA~g2(f!cSSY=eD_#@AZvnPRgIT_-UBY5v4 zqeg_zO?e9UAG3i-h>51b?az)KF%Bj^3!tGT3Gdmk2nOWW3~Y1$asH>o=z*!8m-L;6 zN74l)YsQM61Ob847+{FyS3}zh({}KNTz`pvy0@DquU0BK-D=Wx@kek~R;)tmvQA$) z_PB{P4D`dWY2RI^L|JL)Sh%Ng`>RpV<^40VsVs_0$Gl})Ae<4<0WD-f= zNg-3Fn6+kKLpgC%Ft=QZ@rbuR8J(USFa2E>xhK+Yl)hH1rWIPD>D4Y?gl!Gl5=0tb z3!~AMm55j6{%evNEfy4>#LHTf-pZsI`N;pK=HWSXg!?yD%^Ozf!Tz~)zMxg^zFI_x zZ)H7-i2!q!Tul~cp;DNUcwMyOs+*kuMR!I*o`E~yh- zB&*0kRt|=Vatf~TkwgVYJuL4gHll0|mzCvaoJ_RWFl3UF!xn3r<=ydZvb@36G>!=3 zvZP+DDYEFb+Zj+Nye@dPh1ZZxqpGa(@_ZA}#qV~9SvSFyD;R9Y#Aq15feCRnuZE4X zt9hHj;PprWtd0qxAs+om5PWGydsxpigVi=6WYl2T_3(1}pa4Pez8T#Koe7~_5VG>W zwoGX9;w6`+tHLP!|Mo9-&s&-{*poYHNt2e4ScRe1!nZsx;$KqFCL~m0D7ElR=^zOf zu(dR_%M;bFvF3?9UeYxt&d4|yz0rv zyJWCHC@#fF$>QC8LBnq#xGvbLC#rbtpCv5mE)a4{F?_Q4yXVT1cs(~z)+~fM4<^Nr zbjRu#5VGho2tmAWk+LA(-W)X02njHQt<*$%wXtv zSAH3T0CMkU0e8lKbIHuqBPkM0RkSHY{#|QZKVvA4${xOEIDYQ_pH z;+tX`1@ccT%eb+#KN&kUVJcUiZVUT*z=OG`J(gy3r-}~RI)20fMmW2Db|}t#b3WNe z3b+bgvabq6Mq0B;y5-zB0Y}wz*k(kh^IEBcX7A565I%=Cvn*?-w<|kKAUBs+Yn%l@ zDO#dEJ%~YtE2gqA=LAwt+f* z$EtW$>IS`TYY(a#B!1LPIetcDmAN;*5%ZElc=VTseL{3ib_S;vwV>VYyw}_9)n_`q z#nskO1DerLROL60xG|Ftw%VB9M`0r-yz{S8-J2=0rh`1toicuZ0U_ekE5v0#Hzd2DU6cz=l+)_I)k_XWy(J6O^=mEZVF=&6T)9 z(aiF3m@6S^l568nPwykpj6kezp}=HW6*hH_i@WPj3OI=GlW1GY0O^^<(=8&stcM8p zr9wVjbu_bKCqQ7Q`?+Ri4ak&!>8}~}yNe%otEC9Us5|FObPRt)fzjQjh%ubs;W)!E zO!{rZ`kqRR=rktZ4{bpw+-z*ifGHMauf!1ah6)rF}(XecXw-k^+h=p`{xP|fl-h?YdyB&8}$X;i>R_5|PeLfT39 zT52#`g-b;;2O!Dj=SQ6;S|;4~(hHvF&;1_!%F*e2?S_&*Q}65?!`;TD@ZWc{AUkL1 zBH)syA3KXNX6erdLeUtS=uGKA=w5xQ5yJviF2+&0m5QzuT>*)rkgPxN8ik-S+h(9- zU9pIH**igkTVIH|RCEI3r3>S6&w)%|8+Vv=9`y2*|Kc=g1AX3L^`$LucVNfk&;d^CK4b)OXz4FJ`dvIfoRDhBznnVk}boWm= z%#^A-5!1}FvTFwZb!MHoeknf4Rwr0Vi<{9Vdt_bz^f8I(hLh7e<>Pm3h}!o;mNX)R zGtN&O&LJE3&CNt{jpo`s*4ZqBl11@>e`6e-xTi$oI9tt#Y1_!G=F!9vuC*lpsfajR z;+q-9G5)k;!a4tq&%qeiGEY~MSV2p~?B$amKit-mT|I6t^1bZ~6HWW7?jL28CTIA^ zRGxe#o~PWLCoT_5niD%x_jJFvjxt7mkCt!BWY#9o5^{!1vR8dU&z1-j)*lMg#xDH> z*}jd+We+p=ZHc8?@^ZSs3aIhxuyNFgSoG>kGq-NO_GjazWSdV0E|Y8+X&1)Hx3M^i%!=b#IRFHa%v_KU@?rp=C6ZWd0BmUjI+S*ag%zRvL67$c3Z-qI| z%a*co1M(*oxY*I@`JhEM~sAqr1* z`psG9bA`8-N&JQ_V_A&H{y(ww&u4yej3@Kj4l^@m3Jt#7Vmjy=(_WKmGP=pyG?D~3 zvEa`rYKujCS(yzZNA_?v(h%jTymxoz;?0Eyqcc8a5W#49?`MVU>{$lYu{Ok6PW|HP za~#c$I6K>NHsxRJI#hygj+4fRk>vuEhurL@3vLqTf=bgGvp)@DnZ-5F{s9Asc_OrE zjVb-^D`|~)ACUQ9-L>>G3VY&HLeh$D~!%?vaInO)67t ztYJ);fGqIjy<=;+b-OO+Ak0@Ej%yT|p8wY{lJryG)jL?DX7779vM)gAe3w07gcwIs zkXW)tp0~Kv{aNZc55H^SE#}quB?(%!gvVrk(h{kI;0ta499g~m=1J@ESZ!C=Pwvct zuCnm@aP-vUYs=~`zkKcUW7C$nGPV>~jyU-|)f@$rAC#DX75pF6*Rl`N6IwgO*9%;Jfn3nf zRP;oJ5GxNa{vm({hH`RW`jLkgGaJGg010kngQJ#r?|9_R2iwqQ-LkY+RGwrYtI$54 zhjx`)9S=hP;g4!J<-ueOgXCXy20fOEQvR;5Z!2w4z6=nAiX%gAw>6PRM?=saWBb^z zmzo+6X}MeiNCl4uVb=D`;q?v1a7wvXwupp`TI#uukKCm<$4Y3v=Q=P=zKb1^!&UJ& zQ zDT<`3+sIV=*uNN$mR7R9PwyksEv7;eI~C-KhDF~A>re?Ffh|>*y;=+eYIyp%pdy8q z6+3Ls^Zs7B`_zeV6=zOxf_v}6qU;MGXLOENvjB2T00GF7fnupFb(L7D(J`ah7A+Yk zd0scUZ5>3yBKqX=w??|a%}+h9(VtR6EIgzdtWlkl&DVhSO#2Jkp$0N}DmvW|GB1>O zYIa5wQ0)mNFi+uvw8lM%&#PU)la9WP9$dyPmVH95pr_g*fPCtQXi$s+Sc@}!$+9x< z@LKx7+pPp_ZV_Ju$zeY>AcmFGYZGrx;?pOI_>8lqak$&I0Anqu^9u=2x1Y!M3pv%q zC_;co(D>2@FQ-1QbKm$YC4h#8Qz_%6-l_x<)+>sR4|*uFc#qDmZC`MBbzn zVUWG!Gq#Ryz;zs^W+xR|hU?1@nl9jGqFKU%=*!)g((V|*ZPQRr?ejWEMI!Bkj_1>* zUoJM|jX%|<{nhJ5no_IWdFOcg>8SKr)4E8fR)Ockwv!rmhpmz3_5+ z+|z+NQ=N4CYTN8zi8jv~fc6*~c@prn2yj#Bke#d7@0MryJ2o~|fduHB^@r6B`dIrP zYwRNc8eS}sw0)eD+P6}8;DKa(?fh}xtBqPb?$TNM#=KYfNbu~>(2!5W!hbp=53(T) z{ERMYG?t$}#j=?!*2?UqS-Mo&XNwo;eEuW1T43R?upaibB0`<%zS~J!970=onZ!5i zGnQM0^b`W6n%iWW_Ek(uuvRsR8^mcXZx58ua#>!=vX#n}%mjE_^WDt}U!q{~k>S@| zxnQ18fm%3NSVr*>+r1re_y6yc(@t@d<(Dkz3`I;_#}8Bx<`QM9^E-ugWnO43n&ox@ zvEORvH147SyWHUvd1y;@SKpIr0hzP3g8|<7Yt?EZdJhJZUZE+P_IY!t{u5PDu6OPz zGW8{oZ4dJq&Gq*T6V~N^c*NzD$iOrY z`2zld&VV&bbHJo}N&8t5#<#1JVcZPv!@@VY3v`%rcbSfhp!yGyH6C#-LWk`Jz*D7; zHZx(jZa<__Xt2EaN+N-*FC^nGpZT4~4{NFQdj#r>qqhnEskpV@=5jaHQ*k;suR*t0 zS80w!pS9W2DxJSD@_gnW%OGCBllmHxYC9~;KT3)K|9dXEFPnvrkGVpSBD5n!mt~Un z0AEeVg26!68|DEi4pTp z{ZvC9z?vhu69{YR9je0Q(zx#^W^Q;E*?iwXS1xm4e%Y?Hfd)W)dXTMf3485?*QXl4P zD*S4t+d7&vXBam9Ev%eBdfu5#nY4g*;>@1-ZYRq$EU0&(m*i6_hH07hl~X55DC)hm zDp1o$>XP)D*5~4v?3`)~(R6CjD3PFEl-I0!42Kf_Aj2a6-in5rwdxR5cf^_bV~yHO zVRh0PiczOaUQSW(n(B^%e{*`RooP(M7jXXb3Hq4nId@qEGxO5D>qeMWU~oFoE{B+6 z0d-_$OifRVv_TYd+`Ni|nOwJ@wcxpukJFH@89ULHCqb{ZRi^2bMJl!M=N4Z2r}&n% zx1I~o0s~%uuB$etluEMl=8x?gE!`$(^<^r~&+#cPddm!-@rlFeC{vV%_V+oLDQkH@ zWjUX@5IAv%SOU!Ic7BXTyih;pj73n*n@k|bxReg+G^u&HHsz6ERS?vl7%Ht5BMs+r zG?AGPAR>-`$hDXfx1Bkb03gZfV1se2RC&e$fi5?^pM1+-2AJsGXXl*u$9B`)0=>bj zsLWw&$A4rRp7J0^8$aZxM%{g<5$~Tmhr}c|THHYHBDLs#FKH795Q{0GD0L`ods}8} zhc6TRmdXXJYM8i-{`wz>FjLYHf;tcX8%i7Sjff^w#Z{JwB5<(moTE+Xr9=ioX5s~U zsCJ#97Lx9YWud0y|1XqsWbUTeVY-}w$dieS4Si2=lh`xheyHYE-d-yBhCtbnB9N8% z`H617aQDEay?w zSFmv_j{Kd`YE_08v!0buzXv$^8P@Cu<#|t!WNQJPm0vWT(CXlXNZY8F$gbJHECER# zsFL9LdbBtSq1Fym!DmE{q<_gDqZ9X@{xXI;96L8`a>=*3`YqMUnw&7R&>Mh>J;v^a z-FkRw#A$x7IT-#4sG=3*d6Is41Webu*apw5eWet6l?R%B0O9sSjA(=PhJlaiEST~N z5AJ*;BC-Tw2q&3xakzAOJBWQA7Q_wU&B7+5dw-8*)H=aD7~#B!VzWi>h_MyE8}Csz zVaJ4-j3@iFCdFpzEYwmy)J=^#l_7b7KiR;$0qS9G$OjChYvj3kD0Qi~Vy#O3Tsn7C z>Eoz|j+_={lJkRksKq~jOnD}{@!{V)=j~m-M+h52+g&ruW zQcIznDgThja0+Ah{tmVOSC#xwXTE=;K~j;8uTnXtX_WM4;Vt#I>Bipx^_Q$68uJH1 zOHX40vx}_6;3mLWURS{L)d*vUtws*}&9JHkZ=kl%xkeN=^kVWT*sxhT@JGBw?+?x- zM~`sp-(cBZH)P0m)#*wb%a3WgnG4R8?YjkmkGN1=w=)T!E~r?Zr`axpZy5I&U$Rl1 zp1nP(E-mb$OJu2_pK_;pK`THiwx6BYKr+YRN2bvdTL3XnpiuSBBFTG0gE1E<6BHmM z*Q=A}>~C$vwWnw%R0@xOVH&5St3;&U5y~^Bve%yBYP`Qsc1*37Yf;QseZp3Gx3S;3 zJ?5F#eVj&I^4&j&>8!4EXY$nnIj`c++VTStZL@E_iarAA=e_zUq2lIzH{{K(8Q)%> z2iHs;m6l9mqL8cAw$?I_*)^T4sP|usKE*9{uF+Xtw`1AuoJaaeyp(Pw5sql~3BhjF z>W2=$Bt@?k1(tJ3x4AC*c@7bfF)Jf(z{c?SUHk!o(vsMd)4)d#6g@q1t_Km<>sGK# z*^$wU6CM>0smO-qy7!>2)|?gfC4IBiXq6azWauseI>#}TI?UQLx{C7y2AbrK|AOS1 zxS7-?aIaQmJgNFw@o7oN^*;A}9>x^Q>?g?!Px!S7PC^HwXU!40sUNud!P{iX(mGayV=c_ zj$|vASf=h|w#-}DuS?5|()9O~y?<7VxOP9U*S#wo^bi~O;k@Dh*?t0wty%AEgAgA$ zn~+KzlWLj9dz@yk9_&PUv>EueENB<5B$ft?Up>VOMv>GZi0O`r&Q{oD+a3b_m2S53 zm5IYUQA-Q)I9B@VY zI#olvrhaNi=ub**Wu7RG)3cRJdZrJ0nNBM@-)C`3I{p&TSE%WaQy(n{7V0L}!<*jT1l=TZIh=)mL$MaS=@UgSQ5? zBIoo?&7|jysvY|& z@=d<79uzVAxh6}Y?&9AjJ6#)IM~#_n&;H#T$z%s<9!Mr*St$%h)&g_hJqB=^WE@x?AaLAdde?yr||rTcN(sQh$m<#}we zDH7}DK3)Xh0R#z&dhv1Jr}GsljP0C{(Q4oks;79mkm&i?kuk#gyFc=da>T1FZlo{d zV!sm%698EDMx%)^LK-%~_?i@SHOv~|Ad40m{x=zEJ#8^cym~gG<&oF-I21#EvkRR^ zaA0~d&@qI7yBrywY^k=0c6u7zN17zyw>6(or6zF6?=5xAP2{AQszP_~%9Z3_7f1K) zxupydjGx*sTlh}Zs|+Cuf)2xNO8EFa*|TU)i?3|NhYw$##n_eOF4`#Z6WoDRo727? zVKh-m+^D44Wq_lD6Mf%H!3xsCz7I2|DGk>0gda61Q1$m+u0saD3gHuJiXgHCix@6X z-KH!aGhd-)0bgh>zh`j$&so}l7ejjVYpa1(8AW%>K@C~x=xbo@2`KL)f3ouiN9`}G zkqf;Po^gH(#CN(a1Z}o(&slLc_aj48$UnH$ox&ItLhy?Da& zX-G2q=%J5VXg)PHs(sVIo$ocGEd6C)QRiNuz`RQNQ zp7TbTLw$Dm-tXanOi4!Ai{c~E|NiQcoL0ivkCkS}x|1mKgi&6Qp6(<*T7zvm-AXpJ z%h5+d`6sG43V{*BV)b*n7=gL;*}{c@VW6_E&b3Dw&n!7f!x7N>HJXlH+y;bRJ_l`o zW9w>)GpyV3??fSzUpUEH*o;dg2`_{wN3_WMds+zbbaLnOKcLM^=8e{Iby!KJ+51pP zvo1yYL~fK=XqT=36abv3&(BYcOt=%v9$#Rf@i&QQALZ;KwR;=`{7dpJAnps4=vY$s zMY8yu;0(<;<+f)@S6E*v$|0PLwYAlQlH_wl+0Ig!;%{89zQC!=6O(e3VAAYH0@t>a%T>MMTdie0Z?+5~3Q2i>UB zlq1NCRKay1%<2(NgZ&&R@3AQUd1bgZ60#aF~y;$e(ApJ*|zs zt~OQO{VW!0E(3dMp-)E4um03ZsK}H>YfozWY#H5#+5U5mD)T)UVtkTvxMP8qaDi+V zby1cpcI~sZ&VL2CD+ZF9gKBe$j72QTMN|H~5kC6zQD#(W4MycW)uj{%=$e7>wS949 zL0AT{Gn5Uvf(E%SVecLMk0|*(ZHSX8eleRM=_18vXbG?XOL)r-W2& zUm6-MO|Njru|cVQde?4Uo3=g@gL0)U{!-l|y8Kr$K5>o@8r#-7GY*rqUbGYdMYvlv z_I74#NDcZ+2o9;N0WqGaL=}r*#EPR4mD4Kx-z{>JUA6V%)Z}1fI*~gT2iL$gUE;a^ z(pIG-d$gFr5r+RYtLI(05Jwl7P@*#(Ik?Cf9+CZARd%8qK{~~f+B#`ov~^i@!}u+J zCGp9qyb!)W5%7dI$8cqNQjyO3Zy-hc)3nr-Fa=sg^N@%5Bi{9qC^S2nB0+ziMqnY5vz1Z5XcUd@$%oH_VmDtFMd7vz)MkW#DU^ev`{(T{6ha4NfMREpE- zhn>oA3Tlh|Ne+gd^ydbQE9OODpP(U#-TbwTfUw(bXAM)3yz6?NfY^aGuKkjElbbh7 z_zlT66UowutZ}eE9Hqs&_!rRHPCi=Me_YFIwR<>MPLA?ZunT!Y&d=+Q$wu%~0h0)fp3TL?&`hWRj) ziQ7i3Zy$EbTTot6oYiI`ik;XGHNe)L@{wW zRIgKz0=k7a_r4m}_>cn{efjcPGwSmqQ*fJ>$?bJNj$9|?6};l@O^g}&ELJ9q=l^W7 zyS!p!5p&^J^5*-ycl0Mh4&^LpQ0*zW8fyG*H1**Cz~+zoA2DXRg?8LUdcl3GH4RqM zjM$gnYP!SO7GZ!*QjmS6UeW$QQ+)!JyJjv86O;}D8{O)L!j!o7&AKK|kM%7gT{ZrY z0SQg6hGiev!ZrG$-A%nuv%rrj^grozZcx6+E2kD#OKJ6|NshUtMZ`3*ifPNv}?=(r#rx!Q`_deJx^*hCU_>X!Xa&0{}v1 zml8_6*~g_I+Y9i1Ci=s6ss$H$!YJVTD!tZE-TTT`0h_N@uyQGa;>8hvIn~nQokvym z?m`R_F1MyGmlHISWOo%_=XB+N6Mu%!mCV||M-AAAtGr_wSJT4)+*vwc$6KY6;1tR0 zb57%pDT(wnDUZ3PIe9A=3hbj43D6@~sNVzpDQXft9y}3#iU)Jy)H%57jzBaUy|{G7-dN z@EGD%+C978cq}Uj0DJM_PM|AGp~?{@iZ~{$0U+U>COnye_QwU?v@R@O(pd?puD}E$ ziwIVR*s0-)P8PEw^rcvV5i*lVsUc>N2723JGa%$eJH`w_>vAXsevV>-0%3md#%_Eo zAWExNof-BT%u^kP>uTghHG-;}RN$2eIi&<`({P<5DA$l6UUoX!q}Aw@g~2~WAQU`8dx*aR zfi(EasDYd&h#zKghXzTiWC%c{h=gCgyLi$iCKN!4emdE{I^Cy|WPJ)NHUZPc3H19< zr45#)3(kd5lt62>5$|dllw?K{vUOt6pplrI0@Mv;h`>bZ00{eXuqHayrto;?!JJTw!*E8B)!s03dff^5m7MMJ<3ZYE_Dpm2eVwhLog&1 zRb(|7{ol_HL;wq7*Fr~s~H5SoUqD!(ff zN4Mjs?g(2RLqKH$Ce$A*6(=I}X8OIVxloTu9G0=jZ{1?sTxa7%VE#VrQt~?po##XeCpy5U#AR* zGck=BhNT6OUI$|0e~SOp2;*OoEO#@n15k1YNRRFROK#j?s@uQVfre;u3h`> z2uX;btmRL=LwNFy+<6INJOV)sEsk;sE;W_2(-t;p44*{wQ9scb7Y ir?{?FXP<+xvf6n%P literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.woff b/AvocadoEdition/plugin/editor/cheditor5/css/SourceCodePro.woff new file mode 100644 index 0000000000000000000000000000000000000000..395436eb8493c7f2b990460567348950d0171c94 GIT binary patch literal 89024 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 n(Q literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/dialog.css b/AvocadoEdition/plugin/editor/cheditor5/css/dialog.css new file mode 100644 index 0000000..856c1d7 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/dialog.css @@ -0,0 +1,185 @@ +body { + background-color: #fff; + margin: 0; + border: 0; + padding: 0; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + line-height: 1em; + overflow: hidden; +} +td, input { + font-size: 9pt; + vertical-align: middle; + margin: 0; + line-height: 15px; + height: 15px; +} +select { + font-size: 9pt; + vertical-align: middle; + margin: 0; +} +.handCursor { + cursor: pointer; +} +td.hover +{ + background-color : Fuchsia; +} +table.dlg { + border: 0; +} +fieldset { + border: 1px solid #ccc; + padding: 2px; + margin: 0; +} +.content-outline { + border: 1px solid #ccc; + border-radius: 4px; + padding: 5px; + margin: 0; +} +.dlg td { + text-align: left; + height: 20px; +} +form { + display: inline; +} +.dlg input { + border: 2px; +} +.img { + border: 0; + vertical-align: middle; +} +.font-normal { + font-size: 9pt; +} +legend { + font-size: 9pt; + font-weight: bold; +} +.bottom-status { + background-color: #fff; + margin-top: 10px; + padding: 0; + text-align: center; + height: 24px; + vertical-align: middle; +} +.button { + width: 64px; + height: 22px; + margin: 1px 2px; + cursor: pointer; + vertical-align: middle; +} +.button8em { + font-size: 9pt; + padding-top: 2px !important; + height: 21px; + width: 8em; +} +.button10em { + font-size: 9pt; + padding-top: 1px !important; + height: 21px; + width: 10em; +} +.emIcon { + width: 19px; + height: 19px; + cursor: pointer; +} +.schar { + border: 1px solid #ccc; + background-color: #fff; + width: 18px; + height: 17px; + text-align: center; + cursor: pointer; + font-size: 12px; + line-height: 1.2em; +} +.spacer { + margin: 10px 0 0 0; +} +.spacer5 { + margin: 5px 0 0 0; + clear: both; +} +.wrapper { + text-align: center; +} +.clear { + clear: both; +} +.flash-movie-source { + margin: 0 auto; +} +.flash-player-wrapper { + width: 560px; + height: 315px; + border: 1px #a0a0a0 solid; + text-align: center; + overflow: auto; + margin: 0 auto; + background-color: #fff; + display: block; +} +.media-player-wrapper { + height: 200px; + margin-top: 5px; + text-align: center; + overflow-x: auto; + overflow-y: hidden; +} +.hr { + border: 0; + background: #e0e0e0; + height: 1px; +} +.colorCellMouseOver { + line-height: 0; + font-size: 0; + height: 8px; + width: 8px; + border: 1px solid #fff; +} +.colorCellMouseOut { + line-height: 8px; + font-size: 0; + height: 8px; + width: 8px; + border: 1px solid #000; +} +.colorInputBox { + background-color: #000; + text-align: center; + border: 1px solid #000; + height: 16px; +} +.colorWrapper { + border: 1px solid #000; + background-color: #fff; + position: absolute; + padding: 2px; + display: none; +} +.colorPickerButton { + background: url("../icons/button/color_picker.png") no-repeat center center; + width: 24px; + height: 20px; + cursor: pointer; + float: left; +} +.colorPickerButtonGray { + background: url("../icons/button/color_picker_disable.png") no-repeat center center; + width: 24px; + height: 20px; + cursor: pointer; + float: left; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/editarea.css b/AvocadoEdition/plugin/editor/cheditor5/css/editarea.css new file mode 100644 index 0000000..fb6dc7b --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/editarea.css @@ -0,0 +1,23 @@ +html, body { +} + +p { + margin: 0; +} +table, td, th { border:1px dotted #ccc; } +table { border-collapse: collapse } + +/*-------------------------------------------------------------------------------*/ +.ch_bogus_spacer {} +.cheditor-zero-width { font-family: monospace; } +.cheditor-insertpara-pointer { + height: 1px; + display: none; + overflow: hidden; + background-color: red; + position: absolute; +} +.cheditor-add-paragraph { + border: #999 dotted 1px; + margin: 1px 0px; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/imageupload.css b/AvocadoEdition/plugin/editor/cheditor5/css/imageupload.css new file mode 100644 index 0000000..2814a58 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/imageupload.css @@ -0,0 +1,136 @@ +#uploadWindow { + display: none; +} + +.clear { clear: both; } + +#container { + padding: 0; +} + +.imageListWrapperHtml5, .imageListWrapper, .dragOver { + background-color: #fff; + position: absolute; + height: 295px; + width: 522px; + overflow-y: scroll; + border-radius: 4px; + border: 1px red solid; +} +.imageListWrapperHtml5 { + border: 2px #66b2ff dashed; +} +.imageListWrapper { + border: 1px #aaa solid; + box-shadow: 0 0 3px #aaa; +} +.dragOver { + border: 2px #ff3399 dashed; +} +#imageInfoBox { + position: absolute; + left: 548px; +} +.imageInfoTitle { + text-align: center; + background-color: #e0e0e0; + width: 130px; + font-family: "Malgun Gothic",gulim; + font-weight: bold; + font-size: 12px; +} +.imageInfoTitle span { + display: inline-block; + margin-top: -1px; + line-height: 22px; +} +.remove-button { + width: 93px; + height: 22px; + cursor: pointer; + vertical-align: middle; +} +.imageBox, .imageBoxHighlighted { + width: 120px; + height: 90px; + margin: 3px 3px; + float: left; +} +.imageBox_theImage,.imageBox_theImage_over { + width: 100%; + height: 100%; + position: relative; + display: block; + background-color: #fff; +} +.imageBox .imageBox_theImage{ + border: 1px solid #e0e0e0; + background-image: url('../icons/dot.gif'); + background-position: center center; + background-repeat: no-repeat; +} +.imageBox .imageBox_theImage_over { + border: 1px solid #a0a0a0; + background-image: url('../icons/dot.gif'); + background-position: center center; + background-repeat: no-repeat; + cursor: pointer; +} +.imageBoxHighlighted .imageBox_theImage { + border: 1px solid #ff6600; +} +.imageBoxHighlighted .imageBox_theImage_over { + border: 1px solid #ff6600; + background-image: url('../icons/dot.gif'); + background-position: center center; + background-repeat: no-repeat; +} + +.removeButton, .removeButton_over { + display: none; + position: absolute; + cursor: pointer; + background-image: url(../icons/imageUpload/cross-small.png); + background-repeat: no-repeat; + background-position: center center; +} +.removeButton { + border: 1px solid #a0a0a0; +} +.removeButton_over { + border: 1px solid #808080; +} +#insertionMarker { + height: 102px; + width: 6px; + position: absolute; + display: none; +} + +#insertionMarker img { + float: left; +} + +#dragDropContent{ + position: absolute; + z-index: 10; + display: none; +} + +.button { + width: 64px; + height: 22px; + margin: 0 2px; + cursor: pointer; + vertical-align: middle; +} + +body { + margin: 0; + padding: 0; + overflow: hidden; + background-color: #fff; + line-height: 1em; + font-family: 'Malgun Gothic', gulim, tahoma, helvetica; + font-size: 12px; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/imageurl.css b/AvocadoEdition/plugin/editor/cheditor5/css/imageurl.css new file mode 100644 index 0000000..b053576 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/imageurl.css @@ -0,0 +1,5 @@ +/* CSS file */ + +Application +{ +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/lightbox.css b/AvocadoEdition/plugin/editor/cheditor5/css/lightbox.css new file mode 100644 index 0000000..75d9d93 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/lightbox.css @@ -0,0 +1,95 @@ +/************************************************ + + CHEditor Image Caption Util + +************************************************/ +img.chimg_photo +{ + border: 1px darkgray solid; + padding:10px; +} +div.imgblock +{ +} +div.leftjust +{ +} +div.rightjust +{ +} +div.caption +{ + margin-top: 5px; + margin-left: 0.2em; + color: darkgray; + font-size: 9pt; +} +div.caption-marker +{ + float: left; + margin-right: 0.2em; +} +div.caption-text +{ + float: left; + clear: right; + text-align: left; +} +.imageUtil { + cursor: url(icons/imageutil/zoomin.cur), pointer; + outline: none; +} +.imageUtil img { + border: 2px solid gray; +} +.imageUtil:hover img { + border: 2px solid silver; +} + +.imageUtil-image { + border-bottom: 1px solid white; +} +.imageUtil-image-blur { +} +.imageUtil-caption { + display: none; + border-bottom: 1px solid white; + font-family: gulim, Verdana, Helvetica; + font-size: 9pt; + padding: 5px; + background-color: #fff; +} +.imageUtil-loading { + display: block; + color: white; + font-size: 9px; + font-weight: normal; + text-decoration: none; + padding: 3px; + border-top: 1px solid white; + border-bottom: 1px solid white; + background-color: black; + padding-left: 22px; + background-image: url(icons/imageutil/loader.gif); + background-repeat: no-repeat; + background-position: 3px 1px; +} + +a.imageUtil-credits, +a.imageUtil-credits i { + padding: 2px; + color: silver; + text-decoration: none; + font-size: 10px; +} +a.imageUtil-credits:hover, +a.imageUtil-credits:hover i { + color: white; + background-color: gray; +} +.imageUtil-display-block { + display: block; +} +.imageUtil-display-none { + display: none; +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/css/ui.css b/AvocadoEdition/plugin/editor/cheditor5/css/ui.css new file mode 100644 index 0000000..2273f40 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/css/ui.css @@ -0,0 +1,653 @@ +a.cheditor-tag-path-elem { + text-decoration: none; + color: #0033cc; + font-size: 8pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", dotum, monospace; + cursor: pointer; +} +a.cheditor-tag-path-elem:hover { + color: #0033cc; + text-decoration: underline; + cursor: pointer; +} +.cheditor-container { + border-top: 1px #ccc solid; + position: relative; + text-align: left; +} +.cheditor-tb-wrapper { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background-color: #f0f0f0; + zoom:1; + height:auto ! important; +} +.cheditor-tb-wrapper:after{display:block;visibility:hidden;clear:both;content:""} +.cheditor-tb-wrapper-readonly { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/readonlymode.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-code { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/viewmode_code.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-preview { + border-right: 1px #ccc solid; + border-left: 1px #ccc solid; + border-bottom: 1px #ccc solid; + position: relative; + display: block; + background: #f0f0f0 url(../icons/viewmode_preview.png) no-repeat 10px center; +} +.cheditor-tb-wrapper-readonly div, .cheditor-tb-wrapper-code div, .cheditor-tb-wrapper-preview div { + display: none; +} +.cheditor-tb-fullscreen { + width: 16px; + height: 16px; + float: right; + margin-top: 3px; + cursor: pointer; + background: transparent url(../icons/fullscreen.png) no-repeat center center; +} +.cheditor-tb-fullscreen-disable { + display: none; +} +.cheditor-tb-fullscreen-actual { + width: 16px; + height: 16px; + float: right; + margin-top: 3px; + cursor: pointer; + background: transparent url(../icons/fullscreen_actual.png) no-repeat center center; +} +.cheditor-editarea-wrapper { + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + width: auto; + overflow: hidden; +} +.cheditor-editarea { + width: 100%; + overflow-x: hidden; + overflow-y: auto; + margin: 0; + padding: 0; + display: block; +} +@font-face { + font-family: 'SourceCodePro'; + src: url('SourceCodePro.eot'); + src: url('SourceCodePro.woff') format('woff'); +} +.cheditor-editarea-text-content { + overflow-x: hidden; + overflow-y: scroll; + margin: 0; + border: 1px solid transparent; + padding: 7px 10px; + display: none; + resize: none; + outline: none; + font-family: SourceCodePro, monospace; + font-size: 12px; +} +.cheditor-modify-block .cheditor-ico { + width: 16px; + height: 16px; + vertical-align: middle; + margin-right: 5px; +} +.cheditor-modify-block select { + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + font-size: 9pt; + color: #000; +} +.cheditor-modify-block div { + padding: 5px 10px 5px 10px; + color: #000; + display: block; +} +.cheditor-modify-block div .wrap-text-desc { + line-height: 1em; + color: #000; +} +.cheditor-modify-block div .user-input-alt { + width: 120px; + margin: 3px 10px 0 5px; + height: 15px; + line-height: 15px; + padding-top: 1px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .user-input-caption { + width: 350px; + margin: 7px 10px 0 5px; + height: 15px; + line-height: 15px; + padding-top: 1px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .caption-align { + margin: 7px 0 0 4px; + font-size: 9pt; + vertical-align: top; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #000; +} +.cheditor-modify-block div .wrap-checked { + vertical-align: middle; + padding: 0; + margin-right: 2px; +} +.cheditor-modify-block div .input-submit { + cursor: pointer; + vertical-align: middle; + margin-top: -2px; + margin-left: 10px; + height: 20px; + width: 64px; +} +.cheditor-modify-block div .color-picker { + cursor: pointer; + vertical-align: middle; + height: 20px; + width: 20px; +} +.cheditor-modify-block div .delete-submit { + cursor: pointer; + vertical-align: middle; + margin-top: -2px; + margin-left: 3px; + height: 20px; + width: 64px; +} +.cheditor-modify-block div .edit-table-ico { + cursor: pointer; + vertical-align: middle; + width: 16px; + height: 16px; + margin: 0 3px; +} +.cheditor-modify-block { + display: none; + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + padding: 2px; + background-color: #eee; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + text-align: center; +} +.cheditor-status-bar { + font-size: 8pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", dotum, monospace; + color: #333; +} +.cheditor-tag-path { + border-right: 1px #ccc solid; + border-bottom: 1px #ccc solid; + border-left: 1px #ccc solid; + padding: 0 2px 0 2px; + display: none; + height: 18px; + line-height: 18px; + overflow: hidden; +} +.cheditor-viewmode { + padding: 0 4px 0 4px; + height: 16px; + background: transparent url(../icons/statusbar_bgline.gif) repeat-x 0 0; +} +.cheditor-viewmode div { + width: 24px; + height: 16px; + cursor: pointer; +} +.cheditor-tab-rich { + background: transparent url(../icons/edit_mode_rich_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-rich-off { + background: transparent url(../icons/edit_mode_rich_b.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-code { + background: transparent url(../icons/edit_mode_code_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-code-off { + background: transparent url(../icons/edit_mode_code_b.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-preview { + background: transparent url(../icons/edit_mode_view_a.png) no-repeat 0 0; + float: left; +} +.cheditor-tab-preview-off { + background: transparent url(../icons/edit_mode_view_b.png) no-repeat 0 0; + float: left; +} +.cheditor-resizebar { + height: 11px; + overflow: hidden; + border-left: 1px #ccc solid; + border-right: 1px #ccc solid; + cursor: s-resize; + background: #eee url(../icons/splitter.gif) no-repeat center top; +} +.cheditor-resizebar-off { + height: 11px; + overflow: hidden; + border-left: 1px #ccc solid; + border-right: 1px #ccc solid; + cursor: default; + background-color: #eee; +} +.cheditor_mode_icon { width: 24px; height: 16px; cursor: pointer; vertical-align: top } +.cheditor-pulldown-container { + border: #7d8db0 1px solid; + background-color: #fff; + padding: 1px; + position: relative; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; +} +.cheditor-pulldown-container div { + padding: 2px 2px 2px 15px; + font-size: 9pt; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + color: #222; + position: relative; + display: block; + line-height: 1.2; + margin: 2px 2px; +} +.cheditor-pulldown-color-container { + border: #7d8db0 1px solid; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; + background-color: #fff; + padding: 2px; +} +.cheditor-pulldown-container div label, .cheditor-pulldown-textblock-container div label { + display: block; +} +.cheditor-pulldown-textblock-container div div { + text-align: center; + padding: 2px; + font-size: 9pt; + color: #000; + line-height: 1.2; +} +.cheditor-pulldown-textblock-container div { + padding: 1px; +} +.cheditor-pulldown-textblock-out { + border: #fff 1px solid; +} +.cheditor-pulldown-textblock-over { + border: #ccc 1px solid; +} +.cheditor-pulldown-textblock-container { + border: #7d8db0 1px solid; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 1px 1px 10px #bbb; + background-color: #fff; + padding: 2px; +} +.cheditor-pulldown-mouseout { + border: #fff 1px solid; +} +.cheditor-pulldown-mouseover { + background-color: #f0f0f0; + border: #e0e0e0 1px solid; +} +.cheditor-pulldown-frame { + position: absolute; + visibility: hidden; + z-index: -1; + width: 1px; + height: 1px; + line-height: 12px; +} +.cheditor-pulldown-color-cell-over, .cheditor-pulldown-color-cell { + float: left; + width: 14px; + height: 14px; + margin: 1px; + cursor: pointer; +} +.cheditor-pulldown-color-cell-over { + border: 1px #000 solid; +} +.cheditor-pulldown-color-cell-over span { + width: 12px; + height: 12px; + border: 1px #fff solid; + display: block; +} +.cheditor-pulldown-color-cell { + border: 1px #999 solid; +} +.cheditor-pulldown-color-cell span { + width: 14px; + height: 14px; + display: block; + border: none; +} +.cheditor-pulldown-color-selected { + border: 1px solid #999; + text-align: left; + margin: 4px 0 0 1px; + padding-left: 5px; + height: 15px; + line-height: 15px; + font-size: 11px; + font-family: verdana, monospace; + width: 55px; + vertical-align: -10%; +} +.cheditor-pulldown-color-reset, .cheditor-pulldown-color-show-picker { + height: 19px; + width: 16px; + cursor: pointer; + display: inline-block; + vertical-align: middle; + margin-left: 3px; +} +.cheditor-pulldown-color-reset { + background: #fff url(../icons/color_picker_reset.png) no-repeat center center; +} +.cheditor-pulldown-color-show-picker { + background: #fff url(../icons/color_picker.png) no-repeat center center; +} +.cheditor-pulldown-color-submit { + vertical-align: middle; + margin: 4px 1px 0 0; + height: 19px; + width: 40px; + cursor: pointer; + right: 0; + position: absolute; +} +.cheditor-container-fullscreen { + position: fixed; + left: 0; + top: 0; + _position: absolute; + z-index: 1000; + text-align: left; + background-color: #fff; +} +.cheditor-popupModalBackground { + background-color: #fff; + position: fixed; + _position: absolute; + display: none; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.cheditor-popup-window { + border: 1px solid #0078D7; + border-radius: 5px; + background-color: #0078D7; + display: none; + position: absolute; + top: 0; + left: 0; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 10px #bbb; + padding: 0; + overflow: hidden; +} +.cheditor-popup-cmd-button { + width: 64px; + height: 22px; + margin: 5px 2px; + cursor: pointer; + vertical-align: middle; +} +.cheditor-popup-cframe { + background-color: #fff; + margin: 0; + padding: 10px; + border: none; + text-align: center; +} + +.cheditor-popup-cframe iframe { + margin: 0; + padding: 0; + overflow: hidden; +} +.cheditor-popup-drag-handle { + height: 31px; +} +.cheditor-popup-titlebar { + padding-left: 10px; + line-height: 30px; +} +.cheditor-popup-title { + font-size: 12px; + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + font-weight: bold; + color: #fff; +} +.cheditor-dragWindowTransparent { + background-color: #fff; + position: absolute; + display: block; + left: 0px; + top: 27px; +} +.cheditor-pulldown-wrapper { + line-height: 1; +} +.cheditor-toolbar-icon-wrapper { + margin: 0 2px 0 0; + float: left; + height: 24px; + overflow: hidden; +} +.cheditor-tb-icon { + height: 22px; + width: 16px; + overflow: hidden; +} +.cheditor-tb-icon-disable { + height: 22px; + width: 16px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-text { + padding: 0; + margin: 0; + color: #333; + height: 20px; + line-height: 20px; +} +.cheditor-tb-text-disable { + padding: 0; + margin: 0; + height: 20px; + line-height: 20px; + color: #333; + overflow: hidden; + filter: alpha(opacity=40) gray; + -webkit-filter: grayscale(100%); + opacity: 0.4; +} +.cheditor-tb-text span, .cheditor-tb-text-disable span { + font-family: "Malgun Gothic", "Apple SD Gothic Neo", gulim, monospace; + margin: 0 0 0 1px; + padding: 0; + width: 41px; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + display: block; + font-size: 12px; +} +.cheditor-tb-icon23 { + height: 22px; + width: 23px; + margin-left: 3px; + overflow: hidden; +} +.cheditor-tb-icon23-disable { + height: 22px; + width: 23px; + margin-left: 3px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-icon36 { + height: 22px; + width: 36px; + overflow: hidden; +} +.cheditor-tb-icon36-disable { + height: 22px; + width: 36px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-combo { + height: 22px; + width: 10px; + overflow: hidden; +} +.cheditor-tb-combo-disable { + height: 22px; + width: 10px; + overflow: hidden; + filter: alpha(opacity=40) gray; + opacity: 0.4; +} +.cheditor-tb-bg55 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -483px; + position: relative; +} +.cheditor-tb-bg40 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -552px; + position: relative; +} +.cheditor-tb-bg44 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -621px; + position: relative; +} +.cheditor-tb-bg30-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -276px; + position: relative; +} +.cheditor-tb-bg30 { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -345px; + position: relative; +} +.cheditor-tb-bg30-last { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -414px; + position: relative; +} +.cheditor-tb-bgcombo { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -690px; + position: relative; +} +.cheditor-tb-bgcombo-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left top; + position: relative; +} +.cheditor-tb-bgcombo-last { + float: left; + overflow: hidden; + background: url(../icons/toolbar-background.png) no-repeat left -759px; + position: relative; +} +.cheditor-tb-bg { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -69px; + position: relative; +} +.cheditor-tb-bg-first { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left top; + position: relative; +} +.cheditor-tb-bg-last { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -138px; + position: relative; + background-clip: border-box; +} +.cheditor-tb-bg-single { + float: left; + overflow: hidden; + background: transparent url(../icons/toolbar-background.png) no-repeat left -207px; + position: relative; +} +.cheditor-tb-color-btn { + width: 16px; + height: 3px; + overflow: hidden; + position: absolute; + top: 16px; + left: 3px; +} +.cheditor-tb-button-spacer { + overflow: hidden; + width: 4px; + height: 4px; + float: left; +} +.cheditor-tb-split { + overflow: hidden; + height: 2px; + width: 3px; + clear: both; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/editor.lib.php b/AvocadoEdition/plugin/editor/cheditor5/editor.lib.php new file mode 100644 index 0000000..5a9eba3 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/editor.lib.php @@ -0,0 +1,158 @@ +') ) { //textarea로 작성되고, html 내용이 없다면 + $content = nl2br($content); + } + } + + $width = isset($editor_width) ? $editor_width : "100%"; + $height = isset($editor_height) ? $editor_height : "250px"; + if (defined(G5_PUNYCODE)) + $editor_url = G5_PUNYCODE.'/'.G5_EDITOR_DIR.'/'.$config['cf_editor']; + else + $editor_url = G5_EDITOR_URL.'/'.$config['cf_editor']; + + $html = ""; + + if ($is_dhtml_editor) { + if ($js) { + $html .= ""; + } + $html .= "\n"; + $html .= "웹에디터 시작"; + $html .= "\n"; + $html .= "\n웹 에디터 끝"; + $html .= "\n"; + } else { + $html .= "\n"; + } + return $html; +} + + +// textarea 로 값을 넘긴다. javascript 반드시 필요 +function get_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "document.getElementById('tx_{$id}').value = ed_{$id}.outputBodyHTML();\n"; + } else { + return "var {$id}_editor = document.getElementById('{$id}');\n"; + } +} + + +// textarea 의 값이 비어 있는지 검사 +function chk_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "if (document.getElementById('tx_{$id}') && jQuery.inArray(ed_{$id}.outputBodyHTML().toLowerCase().replace(/^\s*|\s*$/g, ''), [' ','

     

    ','


    ','

    ','

    ','
    ','']) != -1) { alert(\"내용을 입력해 주십시오.\"); ed_{$id}.returnFalse(); return false; }\n"; + } else { + return "if (!{$id}_editor.value) { alert(\"내용을 입력해 주십시오.\"); {$id}_editor.focus(); return false; }\n"; + } +} + +/* +https://github.com/timostamm/NonceUtil-PHP +*/ + +if (!defined('FT_NONCE_UNIQUE_KEY')) + define( 'FT_NONCE_UNIQUE_KEY' , sha1($_SERVER['SERVER_SOFTWARE'].G5_MYSQL_USER.session_id().G5_TABLE_PREFIX) ); + +if (!defined('FT_NONCE_SESSION_KEY')) + define( 'FT_NONCE_SESSION_KEY' , substr(md5(FT_NONCE_UNIQUE_KEY), 5) ); + +if (!defined('FT_NONCE_DURATION')) + define( 'FT_NONCE_DURATION' , 60 * 30 ); // 300 makes link or form good for 5 minutes from time of generation, 300은 5분간 유효, 60 * 60 은 1시간 + +if (!defined('FT_NONCE_KEY')) + define( 'FT_NONCE_KEY' , '_nonce' ); + +// This method creates a key / value pair for a url string +if(!function_exists('ft_nonce_create_query_string')){ + function ft_nonce_create_query_string( $action = '' , $user = '' ){ + return FT_NONCE_KEY."=".ft_nonce_create( $action , $user ); + } +} + +if(!function_exists('ft_get_secret_key')){ + function ft_get_secret_key($secret){ + return md5(FT_NONCE_UNIQUE_KEY.$secret); + } +} + +// This method creates an nonce. It should be called by one of the previous two functions. +if(!function_exists('ft_nonce_create')){ + function ft_nonce_create( $action = '',$user='', $timeoutSeconds=FT_NONCE_DURATION ){ + + $secret = ft_get_secret_key($action.$user); + + $salt = ft_nonce_generate_hash(); + $time = time(); + $maxTime = $time + $timeoutSeconds; + $nonce = $salt . "|" . $maxTime . "|" . sha1( $salt . $secret . $maxTime ); + + set_session('nonce_'.FT_NONCE_SESSION_KEY, $nonce); + + return $nonce; + + } +} + +// This method validates an nonce +if(!function_exists('ft_nonce_is_valid')){ + function ft_nonce_is_valid( $nonce, $action = '', $user='' ){ + + $secret = ft_get_secret_key($action.$user); + + if (is_string($nonce) == false) { + return false; + } + $a = explode('|', $nonce); + if (count($a) != 3) { + return false; + } + $salt = $a[0]; + $maxTime = intval($a[1]); + $hash = $a[2]; + $back = sha1( $salt . $secret . $maxTime ); + if ($back != $hash) { + return false; + } + if (time() > $maxTime) { + return false; + } + return true; + } +} + +// This method generates the nonce timestamp +if(!function_exists('ft_nonce_generate_hash')){ + function ft_nonce_generate_hash(){ + $length = 10; + $chars='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'; + $ll = strlen($chars)-1; + $o = ''; + while (strlen($o) < $length) { + $o .= $chars[ rand(0, $ll) ]; + } + return $o; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_col_after.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_col_after.png new file mode 100644 index 0000000000000000000000000000000000000000..8a39314556e620d89c2a1f92f8e15d8c8931a3e9 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT+`0{2Ld1uNV@*}2r`YOB*-rqBgnPb zQgJIO;TV&|3BeSlpb4BTC$9HpSqrN%a2Yi*Oi5v2yu`vei!;=}OTo;zlQ*S-ftkVT XDD#vll?--30~kDA{an^LB{Ts5VP!fh literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_col_before.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_col_before.png new file mode 100644 index 0000000000000000000000000000000000000000..d8f3a56ccb1e1583522fd1faad9f6078fb9a0774 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT+`0{2Ld1uNV@*}2r`YOB*-rqB~INa27{-opUXO@geCw!KRoCF literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_cols_after.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_cols_after.png new file mode 100644 index 0000000000000000000000000000000000000000..d177a0418e6698a8fff25c5957928b4de59a5f8f GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT+`0{2Ld1uNV@*}2r`YOB*-rqB0IVk0}ov} PpiTx)S3j3^P6gnPb zQgJIO;TV&|3BeSlpb4BTC$9HpSqrN%a2Yi*aCuHrkTaHaV2HIgY`Sqq#cTp26Ay!Z XIP;YEoTeXv1~7QK`njxgN@xNATTeQC literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_row_before.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_row_before.png new file mode 100644 index 0000000000000000000000000000000000000000..9cff358aeeccef4bb8b0ecdc3f878e10ab0ec9c4 GIT binary patch literal 188 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT+`0{2Ld1uNV@*}2r`YOB*-rqBmdKI;Vst0MT|lYybcN literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_after.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_after.png new file mode 100644 index 0000000000000000000000000000000000000000..579a2db0a153e79e7346d4ba20c58df17ad7ef96 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT>t<7pLXUykOyRBlpL`HvRF!j{DOg81_!N`Ux0j5 zPZ!6Kid#tu$CxBe2&O0nP2glXalJ3gT3C&N%cy}t%d<-%%vjQqp;g6GVD`)-Y(@?Z aj0~#%%w;~pJ6-?{VDNPHb6Mw<&;$S_9y$sD literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_before.png b/AvocadoEdition/plugin/editor/cheditor5/icons/add_rows_before.png new file mode 100644 index 0000000000000000000000000000000000000000..45d46b4b02ae3c37321f35384158d028253f0344 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT>t<7pLXUykOyRBlpL`HvRF!j{DOg81_!N`Ux0j5 zPZ!6Kid#tu$CxBe2&O0nP2glXalJ3gT3C&N%czNg%X5-Kn6ab-!&DVlf!Q;Uuo*ct aFfy0~GncjO{@V{UfWgz%&t;ucLK6TiI69sH literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/cancel.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/cancel.gif new file mode 100644 index 0000000000000000000000000000000000000000..434323b087503f716f0226d939a1f3d6de8622c6 GIT binary patch literal 2265 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/color_picker_disable.png b/AvocadoEdition/plugin/editor/cheditor5/icons/button/color_picker_disable.png new file mode 100644 index 0000000000000000000000000000000000000000..34d8a22923e97b5000794e4e03f1166f4ed1733e GIT binary patch literal 1783 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS=07?_nZLn2Bde0{8v^Kf6`()~Xj@TAnpKdC8`Lf!&sHg;q@=(~U%$M( zT(8_%FTW^V-_X+15@d#vkuFe$ZgFK^Nn(X=Ua>OF1ees}+T7#d8#0MoBXEYLU9GXQxBrqI_HztY@Xxa#7Ppj3o=u^L<)Qdy9y zACy|0Us{w5jJPyqkW~d%&PAz-CHX}m`T04pPz=b(FUc>?$S+WE4mMNJ2+zz*$uBR~ z1grP;werj>E=kNwPW5!LRRWrzmzkMj}2Nb=4b?@O-)TK zOiavSdR_99OLJ56N?>|Z5PB_f>IEf*+ybD@E~!PCWvMA{Mftf3U@u!`;&zJ}PV=C8 zQ*gV*9H(A=pkwqw5sMVjFd<;-0Wsmp7RZ4o{M0;PYA*sN>$0>{&lngO3j=&YTyNgI zdF$4#zkmPUxpQak+_@JnT)2Jvc6WF8moHzIEnD{U=g)87zCC{Y_~XZq_wL=>v17-z zYuC1H+4BDV`)ALdEnK*8_wLbLQ;Ywd>%)gBvz%c=+()f&~jID=Xi;d9!56k_QhS z1OxF!DJRo|4><@lJZxsU&su{k%)xP0(A&M=?>RR8{Hpf4C%z{CTUol? z5{=-+^}d>1K_b7u?|;K^$-#HM*@f)(vV9C^_+yG29S)QVcDls$mfU(Kb%yyvoYlP3 zv6t6xJT38enup2@9e#nOGg&<+Nj(4ZMeMOfWL(+{g@zLoDomu-nAF(8P1f9BRajVj=S`k1HYVj>_pxp0%IeEB2pf z2v~iC*)=di{qu~2w}j1wZ`iU1BwbuyYvT0&qeW}k`?PeyXr>K%oab%Mb7zOWZn_Y+ z{%VV=HiO>#_Z^EQ-aW98v(uPA?XVHwgd@MQ*qY7QZbS$rEKRuL=w|x%`p)nWgW1nI l^i3b-b2J@@eCOW4$RO8K9e(op+?k-N$kWx&Wt~$(699z*Ia&Y! literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/delete.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a03749f68793158cb49b6b4e9b5a860bfa4c175 GIT binary patch literal 2294 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_cell.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_cell.gif new file mode 100644 index 0000000000000000000000000000000000000000..6022fc400f490f39a5c890cc37ad76e88b71b18d GIT binary patch literal 2572 zcmeHIXf8E0vmr1PDnWvLpns1S!ygcB~MR2Sm)$CX}MdgaC*}tu~v` zZZ;WBCA|o$hcuz6)Ef;ETAlV>Z zsQm+I_sNpTAkd%aOW^yE$smVYOspRz_#fMBG`JfM#K=xz!QyG*1@KwX3-eiI_ zMjV^-$``t0;xk}a${>-lv$KiWzC?*EokXV7>2?eXg@9@hIarFAM?fYi&6k z2mQ|XzXHn>a-|R{4w6f)|SOK9d|4>R8 zJ%B=`ht1fsCHyQAB!*{f1;5*d&uVKg1(6i>%!Xvb?T~;YlZe2VAv1)ta|xRj@0G1! zb}p=0ZAmB@lKo)+F=xme(JlweS7jmRps$x-+cYouPVxq9yxrdthD6I zFFrr`*@6AVMf>*d*}bc_Z|F*1zYy z?p?37@2v5}dw_4duXbCta>epxZ@sy6$s3Dti(D5jm_N@2>pXXklcNI$06dIN=tu+B z+ixTL|1t!N0G}>c8Ch4=x*NO1dvkGYibpWcbK^n7+L%JW+%@9j;yt($cUZUHOD=<*mDrsZ^B0c2xqe@5YU|13s@Ac}hLy@j?Y#1u#~0;KdTM@Xzym zucnu+2tV75oZZrwn;Vj+2daUTT?*aAAvgCoI99XH)tgpvHTa4nVzyS5>3>l>ra|7lIRi%+8nu@z1vM$77r=L-9I3}z;7_y;C;6{h=ZQ>fsH4b?Qjm$HHW4wbXGDa9FYRw0B#g zdn*bxatL=E_p5|)pvsQm-(SZDBfV-g-O&NhHFsl4El#c& H3=sG)KB5D& literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_image.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/edit_image.gif new file mode 100644 index 0000000000000000000000000000000000000000..7bf05a0e8c2f548f4b48ffbf219d48ef02418d0e GIT binary patch literal 2572 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

    P%8*K{%2 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/play.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/play.gif new file mode 100644 index 0000000000000000000000000000000000000000..d7da138201d506195b80fefe1487bda05729acf2 GIT binary patch literal 2746 zcmd^A`Ck)B7H>?1a0rNiis&=}xU{xa=9Fm%Uf6^z1{!-fL^cD>Gf*0 zx*3MGTAe~6*BkT(1FTReHEOj&iF5^GA(t!EDz#Rlg&>(uuTv>i2#Z#y)o8R*sSN3r zB$f<E_27#@OTkV>i4Xw(Y1v8&YxNU76m5q6zU3mXh7l@f-Vl`54+tV zFaWo(07P7+Rw?9iofgs2snr^lN(}%cnN+G!Dot1|Logh=r40eF005CUz;MLAp6>2$ zxS3^u4TJ-OfustxM#BO~N~L1?(I+H;6;UD~0RV(}3_+xdp~d@pR-SlK-}Q%7CR@_* zx~}7CZu3Ou_4fpcw&waH*42@?c4^G++q4Vs=ne1nI{oqX$E`#1lA)=s>#A?}iTYg{!mdPOTZ%S745UZs*aKlw1zj1lpaP=!#sZ?F*|5%Cm z0k8r^O)V@I_vg{f`VpsV+Q|LCH{Sm<^Xy1=!+VWZbD`&Lz?JdJr+T$U?Ret-JPC~C zDy6!=_})a*qX|eR+xzRpshiK~mF+5(N~hClkloiJ8G-bAy%b4AZQwESsZ0TP9iPrb%w3IAJaQDDNfUDUX zkW4x;{_(@upYPwj9ep$M`qdvVUkpEg_H^jU;NyWu4+Z^yW4%I>-Mc* zZ+8CDA-U21^YymYYc0)9SFc>Y)OfMs!ufM&>(87%b@D{r@!DfGM~@snbnw7W)j$65 zkE;FqDl7h8zIV^=vR$P+cWf`&wzXLN{g%y}HWqCV6|P?=6!6#bxCQxnYjQd492S#7 z&!%N%uKq4#)ylu6uUNh;ZE0#s@{**)#os2x$Hm4(Q==jyDB+93LPN;GL4l+If1;l+ z0gv-pxWL=X(__B7n=94@{AS)<=Q&QZXU%kUu%BT!-PXo>nw6!6ImXO%DjGG#1OQyr zXyhFNEHoaF#`}_jfq}w0r?`tX9osN7yfaFZYrNfSvHW4sqSkY6<_Ja;IhuX5l)UI& zP_npoE8rIXEIl*=R&qHr)eNr2KGC)?0sdcdl%9Mr0Q(WmKqYbUTlj)daDM zZPQ+jQ>?2n6BJ8FN#$*)V#d~ZH^(cs3D%M9>du7N^sJ6eR`#|Dp2^OAk!700khs*Q zo!x;tc4ZuJD5nv`4k#;eu>)CAeG|)a^SuSk%n;X2pP9uo**_~QIbv$PJBMnKP9eMo z0@J38s~l9A`TJIpS=~RePo5b$kk|Bf98R|_44{;mS&JxTC~KZH#eR@^rCh5A7P=@eA5*bajW>?EM*ir5NX$1zRy5Ws+^Xu%~x?Fxk>u zTw<}EAX(OaZ1^Cdb#ckd0S_Ci35ltlb{w!Gh>A^JlY%NsXL@9XHrfzEDRx-fyc#E~ zI+qunrlC+@CNSqvvg|JDD1q8j{z5Xv57(RgqpuPIlw zM(mExxzWo6w#c3qz7U=ot2SS-=h7X|xqGtJ78^xav)6}KeNewSey+FJylTI7>*&eM zMXm2nHc(pWu2ps$y-rksA!98++Qm#?+rLOVcI{D8h`Fn-ylt$*HGGp-w0(+2Qb_39 XZm53+S1%vPY0xVkhBro0fRKLyyPl0& literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/preview.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/preview.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ec331fe81de633ac87bab2a39f5968f65ca3a14 GIT binary patch literal 2136 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/submit.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/submit.gif new file mode 100644 index 0000000000000000000000000000000000000000..3e5af8d64dc80b224f6c6e910017f12be7008225 GIT binary patch literal 2249 zcmbVMdt6i39lsI6BY=YArKNg_Q$QslJT4^iNFW3d!gyJ{Odt@LjR(fZ$4w@a!(q2ttr*s4Fd7|pyr5bP6UAvvCZo-U8jVJc7PDHc zMxzPE7aewk-e5AB4LBMHpf=oOG#D*btI3R46N1=KJ8CiG28#``>GV1jwIPUAZ!n;! zy$?0GV(#v)OF1 zAXdcgz(aOmT8+(y*ipOLY_eFaqCQNo(>aw81OkAGi3tLvL2Ndo!O$-PL;!$cT7sy* z83G)b!-`k|077gC&S)?i^m>EQWWqa*w$Fy5S`DPd`WzUBqNv4UF&GRsn++F75Jacb z;b)-N>jwu1@hGOIrT`~1hPVGm3B|lNa`QkoPsPLg#1yrh$1fAAz!ITYB1ikT3RksGSo?Ao&YWp zGVrm}OeKRaA*!+@GRwIDIyKW^g%FIR#6g0DOb!fu!Ty#LLyg5U>WFSA$ximA|HyDJd_vL*c_xs+uRK(kM~R zEzJSB-2V-gN?)UussiE9@%~q0WzjadkXj&A!W9a>5QndDO34{%3L#GgD~e#aeC`zU zN?{eOEQRG@S|J367fWOUxKbJM63^u_vSdmXPsSH!v6IL+14SYcFrau&YC<}lM(40O zG+KHLJvBOwoyz8<<25awMVs?w!~6=VP^Oym75wZQJ+H4b6{K=pnJrXEwh9Ft1uO+$ zZkZvOHynL^G1@p%eHLouf4~FWz*#EfbITM~e&f)8{#V4;5Uns+~U4f@H0dv^# zXTxeSoABRL_u~1pr%!(R@t=<$J)C`Te`flJd;j?R_uB97emnKe-|pPL_4QYifBnnN zKi`+1aU4@ZxD z^6}wA2Rjb5?{91UeM__Ecl-7>?P=WIP+zyJc4y5;)jPI-_`&;C+tig?D^yCwdvaJN zEic<5DHV%^0)7ea-QWJ^*PGvYd(+0^w>A_N7UbvsDwms+y*?{5gOkoqOJy-rl9LkG zG3W{LP+V+GG%bosiCnv8bwqgBs+GT7K@J6%FMBiOjipP1g8~Emf3eulchN#0Z!eOk zhr1im)nx$z079*t->|!JPeY9~o8JtAd<~!3+|hi1 z&n-Wa$9MJgXobRBj`LUfwD4OG_4GDNfifvEm{{yh^uFZn?@!DbB@PYy4+nR8Tq3&W z9=TN>c0Ks&_|SxZ&dBF|Zb1u@#ctDX;-D=-;-`LovrngAJf01Dt}|Or(_&QryzNIq z&)#}}USjR0@m^kV?YdEvnY!1fEwT$-C1}vJjqZww-TpzsV(l3yyztcK>*tT%Xph>^ zbM6kuhZGlm`-GL8R_A{xrGgYtr98pyWb9eG;gY{NH;y=x`SJRIocdteaO)&#HmkL9 z{bfzd+a=RsO0$2`v7I@;9m z)){X?h>u&MEU)fP1A(&Hu(CY(f@s8LpTE|ZnOP0IQL9N#V(rv;5@H`s_VUu&8_Qe4 zhBKYtx=x*!z?Kj3cXWDbLlFDwmL(5Nl?sQoaI|F#%6yzP>RPOsj*qTaFb=cvp)4Lz~)`{{a7e;=@ z9P4TwVm|I#R3jGNlg3suOp6iBYM}%mw`= znIL80!6(^012doA=(#u(*j2Mce~`!VFx>5i{X%bdKf8k6{SF>BBi*ovi+dC7mwq7s dhEG;k=!-A?i_2e-t_6!vzjrN5>+1om`xga!<#hl6 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/button/upload.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/button/upload.gif new file mode 100644 index 0000000000000000000000000000000000000000..1accaba050e3a1def253c134298b529b93583923 GIT binary patch literal 2275 zcmah}d0Z1`8lFIaa0t|bMLar0iWj*c86b$pBt!*6DNvUv@wh#1x7BKOxo`}#b`XTcY%v-jw;Q)ut&qX!a=P4Z z4~E%rFAOu8%r=s2#c(%{*)WU6isNpF-QmJr1YyK+7b)j-IB=KCZnv4tCbPxT2r2D0 zyBl{~Emnf)a5$V!r_1heSTU=`Vs_&=8G^?{IGql=-9aunNr1~~Hkk;IN7+Hx>~;^~ zAppWb?%Qmb)k?z2-bE6ePP@a7yKoOdC;=s5G&r0No88u_1TdRT2>=vjr_)86b6{Yg z5dv&BI|Wc$triGSl41}5K*~-lhLOF+Y9Tt5E*ys-rI`%cY&H@E1u_^6kP;w|fv{LC zULmK`WHRA6ZX>nqcDLJYHk-S&MnVFEL@;!#GDAvRQkW6YV}LBPM-t+8Sj4;*5$22VO9>TLsn?zFbSXJb%pXp zT3Dt>w0Q_pGIEO9MTj2J6(J}n%7wrw3so8gQmUK!950pf=V^3$nMMxJ6Q|Kh1*S@+ z;IqYSi8wIW5ou0s+Elf@n^4RGkTrnbFp@ud35w7A-Zqh5c-cnGb zq-Qa#Rjq^-5-p+zpQp@My*d`|EA?J*6|atk_ew5{42I>s*#EfbktMQvyu+7eOHN)E zKCB_DT}zfVh48p>7x@;Df4aqNdiL~>-+%k{$>T>4hacSk<=)SC@BH-RZQ~FB{KwGu zfB){*-@d&$c;otCuU#Fua{1E5Z~8Cv^`7rJclJzo*XhoVQzuUxKh}Qq>m!HTzB+X9 z!2W$-?%mV6yJgoGpYPo9S##6&ZCkf|y1CJ?siA)3hV|>}YHQZ6sjjN5_~hf&fBC3< zRaxoE6?&a^If`i1CB@5BMTJUOAzvyh`0#`Gmn>fNUjD)b@8;#^yp#QQmUMn*#=N<6 zBRRhdneSIhZ5aXbdZ7LA&eMP+QwIG0~NL^mNW^GMv-MaM~>Z){E zg^i)1g@#YJHoo21$O~F33({(HXLl*mm_;sH< z-xC$plX$3gK%49rH90Zks%YU(}e@FR5?8us*oT0L>% zu=$?Zf;}D%Q=72c=HXuBCRCTPrXaVf{z7edOvZZ;QCVncY%|D44yH>q9xnZ#0JUqB3b63{cF6+a|@Uow- zr^QK^pdX*HH(F`~l36RuL7-6J!hXNq^T{mGljXpk+_)50>#hi(oo3(gQRjzO`kABZ z3aGE0XczdKn+p1Tg1N~pm7{Ztc31lgn`CR9@dbCP)lC(H{!^j{X9xK2Z0}vq&<1wG-X=!X(|bh2w26VSv}GmP3#CPQDma|Cr1}2V zqFbmqQqIl3pI>w!e0`IudFmYBY59+o&FXDe-V&BjK@kvbOrd^J?tk7lESlO96j~Wq zlP{T$wqI+#)&^EbR(jSAhex+%9}L-cq#`>s&2seO{+609$>`Q^YXpJ28X_MrY~|iP zc%Zn&sT%!tLsv~iF{lTC?gd~kB_Qw4^rMmXJHEj)=du^8&v^!flrzT+3yuc>r9g0G z1S%MFYv#DaVSO1DgS5aVO3heC({5(hlenkpK9gE9HK(6^)+h*m7AHWu?T1p4vlv#4 zoS{h#HNC36F@3#(tc_@2;JA`%TA1j})7bvVq#2d{5u%di(a?~ghLI|GcJa!T{cWa! Q_>NyqSEq^EMIey+FRf+=(f|Me literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/checked.png b/AvocadoEdition/plugin/editor/cheditor5/icons/checked.png new file mode 100644 index 0000000000000000000000000000000000000000..029325ef6e3e19ef5b11af4f6844f649b86d7f30 GIT binary patch literal 1081 zcmaJ=U2D@&7|vEVb!@Jp;M|2fWI86SP1BEb4eR=q%ofcUZD9p(Op~)MbjeAR)3qB4 zQxvK{!5dK!CVrscjVS2F7|L#Bcr`&}=!JSA6TF+~$y}!w){x|U@I24^p7(vu)rs*_ zT^+q06h(Dq(n8i5oo`<|`CDH;oF~IkEEaGMP2s9+K`No5A_N&-o`zW{tMlboaD<{< zw3aX6f^>#gknWWojJKwngiTQ+v6?9>C5S;0PHRS#{`&Me4Ky`MPlhC)WTxPZmR_)6 zZecvHER>XpO2a)l>9dB-*P`^cE>GspHbaAL2rfnG-$@mu36Me-1R-z0 zqxe`BaGaM7hB%HL0)8LsXME)4JZz8;alAhab{?8Uv(za*D~#>LBC9ApgR#joOto6| zRs&vSO*3pH5^*&Aeh)!-?0EyrHIHHUHxvYDE0$(r4H>{ul#8f>qcq9%_Yrh+SJtq1 z%0vpr)MS%ky*}qi4WK0bAFAuSXd7qYpM3u*Z0F}q$Yi07DwaYTH`VWiGWnDRWsIym zLbHu3PRt;T>=|T&RE`6KlbWHTs(o@BFG+mHu(50?Fe5~1qTtmul@E%Er05Sv!pTUI zWyL^5WP{1Xu$bV+LXm(dHn;*(DmpZ9gRB1GCYo{`E9fSPEI><}gX)-tbg+G7UTdC9 zxT)R_S8blla8oWrl3|?2{?+Kl7IBX=-L)-Q>>3{$#O)Tbb#KR$TjWaI&j^WpZN0el z^JmO;XR%Fqxw?Aj?&$vdl|uUAxnB3%*7EU3*E!dtfVJ{waJc^cb@EPoeUjSjoHg28D&XDT<(2ro&SgEm z)mA@UUOD7`OtIbWzP61c@u36D`{P@CZVb4W7S}$;pY_$l@1=uj>O=R5rCe-dZ8<%@ b?%L<0)@~n*^}PA~$+^rKaa?$iJa_3AuhUtl literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker.png b/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker.png new file mode 100644 index 0000000000000000000000000000000000000000..3ed7f55890df78bfffe61dbf356924ad3bc06cf6 GIT binary patch literal 811 zcmV+`1JwM9P)F`GcoXb?vhdsD)-5fm;_(Sfd(&Krc+`1c<&WxPq?LG;mQ>di1Vlfg= zC8O#mavNn2br3@2q75}~0Q<6p?HtvlOYx?Fk%ohH9ld3{TgV^{2?}J^30aom za0I|OJt#9G@&`a(1PV2v%-e-^=)Dbrm;sxLBC;?+w?&~24=;cfMPwNw;{?|KLlTR@ zur&mzKJf)@t=;B!*mh7R4@YRV0>KTS}ZGS*{a7)sGcyK(j&*WdHlfA)5;t$R$Al>rXLW)!~WjMPlDq`q5C8!O+Y zPf}L*~a`L;Z PKCZl?^}@uHk--`OML81Y literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_cross.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_cross.gif new file mode 100644 index 0000000000000000000000000000000000000000..089b6d1590c90a0a243d73c77dde18bdf5e69e2d GIT binary patch literal 1922 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 YzFqsNg>|5V=vOIWZ|#VBZRvIQe;Bk#LI3~& literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_hv.png b/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_hv.png new file mode 100644 index 0000000000000000000000000000000000000000..1c5e01f8bcecc4cf835e8eeeaa43ef2c06789022 GIT binary patch literal 2865 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 E0LKozl>h($ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_reset.png b/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_reset.png new file mode 100644 index 0000000000000000000000000000000000000000..ba719a74608833a3f6376778dc71e71f143b88b3 GIT binary patch literal 1768 zcmd5-YfMvT7%m`&Ff`6JCcBs%>n>uTS6bFetF=YJP{K-`U|iNidyp1;PB}f;(%Hq! zrjsbnZMdn4&MhilK%Bses}adi333$%lW~{cC@mC<6k6CR0`AAy?|nHZ=X<|A&-1?T z_dVyF<0;A8SA@S6P9P9gBqj*O_;Xd@4hta=f!XxX`&>K3{jE60EVnnsc|-e5Vu*U24&e024p~c6)>0N z`t3dmP{_HYT}%;Gq!vI~iUd6hrRtLT2)dU-W3$--4LUsit(?jU-PEQN)l2$wg)O!DX%wq*8MPC@iANZf>?o2 zK#PfGFh8WnGZwf)M3$?9U~GXaf5l}k$qiURrN%Q0Ayly+l5ay16)@K_N3nD*^doJVJyj|;Kfh^2m6nMURc826PPaA77rGU55c(GQQX#V?^Zm<->l-4BuP9or#SQW z@JEHsJI}Z8ENs|)?rHj^uC+#=yu=RPuxvkGlXR*stFSs2E8Ub=&c5Ro9J&8x{fm=- z&YY-mAHLaI(e2G|^ELOn^mn@T)o%Ov^iTD!XM-bGYI^hUK0i{?U+eInY#6=YYSEf( zhSIJJUDF4P8n4z5UubgcuD9>GH}Z8w2lMWv!{aC3oG9y^z>JpDf6eyT+&A0YhH8gp z%%{BCUe)P7f3Is(ku~i`-;*J~ciMlkWvrmX_syf>V@(qYw;dLzhf(EMms_#o?z6S7 zk|!3_Xg>VJ>+txp%PbE%M+ZlzD?2C5PS2EorrrADtKS`c<1?9MmSYbbcX}o_nEbkm z=V+y^)#<-n)oE<9dP(}%zx@t zmYECNCzFc?c!tXFdS`R1U8k$80~52#3TvI+zpu=!zt;ALZ8GaZk9f;DMw`1*Yd5hGuj-;I)t{`-%y+Y ztum>U>UIURN_nN-yj$a$f^`MFqt2GnmHgW4yycZC7kTDi5`K&iHJmdn&^$WgW-A}%5#j?OaRd6u(2*z#+OqV;am1g2t*#H)jE`@J_ zoy3kuYwA9J$5OnKDBa1DhALBS!!qR!X>d5UyKS&sljHGRK3lFM28FI(?fop=JM=A` uxK>%tI27D$YH&FEOzBg#JCdclehwly=xN0+$)4%Jzb7$1Sy-}FdiZano?hDk literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_tick.png b/AvocadoEdition/plugin/editor/cheditor5/icons/color_picker_tick.png new file mode 100644 index 0000000000000000000000000000000000000000..a48d9da7d123fea36afbb49f61e47bc326cc7014 GIT binary patch literal 1096 zcmaJ=PfXKL94-M7AqXc?6U|FGh{m;R86_(#gRPw`VPn~b>|hLC`^K8lzOH?^!U;_b z;bfvw5{Wl2UOaeJqhdlNUOdRfcz^?EH6A_a>)619^QC{@`}O<2-`}oh(${*s&v#Q4 z)tj7>v*g`F?o(au6xH_h^_g{YIER%2&Y=>nsSczjbyS2PX{rk_3srr&x&tE=)lM7v z0xqPcMGcvZ>SGwsvbFsMQ*1LDYmV1yYCXhDtx zg1~U05kcUt0zSy`Y>-?+fD4Hug2<18#-fQgM=yz4InnS%P7+zEB0=}YJL`ztrNu-A z&2mi8PpJt^rTz~!%_Fpnv+y|He+s+#WgD_t=%OV@BaJH!`mSs-?m!hICy&r#vx=EA z!pJQn8^m)07@9LI9o5{+b$lu%CM_4MmIjluL=y$ZFmy2{^GZk%h6O$r<2WT08x=wd z7vy7;qk<9+b4{*{v?UW-xXIOzxuKR^e-uocc$T4K+=6<-K_;lDEE=t2;aci7xO(eY z_?BFj1jG7`{j1SU6PX@=do;G>a5VVPBGc}Wu{O?*Jtn`zmCSTrNhA`LN+lkT&(6-y z%*;rVB#L4>ogNz-i$o%dqC}(7-}UuO{PcpbPUCDkcW7xmDdp|g59G^YQl89vUy6GN z>fXVLF3@?i^WrL1+}q!8>jL1x#_i3A19E#ue>>a9_Fc+6TD!ZpF#uL4=vVXA>*>yf zWm#bJ$pw1rV^9Bl|NV`Pwe^!jTkktR@4VY?E4kGwXaAVk{T}?ey4yzmy4PXe=-wVD OeyOCAmY>Jw@B9I=uVS_U literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/delete_element.png b/AvocadoEdition/plugin/editor/cheditor5/icons/delete_element.png new file mode 100644 index 0000000000000000000000000000000000000000..80e1db21f075cc1831cda800410a4cafda240d39 GIT binary patch literal 543 zcmV+)0^t3LP)1(b3VW z5fQWz5$^8poij6uMMb1DGqw>C*^G>}Gc%|&Gr>hgp%D@4>gw2xjQI2Oy+uXh;^Lr1 zMZJuS`}6azGc)2^TFypBwv3Fv5fQO7Godpxtq~EcGc&j@F6?AvwJR&I7#OP*6w*pc z+uPgC78bq|67FVZo)HnNBO~74-soRnzc)AC-QDKq=BynZ)=o~e5)$ucXXxnY%@q~u zVq(l28=)vDn-LNB_xIRPP|Ze0&d$!D78b`eG{_<%$rTm06cn{4CZQ=Q^lWU-92}n$ z6ZLIveKRxHPfytq5z!G5yE8N6TU-DC|FnjjuK)l5xk*GpRCwB4%*PUfP!L4XCn8`* zL@R$)LS_xja}00I+T zH+9{bcmSZqDg2_W>1zOG*>0GNQM25cZ}JKtQ+j5vYnRhe4~2ReKrnGEGPt7*!xVx5 z?{>g`?ykVH2QMJCOX5za1&&KrQvmmc&<>gqn!~sOv8iGB48xjz3?Q8<54-V90*I>T hZs$=&z+Z0x1_0Z&HUNjKRs#S4002ovPDHLkV1iNB>sJ5( literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/delete_table.png b/AvocadoEdition/plugin/editor/cheditor5/icons/delete_table.png new file mode 100644 index 0000000000000000000000000000000000000000..87805c966de7bdcca872e353d7705dbe8c8e8c87 GIT binary patch literal 1605 zcmcgsZA=q)96lv;MrLGgi^GiMR`?*z+TOKL;6jDcE2G1*rZfS!WT7tyT%dQ|^_0?p zQxRlH!Ur>xO_6Aj@MZ@iQk6FaffNh)HU<2h|;+eyjmL}5iWHOzhrZ7OPBQ+Q()2mZ3 zC8pM8erv{1Bog^<1?F!!_v*3>yH#BTNRhHVvae4VHovBGz<63k$?` zB344M9FiL(SSlW4rm%Q(oJwm>(}w9-5eLC=6T%4SFik2;Yhz;0NAEb98yW!`}*>y+-;8@*#-w2ySqF4 z`)3vwS|2`~aya^|){}mI&Aq)%Jw2xdg3w#DKUP+X+81wjbpSx$~=WV+z|`Ek3w9)^RPUgu7_vd89x%`-NOCHKK3((16D zJzG*;eX*v-J~(*n?szo}pZaqt%l0(9ZGL=i&eT3q$!1@vuP2e>UNC{^4+x6c*mj&p)A1T!mo^ zn_ZQjUYnM7Z)C(gIx{gppL1`bfFyf{hb4Dc-nd*2r}OFTY~F*H$BK$jySu?|cdxF> zyuHkS2r$sfxcD{8|F#2GwdMiidrXFkRi;5zS3-PiBp`hf`<^U6X1XcCTUecRDKYX& ze?$4eM+u8=@+F!*YQJFJ(^FD$p{A(pm$p~huf|OyN3UanKO?$#hV=sE8%#1$n< z_8U}fi7AzZCsS=07?>FXd_r7-ir>9^_v+QFM~@yoeE9Ieg9mr++_`=G_N`mD zZr;3k zIUyk-Ha0dgGBPkQ(8tHe)z#JB-rmH-1Zc%57!85J83HRS+%$nMV=M{s3ubV5b|VeQ zsr7Vm45_#^<-$q6W(N+2fDL_J9l!To{r~@zo4VQ5bB;S5o;fNoE4|hX)L9bWOGIjL1 z<`(;O?~2FVdQ&MBb@05V6H A_5c6? literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_code_b.png b/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_code_b.png new file mode 100644 index 0000000000000000000000000000000000000000..2ced606d5758637010aceb7463bda22bd0814360 GIT binary patch literal 1014 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS=07?>FXd_r9R|NjqE|NHmvPoF-0{P^+1hYxSwym|fl^~;wp zU%Ytn{Q2`|&z?Pb^5p#a^JmVSS-EoM^5x5yE?v5K@#1;&=FOQiXU2>f_4W02b#+-; zS?THNDJdxl2?^oh;Xy$`US3`?7=4*1`aan$XYwLzPQ>}mhkIzh5JdvsMocHW`W^;MobUKK!Z~DS~ zB5J|eZwl{|6y6o_cFl`#{hh>ps`0ND|5J01>0ka{+djWLOT>Qq##{eZET4KJBs=`< z9EOv3G{O(I%IlfDt21t76KZ{?CG}^jsBEj>7m);peqoNlx4Pv=Kq2Po>gTe~DWM4f DAMc$8 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_a.png b/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_a.png new file mode 100644 index 0000000000000000000000000000000000000000..497b4e859b9715481bfd47974be9168fe4480ccd GIT binary patch literal 393 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS>Jis}M-r^P1VV-=9_9xN+mbg9kTn-n@Kv{gh_^ zmoHyFe*F0K>C;CKZ9a8${l+zO4_I3R^}TuX=CQZ;GyLa#Y z|NnnAeWnG_M6Hq_zhEGjIKW`E;zJBjSGK2%V@SoVq=4}22biv0l{DGtogt*HsI1Z$ z+TQI%Nz;XI5;8;1fze{zxk^r7(rlFjOrr=U;;0g9nep z5|XC|J5PQfl$tm>ZR(WgA}WR+6I4yEZe;NFZD3$#`0Hb4r=W1j3TQ2Zr>mdKI;Vst E0E=tSf&c&j literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_b.png b/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_rich_b.png new file mode 100644 index 0000000000000000000000000000000000000000..732f8253da04425e5896bc991763cbe43d4d850a GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS>JimC&ALR`N;t31Bdd&7LEcP|b+fByXY_wO%XzWngv!-Jc< zUjznz`SNAcrcKu_?S6UT!pHslA3l7zbKbmf-@eVLub(`5@|!nrj@a8jefsp*uV0tW zAGmev7SPla+ZsN9{`|k8VOD48l`B`C?%cU&$BIvHZvOf6=l_?RfB*hHbLPx{F!-oy z#tqbfdDge%f0IN0^k1Yv*ZaH3H`7r z{;+Ol1*dXh1II6|8taB8_u9UeXRl7Ov@F|D!Xhgkt{qTU%pJ4!M2y(mWmPZu@9`AN wN~P_wa|tg{HkRFcr`}JA+i9`zTqYid$(Kxycv&jx0PSS(boFyt=akR{0MBgDTL1t6 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_a.png b/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_a.png new file mode 100644 index 0000000000000000000000000000000000000000..e14add2295260127c09687446bebff0cdacd336a GIT binary patch literal 538 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS>Jip~f4gt(r#`SR7PSIy1Mixw?9efso<4I9?3U3>1_xy_q5 z@7c3w=gytiAHSbDbLP{hPoF=3zIgHCqN1WVAHU6+Gw0Zqhj;JZJ$e1{savnkTz`1t z=Buewr|#Hy`2LfZj~_oid-KW0tvhc#`S9|?*Bv|dUBCWh{`~oS4jh|3d-j?&>vkPD zdivU<+mBuzIdbIOy*CFA9Juq~$+c_O9=!Z?;lhRMPd=2EmTua#Y5D4P>o#tF^5)CV zeMd@4N-o}ibMM8crOTGzzJ2@n@k=!|HOrSTzjyE6v$tQ)oH_IE-Mjz)|2r3DeFJ*U zwIs+d7|5j6a(E@1T1Wy;okcwM5=dbcHISRO3ocT5O&fKGS?=Gx<_J2PohoYkI z{p+8DR0TwZ7hSMZH!M^Sf^ULqWpA(Ny7g@4=jK4cGkXv1!=3prm$}H mu(J8H=F*8JUxOPM8D_2z`?>S==OUon7(8A5T-G@yGywpmk4`-R literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_b.png b/AvocadoEdition/plugin/editor/cheditor5/icons/edit_mode_view_b.png new file mode 100644 index 0000000000000000000000000000000000000000..29fe9077a28b607deee4a0efba57bd0946240506 GIT binary patch literal 528 zcmeAS@N?(olHy`uVBq!ia0vp^58U}fi7AzZCsS>JicSXjgt-3t^=s+Ur9C}8M~@!ezkmPk-Meq!zJ21vi5oX= z?A*C?4G65ec=6(sx8E+^d$n`#!J3+y2QS{O+q8Aho;}BpUwZZG)twig&)QD zC(ph4{G+zEcIC>IYuB#5e*H;HOUwCt?-ndraPZifs;a6BcV4`G`}X_y@3&uke*fj? z?dPA*o;`d2@$(lSeq6l$^z-M>_wV0-^!n?&ckdp*czfy5ht+G=ow@b=>C>khH*P$1 z{LIxyAGU1Yb@;@&MT-`F{rdIH-FGiP{5W&w%zrRYaQ*xN=qcxtAirRU2qh$gV-m}I zpmBYkE{-7;w@NNt<#Tf6alIHPerIm??%jUr&;HwUaVRP-eRKWmrQiwmOuC|zugEi8 zKNYF>hoRznkW%o+hNk<1$wwZYT>jwA(bY?w6>~ZjAH9+ZviQbgH~Y4T+RC>)8>>2l zB_wX1&Dhm#Dpqpb*5GpPZJq1aS?+yZyeII1gKXAWY3{6>ycIuoc@_I#|D||<;ZH{B Vo~YMPrUPBZ;OXk;vd$@?2>>yPO7{Q& literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/1.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/1.gif new file mode 100644 index 0000000000000000000000000000000000000000..192f26f6a81cf4959932ee521597b4f805dab2f7 GIT binary patch literal 1478 zcmdthYgE%^90%|}17v`5NkzU zKwu2H!~oG5!qgMUWnAPs0cD#wRA5deOwj?;_-|}`{*8Lm3t#u5=hg4cbH3;MIlo_6 z1Z7JgZ8@?W!J3h>Kyn$&V+O<8>QYpFfw&B4M^PNdce)Y{qX2&dG|lKt7mBL^J`D!i z&KZ9P_)`F-0BRrN5HwaX;j5|A+%&Bcz0q2s?*sTtpuYtSDp1JUfe!*)V;&+5O4hU6 zSB>|@4W&tN3e0y#L9N=*1K^wr&M5UgU~UktJevV$#|&*T`T+ok4hgc4h|0O*>g-p2 zl+yg;f66I^Kc~+>pgg-4tDRC#55>;*qo&*ZxjU#xn2o6@-K`hkWRvkphf#KRT)gk` z@Z|&_S6O>mXjcqZ1ABaApij4|O+|!@K;)y?ktvV$#ST4^}O- z?~zo{F-eq&e;B@yH&!Hxi<3>y0n{iO%afqy{>xU1;75i@b4OB1hj)RvDyy>KsICo2 zt_Tbx-(>D1iYvKua#Y_A=7v#dM!RS3_`om@BqFx>LO#|Ki~XU{j-dE3z$bvQC-qf7 zrLmGJlU^Hb+KtbG2}zc$OC%~v#coGIx%t-*xC%`C7T-|){oD`==Yg&*9ZvR4w8X=g zlh_lAvUZO_RiW*Vf%DUq1!)cEPnyPRjU52jf$odnjf=i6WBC{d*oHemE#Ic=`0S?m zLpTadFTg@CPbb+0XTZ2Pa_~|VcdrfB@`b89+<32kp^Kqwrs>)NZUkj4vO&r%Je7{M z(9K(c{O=waw~q>?#s;I&p_>9WT3VP3lJ!>Bbfg*aTP(YHCI}Hn(rroMmxb3ktCK|; z)e$#PP5|fQ?fJctk`y*@Yt;dKZbc=$Mw(rDcA5(-Z5d>H+ zTXtrXFs{ymek<{*KDNu@Ey9uKtJNr*T@iXb$iHR7t}L4~C3agF!lIglsAgqkkGIol z=k+CS;T&NR@p8)8c|BuV>E&saOx`}5#V(bw44b{9F`j?;G1OU|Ck$34SZ(%pKjBOD z`?CJPA+`IjmYK1+2V?SpKG$Vy>VO~et<4VCwXWVV?jyqCI!aigly(I{EZ5~cN<B&Rw6MMEE}eQakTZTTGBL+_J%LU2;jEO#)hJF#X$K0NsTI_Eh1%=7FTZ;G z`_laf`W$!XF={+&GJ-h{PSmXlTRh!gmzuno`oSW&rM(+T%3#}A5L{d`oAPM&Jc0vB z#IJP;IZaxf&t$sW5^~%={RMc={)@Nxy_C(~W^i-ZUXDj68RZo>5L2V`YLi6qSHHTc W=tQYD#0zfny-eTN#{UPUKl%$zN_SuY literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/10.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/10.gif new file mode 100644 index 0000000000000000000000000000000000000000..67dabd59f01da19f20b6de9aba2ab9b990096517 GIT binary patch literal 1408 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/12.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/12.gif new file mode 100644 index 0000000000000000000000000000000000000000..dcc1c8f640c9ac5d486cda707d471e343d339ea5 GIT binary patch literal 1459 zcmeH`ZA?>V6vrX$rn4DboC8^JOP#QN0W-R9jsz;%T+*YY%dHwn|@QAH#17u5Wa_xogm zv74*DeRfWkpq8Aq-p@7na&3#0)XeU0srd9o;!mAiR;{^@k$RA0-`llSOOx$J?H#OE zIMT=^Hs-n{1xrI!*o|!4Js?aEh!yCn%hag4X9p!+wVCrBDV9DUO|Yu~asdcE5Ie9m zR!{B%frIVYJzNPRZCu+D)Lj4eamyFP&YI+>JiBSatmW+Vb8O0NYv1QXva9xWSeUqj zFVqoR%T_JS_IyHaz}h(1Is@~aDf7K4q?O{SexWd7VPh*-*5(qO&hHVb%GB>7l$X-7M!2 zs>_{CC7RwILIvxS8I^_cCiCv9Zo0DK>zjqg(tMcYULgO+KNIjLX`GmI+z;4^F(GdT zyEsvm{ubALUWgb8a&$Sq34)Rc+ubLwT|6N0*zrp~XBcAhD^ACcC#H`v5*Se#!K?0q z2G?5~eu+~*GE{=-dU;;-u#+I*y<-vIRDPLU#%Evf8J%w79`-&RD>6JXBp-}(9{N?? z5wC6Hd?zp989SKt_+($DYI&Qh<>d6_Y__&AS;x;*u&5-?9Nj$=6= z7c1So6|`)$Jt08pUH{H0UeBTOz^hKe2!nbm&65_*vV9ufA4}sSUVd{QHpGswXw22n z@c!t5XGs2)a{Y9mN7*TCF%;EW!(MeSHF_g4n7Z0ahy-4w>xHZ!XAv6I;WXiXATm+4 z%FxqGP=OVWoD6rlQv3Etx8ll!c^sd>4ByvtQ@e>ee~+!B2hcrYuQ-UgAp4Mm)Irby zgw66sTX_R~^sSRYy!PVvfqwK-NTBSgQov$Ig_bAzW5q9P3`W=)#%cFTw$L^5vrz{k z!T#6YeZIWG9Tc(-XFa5VoT%`L5@hul#O&*0XXlrR{QK#95B*~8|2BP3ghsi=4RNLJ z?ukV48FAP2{d{Nk5fJ6_qF;E*gQ{>rD4U`Csj5w{Lwl(Z2Rs^;a-)(6N_PmLtzrtE J2c6;@`8P&aF-!me literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/13.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/13.gif new file mode 100644 index 0000000000000000000000000000000000000000..221e0f2e2af00f217dc4650ef49b7f5b0b0da8a8 GIT binary patch literal 1363 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 Uv?JEh!;DX8Kfcoc3$z}80y3avwEzGB literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/15.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/15.gif new file mode 100644 index 0000000000000000000000000000000000000000..adb78d17a092d57f20347e565bee01f49491c756 GIT binary patch literal 1214 zcmchW{WIHl0LQ-(LBn=bSEnB8v347#WlCGm=kY#_nPay*)#J`O+M7^oYqmr@)w;=2 zk4sI1lF1QONmb)nBlXY(8$u}+YIN~Xb8rQ~mjK*bgS*Ruy6Yp|4d^1kHv#@Pfd5RWdH`I{9Te1P6%z{` z34B&6d@F~FNv&cW9|h<_4isNju1|6*(giiCP(Gx3d`Uac9j@`j=6E;;)I&fs1@LVk zx_<@EmJc_7j}4^@YE$9%JiD64siBLwG=5{j0zYA}rC@U`R#=;&nf!5Pkc}+^UVSn4 zDn~lNLAzsCM(YmxqE;krgHM`-oFCxWWft?Mh+ECC&lPg08;@dz4=QmD;8lI26h`5T z0Gn$UvQs$sig#@sH3Q$W7#X{3)7UZ#mE0Zt<2xt^B2F2viK(25T6tOycNXE!OI0_} zD*l370PZef(rWe{3N8b1YaVVdLB(@XO|C}rD>@EDwKsWng>VU|x-+#KETu5}1uuEH zr3PKB#TS6O2cTm5g0K)<&(TPWM9nl@1>gkWlwZY0sLHO`JzrO4SKP)_yR_%-G&fPZ z+z1tOQt>0WH4SIMOy^gcou0@2JI zUa;xc*WbS3p&kQ@_EzqB4}o3VWQ{;$#gnA~@?eA_FVpb-10KA>xwX z(hTYnlO6IyC+x$IXBD$w8y1jrU5}lqx0g1Vcvx23e31Y7&+ZqM&Vdvf$u!v1xtB$^QEll+FV~o0XJqS7C049{h%oy4lG7O?ag~EzUk8DsXJn8> zf0)|qb1pc~KI9rfhooat&+cQi^&BxvkCtiJB z(Lth{5kAp9?&?h_kPsY6(W|ZuB%dAQMm~p3m5iTE9@=%Z(TuB{uVqVfC0$WXAHr@97pK#ON@vxGs9UsUy1H|r zuo-qMo*kLh9`fZO7j?eI#;#6iH(#zJOT>P8p6By9{d9lAy?=WB_?p+u`@kVTubszj zFdIy-!U#4SK|l!-Q7=FgAO`?B0;q9-=7I4!KyQJu6&POt^bdd^Cu*e0bYUUVEiph- zfE)rHjrZZ47HI(e9<(fsnGU!J=!rI3r-ai=ef4lF7Er z{vxjNLHJY`Z%7`kE{}v=an<4&vM~tiUJ#NK^88cu>+)gZs!0XrCe+3*fM$XGUe<6` zC|;69_J0TGG-w2fvjviZbg~r?kM308yJUKrKvtyY7YSS_zIBoA%hT8Ms3%~! zKGd|0Y3c*8EpD+nfa(yo)D*Qel*uKTbU_ByTVQ&2ZSpa%x9M(msmM@w9KVx@dH}60 zg%g0%0(sdjL*u#0J_R{aOm+iPQzShNMmwd(CQwrxBgsh|t`3#t2;heis2hYI-r#v> z_4P;Lt2}*Q0Qw8arB`X4s-`FgbuI}2sC#K>0t2<&(Pw#h%sONMa7NuCyMPyELJc5Q z01X4UI0at;xG)Ll$B+rY+1G|f(EAjJW3@!_3Bwcr(Vj{@5rF3>!Wq!p_L#sgw^WFz zK{?fWW}x<4{Pr1Y6bv+QNpe#tAW6ybh_Lb*7%lDrCg_FCw)Pl2PmvdUO=ilw0tzc$`29Ig7 z&8%-Qrc<<{XZO9#?EIHu4$7*yA9cx^I_;)4u8iMiDI?G4+5^D!ak?d82%SKgmHjzx zxsc;%akJe#D%_@Gzqjp{)DTR%s~>N#OnmSVV_7A!+@p3p6)h9w#Dph*RnS-L}euw zZ18TCX{#hXgC*{-N-;Da7$S3BcMtvKZvS612FAob$1Ikb9mUG+PKVqKlby2kkH?b^ zAK^yZNnLoiABI#PC9-x$iw+<02!50#Q8+#<{5?<>S+shge9$>mkv9Hys7tR&PaT*CkW literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/17.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/17.gif new file mode 100644 index 0000000000000000000000000000000000000000..79382ce8a127f29789abd25b20ca394b23dc402c GIT binary patch literal 1241 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/2.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/2.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c83e50cc33b78a6d472e01b2b24609cead00758 GIT binary patch literal 640 zcmZ?wbhEHb6lM@+xT?W$^W@SX364Lv*KA*0_3=jGuQQ$BUthm>EP4H+*1yjV9p5#7 z?!@9h59a=PTJir(+W-IG|DTyTrP}HC_Jldrno*h(Ey*0uE^Rrywsm=f&i6w>>t^OG z?=Zc0%yRGA?DyZl|GnvV?B4f(=X~yM51rCeyu3qaPPO8{XTJZzfPor7@jthpYe=xO zV}PrXo&hr>&`iajEUf$t8Vouh^FiKZV7u)wrNBc+s++4tXrTq4_0pi@ObiZ7kNX{Y zJW*;vjLyeRU+4I#I(Js<>9#Q({pP~CQW#cuE1U2X9Qx=X0QN5z$iK`C zj0}7XfRj*Q{7ev za(-@^+%VgF&ILoo7v+)-yzU@RXt1_xfIOiA^g$~NAIJxjG*mPc6lSU{ny=n09Xfv{ zKYyP*$l;-2hbyV6X{=uaboS((u^RI78xHN#*c~gs>wIh#x75)iN0pelueo#I(%^`7 HWUvMRTdmdg literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/20.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/20.gif new file mode 100644 index 0000000000000000000000000000000000000000..e55ec3081d0a522ae1ad617ecc1202e0059f3f92 GIT binary patch literal 1717 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/22.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/22.gif new file mode 100644 index 0000000000000000000000000000000000000000..c46dec6cc6c7f401aa85ecedf5c4af1fc6fb1fd4 GIT binary patch literal 2209 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/25.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/25.gif new file mode 100644 index 0000000000000000000000000000000000000000..0e26fe05cf2f7d988cc94f4c8a1e5bc3808816dd GIT binary patch literal 2775 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 Vv03%pwj|)NL7SpuI#97y{{Vsye4hXS literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/27.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/27.gif new file mode 100644 index 0000000000000000000000000000000000000000..8aae5c5168861340715ad4d1e09278cd61804a54 GIT binary patch literal 2080 zcmd6mc~Dd58pcl+c0`1-ge3%I8_^h$#SNRViS+;>fTFb;ER>>90jmPma!6QGugaPT zWf2JLfDOw95reV>0*DYmK-NZWxl~*rLJ1@}=i;<8&Yii={rA2z-#hOg-!tDc&+mH= zAMx6|FGLs61=d!9jZyH#4g&-R74zNl7sq8&{smXf6+?dB+pvfTl+Bb64i3W0b8s(+ zya3k)Ag_c8OP(vn{hLeU;6K6q^cZ9VL>58h4-gi`toMLb#Vn^iB*kn0<;hyVqppY? z+!#qj-h+r3oZ)>9OT@AnaIG}}nFQBHeaCA~%b$a@O~K7~!r`}5{cUADE~~Mzaec0G zqca+r1OIIIMWmpt&0qAe0C@|pKLn8_@a5yuru=YTX{t;B${&F*hw6|aP%%Vb8%vi@ zr7PZ!@p8{0vmm@QE$@fq6HwRPl!2zw=E88fAab@fc%tRYs@z!F1USo2m9~LZoXGV7 zQ1%2|?*~h=WAZa%_*Fl?>}Gd07cLG2G;y!>J-D;+@U%qe&o2qhyGGo2@--)s1kZyw z9In0ox?&`3jqj^?N0q<02aCY~KO@C>d=>k<^}bVF=EPQLQbu3^e4ilcF+y_=f9b4!;}EVqNYkOEfdqu77j%f7PduN0$f4#R#RmuhEbDC=cP=Eo~@8T|U&a&aTk)+{g($7Y;m zr<}7g)v`6wV_!JHuYzb4T))@GW4{zlTa zi$sFHzpFVb?nG4~Q+T%^FP#({LF2G4!K+l^-NJ@!*Ylx44F~j4k9)t;}=< zH4a@|2Pyw}eY#sifm>It!+I~sx#G7m7-Vm0DlCYQi}D<;O?xYKx- z${f+~^$ZMfr%*i|h$IYZ^Pc%SR_QZf71;Sf^I=T@RRma6Gx4q~?qGz_r4WD;QW(b0 zeAP~_hF;K357QOeD;g1NWnt+idXsZqU1?7>B@I9^RgWmge~Y_y(8)ll9G*` zjhB{=_m39y9&8mO0I(%PXjK&Y@(pdBt(rd>@5i4y@uU@_^vs!9Ot&wY+eY}j0U&k! z43zz3h%#WQU$39qOUQWpT`Tw6e;X(tnC1(VhBz((>r| zUW88m7#bG902-SIP&ES<$CyGg-SwgfyTg#Ikwn1`8#xB2wU=}x=yfPzKc#t`vZ=w& zVoTj2D2cLFvulf?SVV7AR?)(KQu9CG+5Q($^d?TNO>gC!KsB`q8STu~1#L}ei9lfZ zU}1Cb>gNo@cUsON!Mn*Nnkr%4!R?eHzAr|Z^zAcody@OgLX7uzD&7^`qSR38!Yks_ zXA;!QCaRy~5)NJMwCLGWeK0~LdpYM{*>h=ezh~@c-|G);t61q5)Y$aVc)^Dz|LAnr zx zT;%Wmc<+Q)-xLO@1r*h%uAUyT)91~RE=(09t%N-paH1(4*=3w57T3g#{Tw!ZES+o| z5*2MetvU>$B12t_a$SbVCzH=lwqE;^^vkK%OOwrosrT?sjmjfYnyMdJ{+Fd;s_O38 zxu8Ua0G}^Br0+AbuB&4V1aXyK9gsE3!cvWD>&{e;4E-23UEIl1$yU)aDLtI-Zgg9+ z5ORGVSvk{OC3rahu-|FYckfS0UjODr$+S`#T*@)f)2}Zla=*~n7VhIvNBdl0H{n?O zIEdCUVyC;i$nt30+54fD8e8}6J^0mFY)0`fSvb~;Z9f+UKUmUu%Qm+ud@NLqj-Exy}y3&iM7PB;w7d(rL5=h2UDsnumLz0h{(yp^h? uuzq#)5OlwhfW~Cm`>G!!V63{09Sul(HKaP_DV&srQG@@?=l`7Kfqw&(ji}`S literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/28.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/28.gif new file mode 100644 index 0000000000000000000000000000000000000000..c3aee8660db7c431c134fd83124335bd6b98d6f2 GIT binary patch literal 1310 zcmds$`A^el0LI^52sB&;4H8DI(@i62BhJCtmV(gp6)4v@oFYd!+~nAPV6u%%m<|>g zXBR+Pgix+=w}9O&*SLm2f#QHNt`Nn60!H}uc)!E_!vC-*d47A6Po5`v*j$#A^G!=& z3HD@wV?i!VcGFBj-O6X$IRQQa(e`4QGhP3W0N23nzZ%faGX5NncC|N&Ge&-^l2#^_ z<|Yh3sz4J7xEkIKH$=@Wz3LmRowu{Dn(Y%yioZbHe`}Nwt#xW=p|&4l4Lpr9r8F-= z-5!YgII8;VXbGZqh_ArX{5#r(YTaYl^zfd%rDSi)bN}&G-7>`ffZF-bB}KRQYkkn> zWRox!4aIbnM(MX^VX8-ZAL$i(kuO_f>d?m$UNqJFYa z-54gXh`@%g$tB-wp7^hhH%rAyO*Q#gEl*kzrD*vPZOv(FgLHGbdo#HkQ>~h@aA|oI zwpi2Gn2C=jZM`ybXHcMDAHaIyhRnC?7DKxLS4S%~%`v*3Zzbg!_!iugd(L)-pr=Lq zt^9ql7us1`n0(Ul@H_o{y;`1yBdBfjLStMs%0bWgNWwycTxP6l}B$d*d0nl8+Db&>&~J)hjR8J2- z-z%=(9v9CuNQ8r$bc{@~12SO$w({GX07D$a8QF50MLi*{w99!DmG?+T+-W1ROz&c* zQ>&d*&+b5;y`zgk(5ZbA&%o4x?9jZtY-Va{VcacDuPY{ys7ajyhWJ>`rsJktul>s3CHh-cM~((GI*0tqsE*AppqbF@$V;*36vpSGg#jJBm0>%30%&MF zz2a6DocQHCn-^~dh&zEq6`UVwaJ`F7eeI#F3vgg`a6S+?iVDLA>#W9=1yLLmCL_Yo zoVny*BY5ERi_*4=Cpr`JEayE22zcMC;o5zgW41TVoz9Ry5B=eCx|b-dDDdbA^=`Y752tk~>?sT)rHJwNTjOci}YbN#hBGKGJ+@CFr zzBwJ8SIi1N`q3RLVQnadO*wnKDs@{`?OtT>-a4K5^GRx+H8&QE_A!D#U80Z=0VF^H zCV+SVumW+D#Q1uVYZ^Jm?Dck9WG!|Rt%`mx{l z-=_!b7qXeTJ_HpJ|}lC_;r5b@7uAzuf+fO z{O01J75~1y{&hC?_noCb4kRAlz5L(%Yu{g7`tjw>qeA2&<_kQ1-|L^1de;;noo>cYo)TGxB&K;Q+ziC>)(P??NS34Y?-+cYZ zf{tL_4nC{-*>kCy3l@X#gt>KXU=Z*JT|}T)QBsjTRB`E^sFj$$rLLyN-TRdSQoLNM ztb%N1FevBtCcetGlYW7+Zrj?IUbaekTR-apTZPmwRk;%uB81HbaCnI0SG zZMR}@>Y9_We93W}>~|?=W)$4mV5@aOP l$%czf>#s0$X(|OQHnqO~k1=H86JOD$M+L7~Iy3|rtO3ocuulL0 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/3.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/3.gif new file mode 100644 index 0000000000000000000000000000000000000000..b68cfb128ca840c863b8000973a4f0f44f515aa7 GIT binary patch literal 1939 zcmdUu`&-lZ70181nwS77a)~XnB+`mSX{4?Tmf0j+3i1(xU_qBan6#j?9bmOoWlaL1 zAZ=AZfdVriNR&xZAMOd^8Vdv^s7R}T;i9M@Dq~GTlJB=c+h>o@{(_xf&kyhOI_JDT z3=3iTC$53kKt>Hz?oWMcG$MLXbc|~m1p|tIB2!@RMk?}eVCvXun+KMObC%o3;9mf; z4Ej~)EEB*o2F$&{d>tTjzm9{~{KIe` zfG5igx+=raMcoCSVW@6Ewmo|v!7zBf{Mg3+vhe94rLHEvv1ns^&6ayV3ata8#`Bpb z4M4_$?QR|X0N8GxF{xwWXLsQz!=`pnb}9`q0n4p~vVx;c70K2PfJ}g2IwLH7S!E~F z#v9|zSAnG$Sgrx}xuoUp)Sk;yy`~)b89Z)|9&P!H{Omz^(a>}*`SHyw@+eQsUBR^W zjCC5A2LSx^HlhP+`9F|npt3N{*tXkvGr}?gV1vB{6jeF!5>S*JSRMh!w&?MOI7MZa zxeqi|W*|cVwgB@WXuKd@z9v}wG0N1MIIhkaZ;OM6!L+VQaX#0q0k+4$Itv=hlGT+- z@J~QqoW87yAML4>m!uoplGHyG!_UD$d-dF4w52_2OtDYjEjP6vl2>Heo&am_L3pO6 zr#3`UTL3?eu+6G$^Pk?+9)ahT@C>j_?SU6!t&d`CkDFopFi!`plV$MFz_!qATNu{& zHTS4$dzvb&vmJAz+=fWs%EI)HuY3kBpRp~B4Ah@Ar~@W@0u~?K9yn{q7tJ{+u9f-0i<9NY=m-pUQ3*xg970|c^#5OUgcK1R6CKFm1^f9jF(^9`-HgSp zg*4En6}lBoAOZqq5{Sl0uX6S~t-}%dE$J!rNk(yAA;$GvDuvdW@4}2$KlB&&7Jh*Kip-+OVikPmp>+>~ zw`LcxoyeOjmOt;3@KqP^RN)4PH$q}|h@MERa2Wh%-u%(M-9v8i>H`_9)8X0^*tFwu zdny^DM3Ot!(9TI3rg;!=0~(Y#RDy4#PDj$v8oobXBdI|W1Pb9Q{t_UNVgHqpD(t_A7VqhZs zgzXYU(*M-vLF;1&I-ZgQFW*9~zlxWV@s6C*srz)iX9muj;O^v_!DGMJpVP|z&=3}K zgz)zL@u18+#&cA$B1`k$K?=QlRPKaJTf5}CBXPrPbeeA*ML1Qx^9}Z%DeT5rUn<$n zV=1QJt2)v%pp)5ekcCl;`~-{l>Eg(24Re3Ntf-;hWsv$XHNB-E(g;s~AF}3-*7*9`vzAm;ttJQI-n`ID%o}_(|M`p@`>ILn*2G&n#+#vtW;}v~1 zf5mYVd}3y{P5RJQK#0GApdlxSU_jR3Y+?8ck@G{kI7(8oHS7S5`7+Gq z)vqi4EsT?(a`pr*b20^56{l=DB)#q%^Mhl-iKW$5F8pmrTq(nxKo0k<^j4af6zjMd z$Di?wDlojHANJGcmt#T#=qv+U6yKiSICxm*uBQY!ZQa=>#ziFi`r80_7xDuyK$}8O9`ZaF8tTA1);$DXcL$c42dQbG?#=KXj{U1j-c1IS_ zT~pUxxAA#ezn1)>&AV|&!n$gvqeyu;Vjjb;29fXIAion#`e>Dd-H{#78Eg@1{YTO} z+DnDGlt`Fheg1Z=B7Xa-qVF5_W4y!5x!%O3PTobn%8|WJ*%@8KZ>42kDa>(L|MnmD z%5qEUu$Ts>_s4BB$)tDU|9IfbIJ+ZxtnL32-tf98mXgr$1no)+r#%_#cN!F~V z9xo+IymXr&1FG8JuSO@v(a}|er0(QUXSBzXOM0{?2mgAy$Ys-wT1V=Z_jsqosIS>u Wr0!0MojnQU)!o`ail++&djD6h1~1G2 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/30.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/30.gif new file mode 100644 index 0000000000000000000000000000000000000000..51054ede670670c20c2aba836ff2a68051753b8d GIT binary patch literal 2319 zcmd6me>l^N9>>4?X_y(}EOZY2aI}7$$&RL>DMY?%J8}}Lp)fffKRO+BPi>Ppr4tp| zkd0!bD3m0PaFESx*-CU*xt=c7QKy@Y?Ylcp=XuWa+4$b2UVsJwm{Wia z!ffdM^IMe}rDs$1W1%8Jo?#jsxOds02IqRR`|nm5{t3Q&QV)Fu^}o{RM;V6Sj5@cq z-Jt$8!!QRzvedDL*wTX3(sNm=2SS4m)IYuYep1;kJkWmQ;;r)dhMIHjqGMBvo4W2K z=C)yy%~nytM&4O4JCPlYC0$Ju&2t6*+_GUou{w_S9CcbfM zP7iP8@-$D6}-DmF9>&fjAgo`Cax*}BoQhG(F*0~8e{8^*!;Zcy6`>h6PcT`6-N z`#y?y%uB%czc36lpyp2W?8sT|0BCp%LT~5>4LGj?HTTkW&%xQYP|ZD1(*bG+LG7~| z&Ha$swgcKe5c(Hg)4qGQElfX6hu-a&f3$!8>0W8w&)WW|`7y9Liz2D!+!h_zbcM*e zMB?((`ZS`XDr4$)sFd$DCk;~#Pzw)5N~?TiwLYp}sH!{EhQci9C~>4Vs`Dow)pe@k zGF6xCI&djrsA!Y&GIgYdDyd9Rc6iG#dr2$23nQGBcYGDXppklNL5!b5xLMUnRf&z7 zQL1~?!o4I_w|DY(&m@1+$W3ZN9HTJW=TRLsKYE+~<+r`hW@EmvypW$>cGTIhIKW?E zoDJqX{C9gGHvE=7p-3=CVx)S9v6f$+{;kRYmsBfjF2m{Ju;) z(wbRkX+QNLl|hG_e-(1ft5(4AJ>%+^?}g20R$k9^C4FAEnSfsag!;b#p(4vnXOhGK zW_xmyQ>vPMAs*qKY6hs~P4Vv4gIAt-{t6G zjx2jISC1(npyYOeVh_*~X2b7C#USj-wqYcu(+U?07jp50SqDx0)|PV8(VuI3&5esY zZ@(=xj1cj&*YTCBPfgZ0O-QAcVZ}ldMkT)N3g>P8rijlHc5QFv*~BmsS*_{0N~>tT zrPmR-r|A30ADVY>K^_y{$lWR2dUs{;wtrL#kaqj{x{Pmp5!v>PJc30gq4UJ}Z*-zH2yH<&?pyGiBC?WNYvy#b|?(x zmF&3-9!4J}YLm7!c^twIlm#`#NxmIU^T_f`jF3hybFzp@A@Q54e5yjW^1H+)mB=&O zw@xMT$rWg<<_`T4ueo8j>88_hY8h!nX@+J8%N z>9paeQVTn@$LdC#A#tOszCIy`TH!;NH{)I~19pY)zkD|EaG_79JW7 zAOZYh8W{^|pqc#6Y_y5ojWG4335LLLa%`b3=?ccdNPJhC*f$sJizHFZCYp^Q)J65* zT(xE2aAnAfFjmAMs|W2yAxL=cr5k=6)io-ZJ6Vcj_I~z~A=D-5WoQ3aYa@*8FD@(R zlOsr;Nc{4J8o6r_xDQ0Ca=35rDlzhJ4YUnDD~b09%d?Vldt9?{AB`k=i2PFjt7Ddmdxu*-)U zDNBBiSmYsj^%XDh;ue$($*0P3FcE9{|2p`y0`=cdQqeE~ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/31.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/31.gif new file mode 100644 index 0000000000000000000000000000000000000000..51e9ab344d45e569b9c4a029d036cf6136f27b80 GIT binary patch literal 1197 zcmeIx?N3{E90l-88G@^9mCX&dWwwqf7&QZ?!P&%iP*&3~)lzg#m{+6=0u$%aJ)mc$ zcoFEOH*f%S+6uI>VC!$!x0TX=Nc_XFK6S(YBQ&au@g2Y`K(=0>7JICHE%+~>+)C^P zJOxY%IHcx1>vBoxxw;Ldy{N`E{RDObwsLbKoBU!_7K0 z4%!-pwx$?+08c^C4d_poUR!!+M7r7|HISd^u3Wfh6zf~^UDvbczL(7zD$%-l$*du3 zPj_EAr*F;=4ugOG8oE0koCUW@i#9xDy#lRGZ}!7nw=6J_P1Y$kev-`Ua%oo?sd-O# z?J}|ytUA97jOLQf71XraZ#|`JtE6YH8*g4TX!9D9l4z%)~)ERkp+p4pn(x(N}1iKK@Q2s>K` zRqPv{h9i74Uv-e1$$Emc*Y1aR55(>cw_FN&C$6e2L@2I}4AcD1Vabie_Jp>)-eF}q zGdZ-(D4$Xg`(lz}PGz(zx9=~1Dk4@`6t9#f)Uo4}d78nhME28h>E4BjaK?wJaL&sf zih4F{OhpY`U~BKMbvMP)n2`!iQ|G>hsP%z=`got{BK<;Y`ID-)`|@`HCL z2|`((dX~f0m*k~aAB~R7+T)Q6${B~6syqKSkE&y%i)1gbJ*o<4d@@&(%W*!wJExFf zr(_XzGf^e=GLN7&^5v5XUOb0Kv@oNNm+&SYg2BkMA4l)a;eVPE9w9v=FW7Jlwf1?( zGRuTm&U;{WXv>O0Y$I62BloRD|5}+3t0I`$8AYrdB}DFh9^$Hr)Qiz!X~(>5)rpjv s*hia6JKC*bjGftqM_E#nh?SVIPgo$=e$Gi;owau5KPiX_We_j@16l;u00000 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/32.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/32.gif new file mode 100644 index 0000000000000000000000000000000000000000..3d084cc8b2e32aba04aff07a4dfd7a49657e3b38 GIT binary patch literal 1674 zcmZA0X;f2Z0><$G2~ZV_EFB%KB^|X>Yuliww74J%vLw86*km~cMVnFZfC6HzLM0Fa zC`<(eMWB!XLO^9JOGwxfLP}_W02MGSCG5LMtt7ekzIQmbA7|_! zn-k0l8#n=z=i_~ho;zRSzXNon0z>C&$xT+GS zL|`)=u#JwXbD!c>vp)Y4e6s}CXW*PGR_p>*3~U*o{D|_HU|a`aBLnXNm>_dV%GFgf z@KsRHyNN3SFEbKXGmv^ZoCf#=K%N6^rD3$h4j%(hN=Ih^t^wF&G`ir8w%n`By@V}- zu{uB90D#Zwu!atofUf22(r@x{#nU`na?ZU-9D?+Z|Bg=r_pU&WW1oVG-FBORau<8 zzMw)T{g)66msn$mb^WvRPwIiEvsl)mw!vhfNQ+S7u+< zbOdPH&cj(Cd6qEsOCdHVTAv+kD*c}SFcKMktZDLHZ16(oTG2VsUUsAIabi;`YpNp) z`Sl!Jn}F++?e%$@=3rfatg_|DCLVM8xeytPmW#OBt_XMBn zH*B#%s{n7>+;qL^Xe-dXUY3gr+C`kAG8z52u6(Pe< zu4wc8RYE2lW6V}MG~N$FrJ>kBmQE6`X#{u+BQNplhVaay!a-4yrc)+iwQQX*PStc9 z*1Bv|1Zj(c(WgxK@-(b#w|&`sfpj12r4-{TsEO*untX?Fwgo1`AT*x~q14_)Y!k z`%!1pd~DJ$k?|D(m#W}$6(VqNd=Sy`@6hRN&vd49I@4Px=47T`!*QI9Z*_C@_Hv-Q zJ0AXwVxUJL5Xf30X)ggM9NOHQCov}wjBx_~&K{R4E;as|omkyQ?JxPth-5hV(?^N| zhfLk6ertLP6KRg;m@hzM=d8~3RfWedW zvvX~m!TdyUU#rhgN=Hih57Y$b8AfQF;TPA9v)p83c1 zAMBIdxkvX6NM-kTkXXYW;S&AClloKBft{yHVtrzZYDcUTIn{=RHRv!++7V}6;_<}LaQ}}cyQi~RW#5aoBnR7F)O>Pn?ri+r z@hgw2PZ%a-?c8N|NZdzH+qPRt_oFq?>|`cn+gtERCNbY+?^5!q6p#Hf*5@=Dmv8O9 z#nSEiQ?&y*Feaj7cNCY)wjhOg7;N|EA0Y3#OWE1SA(4px%}U%v-L}bE@|HE6TNY5d z<>0<~M=MVJ_M|jyKE&JvY;50dhjis5< z|D~I~P0u3WSjrHO-NrUHherhNJjso*P{%51uRYDmez}{wRv927Z6(sI!qriF#Z04Jhl>epS?lfXB&XaP?atd{#Wn#|vlLa_Rf7t2)M`1$I>|`pP1l+4w76|1a{N zrP-UMPe`tux24hhDI6N-*+tuV`#!4Vvc)l?cCL%H*I)mSpktlO9~j2HUz1LA3L2#b z8r^&+?*Jv)hJZgfVKH3f%OV^B|BQa6c+qb8sf$Y*S^U=a_+PensYTyj@T2|B=mInN vFj0?`a3SWj?RP;8&Ot}vai%2fZeYWi3!|nrUK7;~)`l_al*x1Ugk%2!!5EPK literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/33.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/33.gif new file mode 100644 index 0000000000000000000000000000000000000000..465a8676462299c9f5967818f914913f883b8c76 GIT binary patch literal 1259 zcmZ?wbhEHb6lM@+_&$N*=P94p_fOtCv*zCypTBQ>{(XA*|ANoIFVB8_e)Io_&+mIa z+ZI-y+Pmc637j-(CFo>A}5?;p-Q+{JZG+dt24->pnley!o{# zW#N><-LorZ^%wnnvg7gj4S%2So;|7R|2v<(8>c^-9kXIV$BKE)|KE83+vWLVgZJTW zbN=u3`gz3X-@9AuXJq}J5%T!x)ZdGJFYKH9`oX#X_k31NFZwaZ@B1FV$EO#qUq0#6 zvul4I0~KHTchK|iv!fSIZ2z+)@$R0sp9g&YeSY%ms?YCh)fW$~xPExS*4gPZI|>(0 zF8cTJ-tQwmOB%9&uJby)vi$Crh&{_2{%vyq|H=FRS)YGrGM`-C_5Xm^!Wj)Gch7&d zJ^0Cu!~ed$-ZnS=?^~ZkYg_(2-~aE%)N8Bb{=Pf=>E*3gmp6TXap~UykAJs4|Ghi+ z``-M2n>_xkE&6%J=l^M+e{V0I+`ZucW$#bN1Aoqs`g?oz?_smcEd$4=Ow48q@GS@F^Tfd~^&wihOCp`Xrc<}Gz z{V6@ge_#3hzT>l}-t7PX{|pQa5E9531yl(E#sA!Xt|7tBjsdPldIrplKtmOOvapIU zOkmIfSpdo=3>^O%6gg!)HY{*#GJYVU6mqbi$B3OZ?_f~VL3SB~CYwMZ)<#EB%Mz6+ zqlE{g`4ibXUkWrl=#Y2jE3gb`I4>)g`5|Pd;6hau<+6V^Qe7)pSvZs1?6MXtWn03d zc*dsaNyZ9(1BGQ_v0N`a#MqoyYK01yy;j!X_L&kW^(|0vTd@4jz$G1gcNUhuvol(t z;kkf2s@?9u0)-EYEkZ=TCN56wyTo24V)0?o7oINdu2~F~iOQ_qW-bzz3I+*Wvz&vj ztqC~N=)$A!BxRbkrFqL6VX>+w3pX6-;&%3tVobP_agpKS5!VX_3M-z9tDF!Q?DvcD zn{La@dM0j4!o(c6JA3m51p)*Pese21Ke=CHcEax_Mn*&^F*C3+@G`IhLrIxI(YA_Z z<${Batg^f%Pfjd22S}ehXU&p=hlkoG zNXXS_OnBhZ!pzMW^rgfI?~7@=+z=3z+epk DAVt}< literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/34.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/34.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7c2bb6194d5fff59630193309441c84dadc4e9b GIT binary patch literal 1975 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 UPvPhDUWYQ6=2|MFN(v(X2GOc0!2kdN literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/36.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/36.gif new file mode 100644 index 0000000000000000000000000000000000000000..779454291fbe8042adfce853445d7d5ad3a58447 GIT binary patch literal 3641 zcmeH}Yf#fy8pe~5kOU$IqzH0%DC`MuBk z%-QTgqu4W-z?Q&fTVXkG)oKXLH3D@TP|E@I224C@fTjnbHzPjA7^MuThd{rips^yS zSa3A$>;Xst)JmY51kj5{NDSsXfO-PV)dKZAP!9m*Q!v*8Zph8#&!I znZnG3xk}BGF6h-0)#x2)xOBccQc(+_sRz(hi>xWDuRIQV-aaP*s;PEW2M-d5$?o%1 zQ=JWWGL?71t=zcjkuGR@Kv6+26r5B|HLFJM7iPslGZT=M2Tk<|&qqM7hoM*fy@f$F zR}Mpxu)bT2*)m^Qt4RF_s9Ql{P6G7uabarst?Ve}=-v6sJ@Pk`69X;7on@-QJm}?s zvNocv@{;-`P>%t51yFPYbw3cKas)pgfTo`+`ZK1-dfKan(A#mwad!U{Is^>k5hkvUnzNj1pGgV&m4}MUM zbrj|&t0qf|vyKXR`xHYvyRPn0JqPp60Yd(PHgU*=b;SLJuN&X%zh%|JDtF2C>JUAntCBV@M2OI``oeLy(~ z=ITIS8AH)q+##SsQlJoXyK5YvcA#wIt474~ii1!qQ1%o;!?n;0FM0Wn*|P2Oicsa4 zpS+5x8V8DAkdk=t;&EbK|7`gWcCakA57bkBw+YQ!Qa7}r{IV5T^ ztQBUpQ0l^(z%Xi92G-PFl<5@X7yiYoA{p(x4I1^;JSi*Mz=*ud7@nQLb#gornL7rc@hS%t-Zw!XmhC{p;8Y%59q)pE(m7W^{nBOsMyE=&vYO~q2{ zBzhU-OTFCNH8dkUBB_s9(HYF z5$XGQpUiLXLFS%Dt3uZ?gHBO^hr( zO8t-M>+rR)C?9lNaUusR3|4qPGmoV8qlq@z&b;U@Wc;FyI(CB2Xv`=A1j9 zq&G&Uce-`icuH-eqy|kXIeJlYy^RpA|vS0Sgq$aIVR9E z#Vj<|ba~jhh5iYZERX46*E9^j2#5Krz%)(ZpgOP+7`u#R4l}8aU!-g6dT4U6CP<9& zS#50%uSTLW^eINRM4KSYX;jb%o_NEr+NuTX{eY0iG(u_11FZ>v75YC{v*B-|T7ZGm zz+ir)W)O%txfEsQLOVx_j&8==t(PZO*(75x+3SXh_++-8zOCoe-S z<694z8S12jdh_huuKA_CVf$vg9RD#T{Czur${P0Xjlkx+L-=fJQiGlWWk$66-3UzQ z#sbOg&sP;c6i19YZD_uj|Ie^lUz5xz|5}W`VArZ z5(Xu9G!6`-^EPi)8B%m|sN1x)5DTfX?^DAyxbYg?k?(i-9v8D@oxj-n=k!>^4T~aN z;vYG)4f`Fr9UML^PBKhMkm)}nvm|NyZ!GY^wlT;vJN-{h8pF9?`u?3HP29PaD`A`A zj-B%)hpf{j1v5naSnlR@%Yjo5b$z2(W|l?C9=Iayx}uWT#b?B&+>t1>CAvXdUDnOG1+z;u1}G%eF>MmL|pWIXvVJ z14H{wWS_J^)>JG_d(2m88Gum{&*78yI5 z1FFklvc`3K+6HqAUhvK6Aa(4jWNGY1;=mWMya;|!a9FJ;2+bl;li3jH=h68lM%Mxd3;@AwLFe z(|0rxzlw{{T?U>N2yVop)9s@uc+UOP`1F8UA)UxcT&WuuQD^lnEkUBAL;Ys@cVNL1 zGJ8FiAJQPiZN`%9^-3vlS8Z}GIBdH-W&jfA9FrSLI z=WXQQrq|89vuV+GTJ+8a%e~JmcGvCLdDg;wW+wNgIr5@*%-n|btEGhtoYw3EM{V+1 z4PMxN?)=w7@YJA)%ao$epRowuq5xVN`7tWL$laql_}boL_)S(|GH#3hid7rRg&Yul z5}}Vk5(1f61N8RGQgUjVF literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/37.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/37.gif new file mode 100644 index 0000000000000000000000000000000000000000..e21691762a0a23cf1bb629147eff325952d1ac6b GIT binary patch literal 2215 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 VmY&*j@l`#t^HV9uc%>9y{0CO;q}Bic literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/38.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/38.gif new file mode 100644 index 0000000000000000000000000000000000000000..76a9e13b28d83aca487a720d7129882da28a311c GIT binary patch literal 1540 zcmciBX;2e)7zXfVKn1m0pjt$&;ItJx)&V@QLKz^CY?6f{P_MxP7Aq=fiB?7E7|{X+ z$0AAvgL0R6a25kXfIvXQ5eOiMoB&VEsVTV_J=1Gm}7uG*o2K3Ix0x15*v6^e~_q>Z(m6x)5Rj z!EzZujgaF_)MN>zmbcajg^8zyzXpT3*ObT&yd4Bp%&7twJdcsZKcy9W=oHals&g*S z1%Ji_LjvsgGup=tT8;p;784(s>0kkM8>Ma)-r?nE#pv2$QpyB1Ofb$R``L5_2Nbc$ zQ3NY-C58`?g|0w$f|?AW8xd+uCVg;$mU8HJE|9@ss#n)`S&(q4UmQjBWrHF(KPTad z;J8kH*I=<4nt8EX9Ky z63{3I&*OjzuA=f@e$q*5yd1Q$RVCi^00*F@aEBJOm z-IIQc2WC~+yGgnq5#2jZsY>V$Hr|jxjw9OAZ(l2$v5FvStd4jAYo71J>U@bVn5vEw zrv~aW0y`glLlnD;GQw~PqLZ<}+W|6{CrUjICb{$gQW0qfnodYXDMV*D`6?W%atA0v zsRZC9f;Z2P7mz(g;MI>{dXVTV1HEiYU7~BbiB%%F48e05+IA13C53v^1JqoiPXs0l zh(QVU2B9VqFEc~&<=r$*L;pNWdWDCZk2k~F)6I6fwZ7hbYKa>dEr)c_wuR=xn?Qy% zG;6d0E=Y5Ze8zlg_QG)gr*_Mh^xUmM`DS~0v6wP3o9}!YZVnPg#W+9y>d85$6&8Hu zeXE~M{9%dz{+Kn_Wx<4hdUoaVQ`a0+KSg)ud2O?@@^q?k%2}(6FivhC@pW)9iNDhG zL2%^WOW&>BlX+AH#qzLedE+tH{n_?IZLu>MC#%ie4o>HqN3E`nKOO2Z)LXrD)7Fn5 zNZDr6&|t%8yqy*qnaN(W#elSc6xoL!n$&qkoU&`K)<0@oaOj~vY5=i1?}xCZ+x;Am ztPbwJHE!f(X@3T~7}OD+AdKMh(E1B4=gTa1-B3W^b7Svv+cn9hHZDmatMEOAe!90O z^~~Kv)=t!K8E%Mk`b_g>J}`l2&&wvwIJ3P^8SFKV|< zsqIw@zu@?mUHp}vo_g=WrcRF5h>QEWb!cXQtNzP5*3OMi@vEKn^cKvQ{Lkk4n;ic( z|9Z#LlzlcoKua9Y%}$TnZhq9ZF#>HG`paCIYc5*#r+L`C`G)^6M;mh*|80Kj4Eu%y z9(;Yy;6eO7JIJ9}#bEn5n%Xf9*UK&a;>}q>Q0XUb^6V41t8bVw>{hvD-u&<)^Q|U3 z5Zi>%Mdq?ABD1_E3)zS37n?t`$0gQAyN(4eGKZi{%GiC``>5$n=gg0_@<*d0fGFv^^L2cXg7c}LyA^FAc*oMKzjlD8Yr59uqp=| z1W?uoQGoRWd|dVA)Z1J{i~&W1tx{x1d;r8pAfFy5lzq#8|f&?j)Oms!cPGI_)@_KCA=6o_5SgX7jS7ilzo8G4t%I#w%SWk9E!h8 zt9o!9pXh=U?TUIpV4&`49{TQJNnQ#Z0{G|?IN2$9%0-KPvEgQXh@XEu8cMsy-U}*u z9JI1?x7#{qMhMbcQGLc@=8DKX)u%ktgA%X z5RXe+u%ttH;d!(%3J#R#a})64r;0`(;y;mBAC@;9=x-}UUwzHXh(PN>du@JCWgIpP zu=JyFpuVo`rr_xveAuNVCjoxyg;VdaK7b8B$3BGPQt{}^hy4v{%8noAUV15n0PW6| z&x{Yeslz9>!O3^nU=}_B;PgQMi)^J>rS>449UGIhqHi4)&j2b0W!dND&pl;Bo!I3g z1L6uiDj+K*thPAjac&&emnDCA6n=W&T@v7-PnK5&Dw8J-bEJ`Vu{$GVd=?+DhadA|`g0-8x20gSkpC z*nGV54u|Lkugmun5Be}a!@DPPcuw;=y|D3tp3{KU>r4~CPV=P{d?dXjf7 zRMzB8v;k%7I`n-t+IF+9;5+yhU?bs>e;iJFVIO^QX;$aGL-=?IoCR%rc z+A+cB^e!d4w5M2v`JZ+)=676Nw&p~UnH{Ok*i2*4A;N-!Al7>jM}hAMH`#eVazS0Z z()Eswg-ox=uWd=yN~`i18D|JwvvM#UPu|8&@j0GnJQ#fa z<$Zs(i=S`15vlRgGoihmGBdP@&9-u%sU8WXC*>M!J0M{*In>+h81scE5%+lr!YV>S zQwl^(i|{f;PA=S)uz9!JfC;;#$T@7+S0^+F1ItFuc$3Uf8imm6-!aJ)&KyO90|MsUGK6utywTv;CsQ zVjV+T5}jFnB}@!j%wr3eDk4Vm#U(cOuG{Z+FV}g)CR&3BFHoTG zOs`0_Ss3){UeK)i-i_Y%lq(Be|0FRXaTcvTUg5U>kyVqL=}H7)JW%Ivzw7dDd-x zX=d+rr1T$PEBDtZ7jOI$Z2a#jP8+mMtA2Mg)uE%E5s7FTkjIVbl1r4J?tR|iQZ1)t zDTQiD)6Lb#aOUY&TG&$3QUT$ZIgF+ zQYax3HA{-+-NS1dSjO$~6bkt>;V5?hJ`AeJ8ag(n8C)LI&1Hle7`dIjI*#(sR9J9s zM`?|}>C%)9VskZf_l!8rd1mJ4er)EEF3)F_8o0(iAUCJC-#C6%N7rSYkM+J#SKY)l zxnDIb`g!z56(ilt@ML5FCE4U$Ba+#; zYt(Ab6DDjLLi|s?UbX0NI1~i^nj8ZyTE%q%UnWOz^y8pC)HW3kGY7(#xlr4dL^JfsE!q3eM446pH1in5FwL|46C{UzWJG$Co9dE@Ajo P2bd1|B*v0d0z3Tz%TE6! literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/4.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/4.gif new file mode 100644 index 0000000000000000000000000000000000000000..99851b3f5e114cc765100fe184da1dd60ba722a5 GIT binary patch literal 2671 zcmeH|ZBUa}8iwCQ5)wcRBtl9NAqEQwC{(Df6cQBVXsP-Pnb92IP3UPCmVJ5P#+6Fc2o_$l&}Tq@9iWq-p6iOv19TjS1$o+m zi21$*!MO~5FVMEdh$`}oQh@5fd`DtS#h!)xbqYRPQUAW-8kp;hkcj?@PJvNHmGOyG zTwQ=n-Jcm#8RU6}_DEC#j6HA}_egW~F=uPmfHyRl%F%g4XiGJL2q=_8v=3?EU*)V!DV|m{2bi2I*bj7=-C@-U zPILCfmp;Gl>FGx!+;jdo*47NCDILG_Iq3}HT~*31qMT8d%X~T;2t$z2Z+pk{=a*f+ zAm?sAqMxY=w}t(^ioLUXPWG0Yk&nC>x@1@l!m8JBks2lE%r7rbTvW~^Y@k^ zX{Cv37_ziGPfDdt6;{|BE?~LXB|2hE@vA1%n2~1!&pNL*aqUtvnWawge81x)oEUw_ z(~quZVle-LhlOyEC4^su=MUv9cr#dh1_y6pN9f$3>CCslc^9Ro{}E1VcgK=S56~cA zYwBDEy&+5vL9~U%5t+0+>5kb6=kZv^zl#i6j9df?GjiJr4zrKLd7gRFBVGqx((if} zntFH}Wx*U-;uj`6rd#V`>D%1wX2U39$%2(`&U9SAiM39v-r6uO;+16QXOI0DXBxeMSA+0?{giN&&?1RYWZnr;>EMcjl4Cv zF>!c^bc0`rUv6!+v%ii<=e)x4bNp{y$|IOh#<$jTio6{*c?@TT3Od1+wMN+MPrPqQ z!b5KruPF>(#7ZMH($_M6DV5;YQdxMky_Ra|l~ls0=GRiiTrgvNNvZ8P`k~Jc`NUK2 zrqS6i9*eBGZW&oW6&@eMuTOL()ut-fMY@p8%`P~)hjuT+=A6Dwot57dgqqvXTj6o6 zOR$;ak6qLFn*^V?5-Z#q^e_%%5s0qJq}{MIr3u?EK7LcG;bj?mH=hakQ!@2da_&@k zDA8s=-gr;_=a@{4{l++NC*?Nv$}Jv~BtgnPoBEIJsRu=ua6wG7ps$XSgoLf8xLpH;a- zvd1c@nr!P}bv(|R%s0>Hr1#Da5$Rn;J|7;M^HzSGO!`CnL08pYg;CdK2AOc(tR+}RW}dB>Qo!E$G{*KCCvY8J zdus}Ylh*j)-=E10N%hzvvLqz)JH6K1e>zpf8c^6`P1@sEH8fnl^w8@a?(=lk(8hf# zY@#339lm|V+y3?iqEFg*5N7QL;Z>}L$F+7Jw$QQPZvI6jk2>=^$ToSFSuK2*5P_V# rVl`XFt#Rxnd9W-I4oS9DNeYGZrr*B{_&*7V`(3~{|AhZmz%Bm(8!%H% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/40.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/40.gif new file mode 100644 index 0000000000000000000000000000000000000000..40f2ac17b0187ceaf129b7900a641c9bac55ae12 GIT binary patch literal 1324 zcmYMzX-t!60KoBADFPZ297AE#Mey3@;)rvKQv(zzr92=a3yydI!W4(77@dlfbD|T2 zawuAk7H}YlML=+Ek)u?(X=OkIEwmgh6ev(s`d-g7zU|xp^Dp^(`>6% zq{x95UTO9@qz1M8YeXxHR&k&LP<_6z2jFj6s+yzZ3r~6$plN`Hednq@0_`p7Xde_E z{Ukkh>80oNNE=?|0b7A-aRwSSaIPJG(6-kXeZ$pGF7#3c!| zp{ta4TTpll8b>9f5>sOsIb2|p9%~a7z{PQW-I3;s6nd%`&h;<#`co5t96E0LFheQ< zoFBs5fq@CK?vez=G2`;S@K}Ghfq8rcrmD&f&K5s!EuKPJtVwbqecfYLR<@z<2DldL~XwgB0iJiI-FHpnHlxlqG}3nTE; zG&D{?qk3E+fpbI9&<$IoO!WYYScJj{wR~1o};gsIx&-c zn?y)cslh6$C7N#VLJchVE|}H>GzDlqm+Z-dyzoMG;OA?&;5UY^7j!z>Yo ztTwPKdG1NqZ0tBqMd@1(TA0TelM5vU`~S*dybO0rZsK^i91AS+F>~+^IUwhUCaRx! zIlF|8^4u-%?aIr#@nAD=!gccwmuI1wQTMryS^m+AP%DqL?dXE%TILpJibHz$?)GNg zy*`G$rTJBP6G({^y|5?bE3F?|N`Lh_Q=NeEoUW>+kF!>T!f)Le6JJWU4kd1-3BNl! zznt~!cIp-XXavTxFf;a++8_BpBzzThAjP=XU*!^S+Z<&${XF=^`47UYZdg){aHTmV z56LrRmmhL6S?P2Fw~CN1%9<@Z?`zM#SmstyzS+jyUJoiLX%*M}e?_{P#tQpyNpwc<1afh9G$nM*E zW$B+N;^3*i_JX$frq06>X@}avM)6ujmc-;X#P@BRWL%K3%&yo{c3<HQ)~&J# dy*#ik$1G-cK50hxeO7SOChPv6>}|09{{h(>9Yz2E literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/41.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/41.gif new file mode 100644 index 0000000000000000000000000000000000000000..5af0bb1f47a1bad6dc00b314c1567c2a4f573305 GIT binary patch literal 1702 zcmZ?wbhEHb6krfwc$UrZ=g-gIN9}$eb4;6g=I5i%>l@NOJiB$ESN+4$;NQm_ejT*> z{p0J6#mSJ6(Srvib604 z{dL&>@0-PcPC4IM>-^`_t>*`#fB*dY;rXp!r_=si3cJ6?-#BgN&i?S{mp9(HbaZd0 z^|L)*U$14n+F#OIIg#cFVINM%8)eo$(0erZv1Dp0vH$f^P>=c3fa zlKi5O{QMkPCP(UIa|kjQ{`r{qy_R&mZ5vef{$J)5j0*-@SeF`qj%9&!0Vg^7zri z2lwyYy>t84%^TORUA=Po(!~qs&z(JU`qar2$B!L7a`@1}1N-;w-Lrew&K=vgZQZhY z)5ZeMTG_VdAT{+S(zE>X{jm6Nr?&Zaj`McQIQehVWAmo_rKzE=rmCW>q^KY-Co3Z@ zB`F~;CMqH&FX#K^#)_>%=lW;5u3N*7RR&A|S$A-hRmSy3ZY zLs413sW;nRMUTZM+=fL@#lFu>O3RX8G*y(}QcKFLNkrO5Ff-FM+H{?ukF-d(q=JDr zuZ}~cgAT8^fr4bVjK75;gBwRMhZ}>Tg}+R;ow2Ph1G8+HEHi_yt+8FUk_#iF04LLX zPJ!1hO4(vUTu~By)-l$65@$3fBqaJaa+_S3VEI_9S6m}8BSvEbTW61u?=h9Y!-glP ztEr|aL<%2iX_rn~B;!%+z%@-;&WA-%#f6<&-C3<^$IS)w8w4AubCqm`xr literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/42.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/42.gif new file mode 100644 index 0000000000000000000000000000000000000000..e5dfb8dc7c6f4eaeb5a27b9db2c4ab3ed714d615 GIT binary patch literal 1704 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 XY$01Rf|hx5i?Yqjx~rujz+epk+w_~R literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/45.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/45.gif new file mode 100644 index 0000000000000000000000000000000000000000..9efbf475232d6af4e09c4baabf4f904d43c088e3 GIT binary patch literal 2114 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 Qq2ge|%B!oJfPS|I0KmMVBme*a literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/47.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/47.gif new file mode 100644 index 0000000000000000000000000000000000000000..8fc0b356378cc05620769128a725bce5347ea9fe GIT binary patch literal 1700 zcma)6dt6gh93KYAOC&W*)4WWqG`8J49%F+EvN1rNAfjl#7~35T*zR7)AS)ZDK#7mE zTxG%#P(jBdQ3RQT4OE0gROAs8Fqlv>U%8Ep?ntmdqEF|KbI&>V`~CiYzjMClgoZQx z$SgOE8)iU+F&d3MZPnG8*ryt%dGv)@9q7eX^p}Now>J(AKj`aizunVse$sCo=v1ih zAIr-+e(Gr5(U^)enWN@s=DKk6<*k3 zoXb92xKm#lX;g2mxG`8?#MPHXT*wTu=+<}Ny?R~$$kN0e9Ced{<6!48Wp>s67<0qsno@aNIbyC2y4TZT(XDN5sq8AGUdr-6T&~L~(+{?lJyb{N zo63${>{9CbR3-A$HFav;1#N?>Z=hFmt4C3&l&jh`w|jDn4k`-sh7H|Sw}y&kK9iJAnNp{^Gy|%5@P#blk zVDFXlnQ6t{8LIZ&{C&fQuH*SRrbf1 z0V0#hRt+K%hazy2G=Y>Q!wDpdClu(gge~R?r94CcSQS}uNQ#t-MKk@o1io-mRv^KT zmxE^`e1eQ6BtUr3TG9lN$^369pFfF~NTc9a`Tnc0Bsxt96QW=Vk|JiqD15Osl#oIb z!z?Kxjz*B=iCv6LK%|Hy0TBYUbv{50PryM^CF5u&lM*hFNLd0l98RZVQ9ho><4_nN zkp%fd5JdB(Lr@6lM+be$G|1PFPK3yQ5IDi5BkUADERarcIj^|HDY;f7@P%k(IxObx zfH@2?!Ux6+rtqfB1!PRA_maz*Iu~$CE&)x3U_I7<9P`8y>K*HF(zNJg()O?b^|}}} zwawU{Fa8*{m`%@rfA;jr<44Akhrj(gJoLaYIPlB;{=VLO`ktS=yE;4Ww%@sZtLJr>(EkTvpd!s;RzMb>V#FxgRUa%Su&e&y*COK6SFFu;4_#GB5Y| z568a$?pwvtZ@xZq_^U$)5A4s`_vIJaS($tHe7-wF{@JciKlym)N9k#@)Ey~OiC82= z1pMTrL|#HX7v`|zSh3r;ZQZi@!%Z7wHmr|c7qvDrVhwZks+Hkkp^OkZEqFyx;Bsn! zKZWc^^7ZldBBB=xkMsOs+0ysldv}S)Vyru`=$(ZN-kv}2tvBbsF=zIy*WG5i&Tw&d za&(w(Z)f}3G#d=Y-E52YB8;c?EwR4VnCXMNL~`3@u0aVwuFGuY`$V2}W{5|WM+lGZ znF9vK0b#4yYr=p{fuP(abmgM8tZ+_jeA1$=p)R5TXQal76hm^VL7W3ba~(1E7@Yfh zcic6M<6P0|rNRye?uIQ69m1uNqQqG?6q|*NZH$G3HnWmNOWbBI@Q#=d&)@F7V5Zwj zt;RjLX^%^=eeyiOqu$;VE7UqZRtC8``Nu_Om1P9yOe4s(3b(vayE)TsPX_E#2Jd&6 zZQJZ8(lj`^2*8q3QLok|bVi~Hgp|z=vzI4&3q7vr+~&PgC_4aY?b?br+SyIR`2PiB C_O?p^ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/48.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/48.gif new file mode 100644 index 0000000000000000000000000000000000000000..7467a5a1204da8acc4c325c759fda265eb6ff8c1 GIT binary patch literal 1710 zcmZ?wbhEHb6krfwc$UZT=g-ea8?FDGa{m4E>-TdNSC%;M=y3gcEc(S}^KU2ozFds^ zb=dyd{KSv{Qu3&M;pxlznb~?$JhNc({8SHes`|q!~WQ`nP<+-x7lcHe0HYA ztDUYp`@>&tF#EaJ;@3f|`)mBaUC+C{%=YKgji=JmeqM?BebnyIjPR?AObs((6@_TkyBjZMzK&gHy4nfm+3*ZZe8et3TC z;Tn^-XU-f9HU4li1X z8<&p$JmB#;Ie4kD@y|z{9}YNwIh^+Qg3tfg3x6GUI5W@s`U188pVs|ujYTZ$8>!a->P!K9j)^J zo=@N1q4XaN7)S?-|G6W40~A~mOA>*!jeSKyVsdtBi9%9pdS;%j()-=}l@u~lY?Z=I zeGPmIoKrJ0J*tXQgRA^PlB=?lEmM^2?G$V(tSWK~a#KqZ6)JLb@`|l0Y?TsI@{>}n zfNYSkzLEl1NlCV?k|Rh$0c59heo?A|sh)vuvVoa_f|;S7p|Od%xw(#lk%6IszJZax zp^>hkxs|bzm4Sf*6et00D@sYT3UYCS+6Cm|Cs(pQ}JoAc667!N% zJzZ>-fco_^GgGYG%v@bvES;PToy}Yf4P6Z!jZH0_%nXfP+?-t9TrACDdR_99OLJ56 zN?>|Z5PF?)>IEf)+ybD@E~!PCWvMA{Mftf3U=Lem;&zKAPV=C8Q*gV*5vN{#pkwqw z(TWt!Fd<;t0Wsl;7RZ4o`_w#OS}y`7YR3Qn{{H#>>*tT}-@bnN{ORL|_wU}mdHw3; zi|5atK6(7;;e-44?%uh5>*kH?*REcZ;0$^0LyB;-bQW{Jh+p?5xa;^t9BJ|cQ;oTXD3GodplbjYb#3&b2C#DV9P?1~91%MgXOBD{t{^=I!n_L!|da97HoQOv|m?VNTi@RrJ3C%aaTz4VzpjL ze(Am)nF||T*^Rt!b;K-M%FNBHdxytDv8hwS!05(_4~JSiJA|1PUK%7kVc?OD&pBX` saHOHnKQE)egXz#A32uc+1q&KQg!*KJv!<*xRAld4m2lXJi-o}&00FC=?EnA( literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/49.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/49.gif new file mode 100644 index 0000000000000000000000000000000000000000..3baf57d92118a9d295f87019c97b9319938fcb21 GIT binary patch literal 1681 zcmZ?wbhEHb6krfwcoxI(=g-f7?^eCv?{Ij!-_rvz?+$qU`11beUfZ90?B5@B{e3#> z>LQchC%hkTbN+SA_4jedk0%qZ?wt7l<+OKu9e$mN*wtqFe23HaCi5?Q9lzh7|Nr@f zKUbrFpU?fU)#c~S^e=apJl^5<`?%-XDQ5p(ZvXyx!{hZXAI`??of^Nj)9=Tjpbtkp zf1L{bbv*9fZtK54-=xhv^M1eM&#&))9`gGCYSORs85`@&E^eFndav{6bMa3P1phu2 zdvAls&jVh6&bt4-Q-6Mr@vo=tKi^;dbiO^RkDt?_xF;1KL`&s?(bMcpFng2SI z^yhNH@hPUio=p08C-KjDzrQz<-|aU2eZuGW>FD35-2Z>x`tM==uhVJ2&u8uFu=@XU z#_kTK|Ns9p&ls47YguJQ{>uF6ifOi{A8Q?RM9s>m(KO)W`OsL0L9E4HezRZ2|BPfE1{ zvO&W7N(x{lCE2!0jvxsIke$x?MX3s=dIq}524)5dW`=r(#wOnqF1_laHpait7C?(A*$i)q67m#PGlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E z!^lV%s6w~6GOr}DLN~8i8D@e@YH@N=W?$S+WE4mMQ?&&*57FE0kG_Vu;$%quQQ%u7!7 zbg@+e>etK6OtErvakelvGjKC>HghpFbTzOrHZ^rJu&^*Pce4QU%wT$5@{>z*Q}aq- zdQ;$f4GnPW1to;s0-((>*tT}-@bnN{ORL|_wU}mdHw3; zi|5atK6(7;;e-44?%uh5>*kH?*REcZ;0$^0LyB;-bQW{Jh+p?5xa;^t9BJ|cQ;oTXD3GodplbjYb#3&b2C#DV+bm#y8 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/5.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/5.gif new file mode 100644 index 0000000000000000000000000000000000000000..50e09671f09a7124b31f042236a5e8d64ad0e1d0 GIT binary patch literal 1407 zcmeIx|8Em@7zglcySiItUDq`_V3>9r%LW5`?JVs;vz1Zj;bznE!`6^U(}tDQEFHJu zNEgzMYvb5lAYNd=A*=BMLe5Od%`e%9tXVu~vYbsY7c}OW)a0gMIze+$6F%OQ-}Ddg z2cMtcPx5|V$@Ah%KDQ@Sg;XKRFe0)+DB-Y(Lj|WNiK3!FfJ2Bw9_N^Z62@3629+XI zWT;3`@CK?;k!OmM0E;4oPzD&4@RDIv3fiE=vdkn$*aW}`fQACe;Y|t%unY-7K#ht5 z2Za~}VMX1Qc_;)~hN2TqfC(36K^B3?vl5L-Y*>*+$P)}rDm-2kIhG=z=qYjmno0mV z3^+;_IF^nxU`fcwf=$&NL&_4bfUwMBP)zVFDG4m(NeKiw zI?U1}6oWiVKq)8-j8c?DK=T}}OokyKc)%zkE(AOZ8JNF%f(_tvm-`_gX&ht20fr=L zieQNtASgucp*5YeGwowLTBB&Ccl>N~seWfRo7!8^+@9&R9VJt_9or)A zczz~FR{C(nYE4-y%!8}>@mmWya@u*PIocg}a`##n+r{f+y`AFct!ef0YXVrG6i2XvSUs*0&@hv2EI+OgXeX#`9q4hm;qsWcJp3YOF#^*nIkZf=` z3tgrHrfscgER0yImP<97{HJT0P2KwQc2_><_h~Za#4+)>gULj8*(2Nhrp&}x#pc=# z4Wu`jrk)-6wx#c3d+K%lVT0q1)7CC&e)9{5;_o-y&0+mBn7?hEPG9#gbhqC*nK9X@ z=ogOJ?84TTmiTIF>yl}E$CN$Z+dpC0Xsl_8+C$_SGlF(Tmri!j=LR>qrxB-cQNR7( z{F=Em`3f=^eN=Lx;M?*#u%!;!qp1`%h9F+4}$h literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/50.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/50.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9e49d6446309807fd90e21c3f40426875c4b123 GIT binary patch literal 1695 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 Vem&pr$cXXGsc}^W`9)EH&tIH8FKYk* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/52.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/52.gif new file mode 100644 index 0000000000000000000000000000000000000000..72e7ecdfc463e54f6074c486f00fccbb23c683c9 GIT binary patch literal 1711 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 J*vPCjB5Y@ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/54.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/54.gif new file mode 100644 index 0000000000000000000000000000000000000000..3b0b8d3d2abe149bab5a334e8574a201833c41b0 GIT binary patch literal 1703 zcmZ?wbhEHb6krfwc$UrZ=g-ea8?7I%HTiYW>cg{JzkhuF{pr@Pb2;}rq9fb|NZ{@?p(>w{r3OvW$x?`|8yqp?**TqS7Lr0wElI- z?#5#0p9efXo(TH)=j+e?*4H9n^eQ-2+@d4750vSRK-eX73>JN$pM`2VMM|DI3Z)2V!9g3^!U z$?tYrt*$WL(kOALPwn_*)lK!1@AjB3F5q~)+Tho@yzR}>>#9YctTsF|&w6)<(tj{u zpa3ZT=Z^3VP;f~sNd(e1_7w$*$=RtT3Q4KynR&KK?|1K4QpilPRSGxtHSjHPPR+>l zs47YguJQ{>uF6ifOi{A8Q?RM9s>m(KO)W`OsL0L9E4HezRZ2|BPfE1{vO&W7N(x{l zCE2!0jvxsIke$x?MX3s=dIq}524)5dW`=r(#wOnqF z1_laHpait7C?(A*$i)q67m#PGlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E!^lV%s6w~6 zGOr}DLN~8i8D@e@YH@N=W?$S+WE4mMQ?&&*57FE0kG_Vu;$%quQQ%u7!7bg@+e>etK6 zOtCVubagXuF)%iCHgh#JbTzOruyA&Dbuw~xax}JZb#sB~b;(aI%}vcKf$2>_=rzHq z7nBfk3xGDeq!wkCrKY$Q<>xAZJ#3YU+bxDT&4cPq!R;0!oO<VgsyL#pFrHdENpF4Zz^r@34jvqUEVojbN~+qz}* zri~lcuUorj^{SOCmM>enWbvYf3+B(8J7@N+nKPzOn>uCkq=^&y`+9r2yE;4C+ge+i zn;IMH>uPJNt12tX%Sua%iwXi?qaq{1!$L!Xg8~Em z{d|4Ay*xeK-CSLO(dl4sXKQ0^Wocn?vcsXsA`TE$Lb@_#TLVbk!b)DIo3^g^xM2&dDd5lEGG&BvfmBdX1 z95ekh{4*T|OvIJ4J$%ho7+fOcII}C5Ftpyfch!oDKviczCwU>dlc+C_d2HEh{_4LMh-es~}&Lg+OIs bbAz%YtH6{G2aY;(vars}x~rujz+epkur-!( literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/55.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/55.gif new file mode 100644 index 0000000000000000000000000000000000000000..28679aae53f6f3075d50b21d1e8a5f3db1d86c46 GIT binary patch literal 1698 zcmZ?wbhEHb6krfwc$UI&>(gBz`1|+og$oyU@7{g;_HCtA#(|d;1*a%|{qc3-n^n%c z{E}}Low#!GXsf`Hp-2bynJhA5F2_<861qx9`;~(?#~4XCf-@x2EkcD0$p8 z^VQFdw0?)yU(R~iLeO|aVQ z<C*7I9_ zm*N7iCQf=aH{n{o_sRgr-9G-;;$zNa6`U-TTdc1*-*DsQ&86FG7r$9!y2ma4XpZ1a zrK(F+cKiHPR-4ZIuwvh#eWn$r|NsAIpf*ta&mG|#px}~Nk_e=2>?;Zqle1Gx6p~WY zGxKbf-tXS8q>!0ns}yePYv5bpoSKp8QB{;0T;&&%T$P<{nWAKGr(jcIRgqhen_7~n zP?4LHS8P>btCX0MpOk6^WP^nDl@!2AO0sR096=HaAUmD&i&7O#^$c{A4a^J_%nbDm zjZMtW&2GK4GRy>*)Z*l#%z~24{5%DaiHS-1 zr6smXK$k+ikXryZHm_I@>>a)2{9OHt!~%UoJp+)JUEg{v+u2}(t{7puX= zA(aKG`a!A1`K3k4sX*n*AgcnUy@&(kzb(T9Bir(o|%`D zUtSDW?dxmhnO9trn3tUD>0+w{)UTJBnPO#ZX6|NgX>MfbZ02fc=xShT=4$NhXy9UL zY-(ZRY-|M6>yn>bnwy$e0@Is<&})oSFDN18765H_NiE7OOHFYr%Fk5*d)O)yw_6Nw zng`XJg4->IIQ8lS9itD5R-|Z#2?5g%hzU=$Kn^_Fr{)3EdJ!;DGyebg_s{QNKYx7x z_Vvr>Pai+LfA{vy>sK#dJb(7|$>T>4AKbrp_s;EGH*Z|OcJ<2TOBXMkKX>-b=~E|9 z96xsS$l*f=5A5H!chBx!J9li~wsp(qO&d3?U$=J6>QyUOEMK;C$>K!|7tEhGch2lt zGiOYnHg(G6NfRgZ_x1L4cXf8Ox3#u3H#IiY*VWckS5;P&mz96TeLf@4rrs0=VO>f8M1M(LVTL{i%K$MMt|%@U zu>i|iDQd2Y(gqxQF?t*Z(u%HXDb6CsW?}pxu_63nX2v4UDN>GpvNi%d@jL=HvVM+I zDK6Gp^1g=b4-9?fwX9uI#DhIdoUGX1TRE9{1dFFANSG=!vi$j{Y--S;@L18QONfa} zB_=}2m4!cL!<-cbtw$TA#o0IP2ztmOW@It#&jck!Z)QW@O&$|IC3EsQ`ZTy$ZaTmr vq0HUq!g%P&L?LUNW3s8=P1=4OLv$cr4hmD%7!&fx#L83ff^h literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/56.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/56.gif new file mode 100644 index 0000000000000000000000000000000000000000..9d46e2964525f6202b5c9cb9960cd04bb8876835 GIT binary patch literal 1703 zcmb_cX+RT47!9I=h!qqqT90MHiU_%oTqGp0Ngzr%LNwwXl3j_AY)lr3w6==XiuLNL zv8}CQt;M6#(*w*U;DOd#iU(FIRHPEAShESF8!FfzrN25qW@l#Kd*AoXyqQ#qn8j9x zkU~f;2+3WON6UbCn#wQ0R7bdE3mc zdu1+b+T+tQrz7>rrA4l4R>w)6#f%)?AaY$@&}LOsmO_ZR{^mYj_r>%lcPk%Mr?wpv z;WgR!PZd0EF!p%5TCY@k&O)yHl|AmR4hwYN%sRGJ@$_^C?%+2a%*1V+hH}XJaJRFi z@x~DZcZl7!0{647$LBRJOJa3dB3?7wS(DRZL2ey_+%xyvqTw@5sljox;1JYvSrA+D1Gr)6P_E!R^& z%iCV=?L7RbD&c@Bp{I2_enI!FPK7&C@j3%Af)a z8krV9gUMvZ0(2^kN}rPAL3MynQJIGpVLXt?^zRb1 z`hHoRk=$DjS%qpTCZ(Q2BU61P^#P^Q|AuO{{b(a5gJ0zPufj(8N)D@AyPo{f`PkX<==b)AZ4Z8HZMpwz^Sxj0Hr=^>>t^H64L7b| zyL#pFrHemZIA4G6?3vSbwKb<4cAM35vbyTT@nc7S{NelWzWt{1$k&Gt9XwF+)&4K{ zeX+NE&+gAZ+x6)uAMZ5p*#6OnAH4tGyW6&I*}UnUjb$6&Ucc_GwWVuTzxl?h*Iz4H zX)0b(gc%LX^{7r;Sg=f!zZ8MhsyyYA#fug$m_ILfu42w?d5$bQD>FlyK5M2VEmbTM zLMh1teiDzH$YHaXjD#8SbmBsh<6@`BOpBiS>XfKRFanr7Y2t)e#*YhsdF+_5(W62` zM!qy6czDpTz<{Ac2Kx{4BatFpgNYs?#rhr_-)l_@Xj_exPKowUnV;exJ*9Lrk}Vh& zGHl+kkWqr{Edg0kvXS&$`bb$+RzT^r@o5Sej$9adSdlh<8ZsG}nIR5lsae6|jG4e> zgcmkxv|kQa#m(^>Jt>TbB#oOo)^9@0+?WY|W2cTwLL`AC5}z@sgTa3oC_&QWsDq_J z=R>bBi?VHvPnFzLr z->azKHZhbFs|WUz)`t(>Kf`%>^~N>f;X$mOwv@Wz(-$ACx@gN=ADPT7UC>~K9qRz* Nu4T7lqC-fDe*yWunnC~o literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/57.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/57.gif new file mode 100644 index 0000000000000000000000000000000000000000..94540e86b892fa98d122226563bb5a13d087b617 GIT binary patch literal 1703 zcmZ?wbhEHb6krfwc$UTR`>5TYKR@E@{(a2x_orL`-^~1d%;D!D&%bXL|32#Q z>OlCfLpHyThCVwO`TRiihyAf>Gtc}y7X9%=(9cJm9}YPGf4%U-(coVPtv(!f|GD4( z{n7CIr#F6iu<_@WnA^*2-|u(c*yQ}}M)AKtU!NYy{&vFeWGJUnv^>t9t zr!#4PKHd6tI_>eEke&VE`)8(IU!eBuWV~_O%(F8s-t70hvc&n-=+{!?QhJ?+(QNIph8Be(m-axmD$Y zf3GI2DCK{+DPVmS-;d+TH|*_y=jX4l;{SEnVReP+|4-|7w93ERWBUKi;(yPl|NsA= zfij@@pF6@gK*1%kBoRp4*jE%JCTFLXC?ut(XXe=|z2CiGNg*@ERw>-n*TA>HIW;5G zqpB!1xXLdixhgx^GDXSWPQj+asv@@_H?<^Dp&~aYuh^=>Rw*$hKPlA;$OZ}PD=C1L zlw{i~If5hKW)J8<-g=m>KFB8k?A#o9ieT85kPq8yM*u8tEFETNxW! z85k%)ffCTRqLehNAQv~NT|l0#QbtKhft9{~d3m{Bxv^e;QM$gNrKKgv3?n05pbFjM z%Dj@q3f;V7Wta&rsl~}fnFS@8`FRQ;6BCp2OG|8(fG&l2A-4c-Y+kV**gJa3`MLTP zi3R$GdIlgb!4&%X;#ZoR3s+rS5|oN?FIIz#Ln;eW^@CE2^Gl18Q-R8rK~@!5ITxiS zmgEz}4B+$G&eP`1g19yq1P3s zUQj~FEdbi=l3J8mmYU*Ll%J~r_OMkZZnrq$G!Lpb1-DzAaq86vIz}H9tw_-f69T3k z5EGtgfgE_UPt60S^&()RX8ix}@1Nhle*XCW?dzA%pFVzg|L*OZ*RNi_c>e6^lgE!9 zKDdAH?w#AWZr-?l?dp}wmo8p7f9~v=)2B|JIDYKtk;8`$9@xKc@1EVecJA1|ZR?iJ zn>KD(zi#cC)vH#nSiWrOlEsS_E|@=W?wr}PX3m&CZR(WClO|5+@9XX9?&|DlZ)6$BX_?c{>9G`txYxY$|V zvva-n*2pqbl`!Nnw@$V;=SfP?NOV5iDdMuH;H1%lg_62S9ZM`0wz2c_h6wx#5Oh1r z&k|yC;laYT&MEw!QYQqM+&X&LJncLZl|0x5RD_};UM4MVWl?b`v1t0F bBU6{MqlLu*4o5W>9zKhCS$DNG1Q@IV_TrRB literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/58.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/58.gif new file mode 100644 index 0000000000000000000000000000000000000000..4f7cefdad761b737fccd8367e3aa98d1f3cbc30a GIT binary patch literal 1704 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 VI;637Gj^A6#DxU!3GSGnzW@n#!e{^h literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/6.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/6.gif new file mode 100644 index 0000000000000000000000000000000000000000..e39f4cf222842ad4c203bbad8bd9edd0d7f35f72 GIT binary patch literal 2017 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 S#Vm8fSX!J5>m-l>jPsu}XXFh4 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/61.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/61.gif new file mode 100644 index 0000000000000000000000000000000000000000..5c297e3888a2cd1cdcc21c4406b9af3db89b1408 GIT binary patch literal 2107 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/63.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/63.gif new file mode 100644 index 0000000000000000000000000000000000000000..a66a51b0343fe3005becb540c5a3d03522503724 GIT binary patch literal 1704 zcmb7EX;>3S7!C?}AP8PyO)KoVfRX)2d5!R_hDmwim9Hf*RC1rDKXZB7<5sFnrKUp#$*`i z(4|?rG{)M{%7P$6C9Az6Mqe8_Y#J~;EoeO-f45Z9-z4d);^=iypB5Urw)EwtI73^R zK^tmlNbBxwGgNU~E0TM((f5yWTCS9J=~6o@Bg=B3+eaAZ^7-ce=7BrXs~VQECfGDM zV9*AcZ!8}+50vjt?JDQ%+nY`O&24oVEvMqmjgY>h`Nj3M?bRy{w^rXe3hC>Uj5=<+ zR#H=(`utL&sex;(294E05=~Rb&9dP~GJlEY#p5!qM)LBWs;@q^bnDE^#s0=x?%6!| zUC*-+EpjA97_~aEIlQ|9S3_W7>^qE4_*}Y_Vy09Y%AXZoK!O| z9-yAj_qOz(F%CR?P**f`d%eYCA^iX5ZE;v3NC0?3Oo)GjL)8kQCS zXo-MK%ps;S1XO_nf~B&kY$cqO9hWT1&JeN1#Ly5RSPiP>3OS4k0kwP+q5{<%qEL*c z!yrDkE>noW2n5UE5W}oL0BcMLRl)#+OeKk^fm9%nMyB}(FqzCH0G&#sQmAwajZUI5 zL4P_(r2?-S5s#)6OTa{4#H(2Nj6;-Sm;$6wva+(sS^i{Hxq(7sv)NV+I-P_gNUALe zCRCFUmCvXG4_1kkG6g0>5x}Y_Oh+>@4iV4v?-JySF zlA;O#N@4)1GDM7KsYcKO0T_*_Fd-s>qj?-6&L_)cVvre5<1-m-77YsI(`bAuiwQAU z;r@IUJB%5?;4w$JJXDk^hY@U)D}K#okIS_hL9W0f^I)ZHGc1l!qHkK>l&Ydmri%0mOUUO{XAUPCgGsi2GkJyEA+-+h# zS9!+TxO2kn5E5g;gvn78`=TayGe}4{5FJBzn2|EWfnGG<#=EZ2-hGzTxpS{wj%E>0 znxH#e?YPg47!#lm&z)A_=NOZpUtM=~qR&D%_tF|kVR67Dw?ou^?w;wcwh@Z3yzPw# rTx?elDvDYgY(1wm%zsRK65$k?D><4|^K_cS!bKA9!^V^ZfDrT-8-S#q literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/64.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/64.gif new file mode 100644 index 0000000000000000000000000000000000000000..e5cb6ca0639b47ad66931cf34678c95231ceb6e2 GIT binary patch literal 2114 zcmeHIYamo<7#@YyjX_GSYD~6lF>_`Z#$*^~+|oqY*zK~$%#n$iGtG<)QAA=(_e9&u zZQJflwHqsqJDVXzkuFN1nvqkkjM^fn_srDJF^OIEjKQG!kc$X;cOf5=r z8>`zWf4Es%ikFsoO1p$lFA&Gtc&&w@gCg>yT%0H~R4Q^-bqbn$#uZH)WaR`&8CfYG zl~j4FdNUg`@xuM&ii|)-UtVeIy5ggOPYOIHs!0~NRXhs59A&uk zRQkn&WMxNO|Cpj%6e?}m+SxBr_M91?P+k$>WR;|6*T{XN^4m$vbLx5u<4g)-^gq_p zTeDZG`tn}&_6l1DKRnnjYh=F~7_HC5a?a-+D(xDPD*HrUN~MZ*`RTRdWdD?`gSkgW zABW`%lWy!?+*h>zVx)oc1#{pI?%jw~bd#wXzFx4$pdS zqoSfvQ8p-uy914JaB$FQV6oO}gf%ak&8G>h*}Rog3KWn>=Q25bCd5W)6loz)B%g>> zSNc~AEY7qnn}?cg2StZiXaS9b#-IRAOH)89_1~c^)-;;O_X9uI`;WrBfM^bg_5*oP zB$p1V;VU(%I0P~mr12qc00c!$?V@iO#D{oc5C=i_#~}ilYz7p?n?zHo1TQv^Ph-n7J0$8M$b6F=)-P{_U8jmek(S z45v-2o=n>wWUIZ-RhwE%rBui#WYUl0W1}BNhKD4B1O0vPd*8k7>F#>-y7Se`ju+3L zJ#Bx|*82ESOY_4AP4^oc#P#?7sH?51uBxmkFB9D@y;JgganbGHe!X?`hOn^U`n9W9 zE?>I%%Y~ow^Kx^t&u9H~?#Hv48E4W@pE`Ns__3o$(heW`AvNV-@`0qp{R#2=_Qu8T ziHR0O?T+O0xVtzIn-vkhlNq)n6lBmtXu;oa-?nwjci#pDZvG~~-*1zz&qnG7@AY1u z9`0@wva1Wp*@@`5j^Kc|x5L@mVAU@a%Gzq}ny)QaulmYjCDI(RV)-(&FPAPcUA)L- zp|O!6+(3W9{CRWd=zXE9qdj|;77S)C)mC4VVOE+?k>+m+(^J7_H_ZVmwY8S)W55AS zWmA%?@!7gfBZ;$9%=UBRUrNYc>9COPMRSrmUDD<=u`Po55Pf4b`T{AsGo(z*V4I_v z=}Y8&6H<77kkB|s@2GCjQi-Kexj~lYu3Lo(ISDn%`T>N9>>Mp!GgM?n#3e}r+}y-F zAVcBna(@|itvd|Xl$a7JThxxqpxK)z4lmFeH=b`*X#NPi}YiIbyoQ7jU~a>{Rz!g_SFCY literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/65.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/65.gif new file mode 100644 index 0000000000000000000000000000000000000000..027f28edf8997f98ba49a4bcf9404d56c5ee2cea GIT binary patch literal 1704 zcmZ?wbhEHb6krfwc$UU+_wL=lfB#;%aN+jt+q-w~-q|1iXoJOy60W~*7T;X!{P9H4 zhyAe|jg3E@N!!1?^vrylw`b0rooVsu)2G|ZY+vqmzrG>u-MNy>3$0fM8^7A=`sHxi zAqR(V*Yp0}%lvaGY-6Ls#yW}TmpATeSKQUD{pi}>`=>YV=x|+XY<#dw;>8ZTtBXtz zPt^IG9DIL`|LaZWzkhuFaxw14V(0JYDsC*({%|s6Z>RN#=eG{c2><_T=AE_9bF*0f zznQtQ$@$BJjmBv+zn$>=d%@@B9_OD|V)oBW`}h0n(juONp~gR-ZoG1K@BI~K|DI31 zw6p!${ls47YguJQ{>uF6if zOi{A8Q?RM9s>m(KO)W`OsL0L9E4HezRZ2|BPfE1{vO&W7N(x{lCE2!0jvxsIke$x? zMX3s=dIq}524)5dW`=r(#wOnqF1_laHpait7C?(A* z$i)q67m#PGlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E!^lV%s6w~6GOr}DLN~8i8D@e@ zYH@N=W?$S+WE4mMQ?&&*57FE0kG_Vu;$%quQQ%u7!7bg@+e>etK6OtG@CFf=!^baFLx zHgh#JbTx1^bai%dcD6J&GBYqWG;)RMb;(aI%}vcKf$2>_=yk)X7nBfk3xGDeq!wkC zrKY$Q<>xAZJ#3YU+bzyG&4cPq!R;0ooO<Vgs zyL#pFrHdENpF4Zz^r@34jvqUEVojbN~+qz}*ri~lcuUorj^{SOC zmM>enWbvYf3+B(8J7@N+nKPzOn>uCkq=^&y`+9r2yE;4C+ge+in;IMH>uPJNt12tX z%Sua%iwXi?qaq{1!$L!Xg8~Em{d|4Ay*xeK-CSLq zog5wP?QCtVtt>6f%}h;V~xOjJZzNKk;E zkC%s=i<5($jg^I&iIIUp@h1zAOk>ai6*i#Knt}awLt3yvfIDw!Y$&gLfIx8C1RiNO zE`N?h4u38;X`Tsb>N-Z&7C{L?7S={O>JwZfq-6NTyyCsY_+_LdT+(bsWKB3zBa$Lg zIZb3mY}0%U92^7fQm@(tIyxBmq**!{N3um}#%M;dMH)L3DL0Upq}J#bKk$0fu&g=?hK-9Q5hn(6gH$pwPIOK}bHvg(I=;R4*s6 zn%QCWtgBhjQ|-$z{L)e7fy(qB5^30 RyI)Z?&f)GU(I5o|YXD_ak(dAg literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/66.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/66.gif new file mode 100644 index 0000000000000000000000000000000000000000..faca98013a37a59761e6b6374ed68fed16e28046 GIT binary patch literal 1704 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/68.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/68.gif new file mode 100644 index 0000000000000000000000000000000000000000..2143451805a5776bd7b9cc1b963d6ac68c36224e GIT binary patch literal 1694 zcmZ?wbhEHb6krfwc$UDhyF=;EpP#>v+WkJ}`1_c{?@zaW9klvzH2D9UnSX%nb2-0{ zI(#@8@@#+FhyAfXpKknh$mab%+uuLFzCRlNe!ugF!|ppeTsJm3e>>s#X20jZKVM%R z2>7`SC>1pG#pM4mf{2oB8xe_TEnGzZZP|zFBOX zHuLMXjDNqs-e2SYcu&Z$!}h;Ur(Id%{NdTHpU0wq9kl*;FZ0e?=U<2H9`Ex1c_rrl z>5VVC<25@~&@4`*X(o|EG1w z*46(y>~Qz)-GBFM|G!zhy2A9=(a;~qli$62_v=jRyFI4A4!i$4O(xg&f76kHNZ5`naheMLcHa&~HoLQ-maW}dCm z``!DM6f#q6mBLMZ4SWlnQ!_F>s)|yBtNcQetFn_VQ=?Nk^)#sNw%$$BS=C4WT$g}QL2Keo`G(%fti7VnW3Jcv5C34 zxsHO7fuVuEfswwUk*=Y+m9dePfq?=PC;@FNN=dT{a&d#&1?1T(Wt5Z@Sn2BngG{g7 zSTDaQUEk2s(h_8bk&!M?g>G?WUP)qwZeFo6%mkOz;^d;tf|AVqJOz-6iAnjTCALaH zmqNUdTL3pUuUHT49lhlIT>Xl~0)0b01CWucqiS6q^qmz?V9Vygtyua}vbVrA*-;^b)IVq)lQ=4xo@YG7gPY~X6)X5#4P=HzDT zW(d>klAm0fo0?Yw)0=|OYl>4ZC?Vt)0Bv?jEy^rQO>ryA&s6|>*eVmZTa0j;2i2Q` z+bza8_38s1qYsK!q-cf-0n-kM2~V^@4m{bX<^j`s5in6R{{Q#)&+lJ9e|-P;^~>i^ zA3wZ*_x8=}S1(^YfA;jr<3|r4+`o7C&h1+_Z(P52^~&W-7cZPYclONbQzuUxKX&xU z;X?-x?BBO{&+c72cWmFbb<5^W8#k<9w|33yRV!C4U$%6~;zbJ=%%3-R&g@w;XH1_q zb;{&P6DRcd_4agkb#}D3wYD@jH8#}O)z(y3RaTUjm6jA26&B>@<>q8(WoD$OrKTh& zB__nj#l}QOMMi{&g@yzN1qS&0`TBT!d3w0Jxw<$zIXc+e+1glJSz4HznVJ|I0W*}I zu8y{rriQwjs*19bqJq4ftcs=*(z*#UHfB7Q`f7e^`j$LqHZlpk&YGf(+U$|++Ki%_&b$fcRtkcQ zE+U>HE{uW-R^|zEDojk=EX?m&xL>QtB^XJtnF?4K_!w9SWJw%QVCE6hi``PP^U_hT z>H4usb&*WRyv4gE^u>M}Ej{V%7`LIK^HFQpbp5!Xc_vCPnpqW1k~Az9DX{S>irHDr m`pDeM%^oDP!{K9co3f)&8N*J7r%V%Mh5EeaYH0{CSOWmW6@>%< literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/69.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/69.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f9a4de5c708f174ddf9e87087d1d09f983d350a GIT binary patch literal 1704 zcmaJ>X+RT47!3%e)nZdT>IE(VYpsy%5<)^STnRyxAg6etEXiUbB)cYyEcC+AS{08< ztrcx6cu=eg1r)&~goH~45ept1idrR9Z9(x0Xz7Lu_J?$S%+Acd_rC9&c{9NwLXI~~ zrBEr|1m(pGbDL&OyB5}LrVTVD-z^VqDM3$N?9^@XxmPAIX+sBUV+I-$`}A=KYi~a` zh_w5{Dt5-^=+x%c_+7`Bn2jM_ z4aMaZ2dZ@YG`rZQmSVl3@KH@%P0OXc(!$)*!p6F+fkx?Lqo}bmJ^N&n@k&=?-PUqL zuAyvWzg}2fos+Mr>*#8KUN3&6^)ob7n6#qKn;jLc_wqZJuiZww6$ zQQp*?hbAl&g#!W@hso~(KLUfrNeB)kAZuj`9<5iSrvWkvj~2@kfg+5LNM#Gtl}J>2 zShP4jN$f45`S}712rePVEI|_xE;+U=Gibmt1W)480xUlOOH4kh zL;w~YbQgnOAm9bjA*Lsr&2|GkKnP@j9t_CC9b$8t9$XLvUNssSO({v_Mhb+lVv#c* zO^V|fm%&I)O{J$Y>8Nro1M>FvwrF^GxRVHXRhj~a33r9cWkf-MsKiPchRaX|U{Qn< z&=j0UBQyQC1UWV;t5DI0%b|-=IfH;P21ExfC5-?@qW_1=<)dg79*Mlp_l?4;=rjyr zL?S9QMJYx|xQite#^oy!7)O=SD4IO7i{VlfM^#c31Nc!aAXcW3psA{1v`EAaQK)cO zAx1(3JQ~TT%VZL+0AvR8gFM*~-%AKVK_G|4hlHM>m(V)^^kPBK2v>lLQ{;#OAK^+~ zb2(#jEk=-IWMl!Nlx;vHLM18(h70D(#?FN`rrs;AWb9nL#^f@{WEhrX{m(IvERo)^ z3`b2%PDX8yC`hj>NmE-5{r&RA;DGu0v!_oU_dj~r*ZbF>5ANUlqsP>J_s;LPZ{6&= zalNynz3tl7E0+5Q3s*Q#!eWgyTIa5)7y6n`+(vsp|iwaL1 zKlaPff}it`96od~FZaMtKmM?PU(Vj|_k6ee+w5K6?A)<^Th`Vso4?-l)t8y-jTv8j z{@JIWq^A+78&YtUay^DBXh(w$K$FEr(w`%2z<;!B1#zaR&Muaa36NN5b z6tXZ_7$o2a2Kf8=@)r1Ty*X?zmM7DLyijy^xA`B>`)KZmb6j0$&cJLZ$5}IHOrQ3_ z)G3oEIlNDOZ=(IX6UM*uw%uE{Hsh?VC=_S24cQYEH_NkOd95jS_cI7JILE^ Qnkta^Uq2rc4p4ml0f!L15&!@I literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/7.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/7.gif new file mode 100644 index 0000000000000000000000000000000000000000..330fc953c5c1f5d8f06ffd0845d7f1967b3d8b9d GIT binary patch literal 2106 zcmd7SSx{418VB$T1Ue98X`-Sci#QmOp%6ra7P2Gg4MSuxLJYg?3Zz9Kh%5;%*bOaV zlK`@VhG7v9h4dsKs|#y`*nwed1+iPSd&o_0Zti59nkj0Y=CRMyc{x?T`k(*zopN_2 z+63tUI)DfTkbB_6``NNzCgAp*C(LX(++Vf~!Y@Fisrw<5B?|^&7H1kf-W(M-SzaXu z{h_WfF^|-hmhry5TMUxWBv3jBb|$4x_0>K$w;ZXduPMnCm->pY`N=+jeVt{fA2>(x z>#RzajZY&pP10%-^7A0X^g`~C(BDBc7K8_xNC%0XLl<8O>kN;PJ>|o*3}NSa3F!Nz zJnT)P--?et96*D)BzTljUzkuDpCG+gh9Y2NL9C?i`bbZ;xF3{7g0f5!)N}4}N+fh6 zy!37g^nij)6iLV+>=Kv9+eny zkN0)gqhp{jBmtsENG^nkLQ}_WPR(V1Uwko4l=yuemDZDRb-ADdib$KI1U&UVFY<|$ zExv`$MZugF+4N7NXZ;}h9hi|01<_|J>yd(5@!bc~67D25WSSO@f?m`4Mbb9GWMpz_ zZv0$N_BgLhw$ioSU(ivV zdWfD*ikb%cTQC}x|9Pz%6XrHy=Nd#GW`opL^YM*N3)+z;G)WHoX0B?b?ez&hfVp|gGz;2)dVl2Dk;*frBU;*l zqymfJwxfIS#;(&%7c|==$bTAEBWT@Z;vBc-u(+uzy9}*o%xOFa4aj=I$R!t__3p2M ziVCCiN)j`RL@6-=XL4o3*-hB|&9Z)jt@DnIKliRGA^O_;rZlhQrs;3qLEbt2WhoU& zl~l*RQEV(lyT-BgukF_+a&0NEU6m>i@3#EBE0BAiOFVIubc`q)?W|k?~bs9SKR(UWD zRex)7TV7ezjMgIpgp4d@oNcmOq?zE;sU60y9vu4&MZR0USsY-$_{`mQr@5MNJ$S6_ z<=4QF`mH4cBFHGwHN;Sz{O|QLH1kK7`YlJSF`2q(sT0!1X=d7k`oPi zi~MbCaZkiCkLO7rB?m175Qcci(bUEOFM}__iE$ci7GWV!G zW%fWNp3sWdND)Xz2Z|{>F}*%Z8wOctd@(ARtxyFyR9y~j`xlfL=cA~ofi=ZbRt@$k zqO``Sj<`T4XGCIi-&%3Njw(nb#9$jM_PHR`x!s4&LQIJ}_HN?vtD_ZZ#;40a6lG{T zIqOF2TTW>XytsF)al^DmLHqD2BzrTzKjf`JW2^ao=mx*AIe1sb+EYcJD3u_1(+KKF z-_E^I=P^g{Om}cqG33_#(qXvsfuCl(CuPYsBag7%8yr8O^^(iSv%8+qi(lFG`y6D7G)znBO{QKGeE`gI< zmVhah*y0IftKwLWQ<_Tx$8y7ec!iP!E6I2z<@ZptR#o10w+GbWw%X@K79k@X_sOs? SKmW&(D2M)M!~Or6ocJg87v0VP literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/70.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/70.gif new file mode 100644 index 0000000000000000000000000000000000000000..c107a14af86ce4bfa1f5a8e393a80c6d2abd3049 GIT binary patch literal 1704 zcmb_cX+RT47!9ITxk{-ABI2@mBDo163xULhgb0xcXt3fDk_{Un*)&-s(%MpLTd*Ej zwHkYgSgZAi0 zqX;AglG+fG)0*INIh^(UkOyj+$h5hZ(Qo zHB|~6)v@k}6;&kyd!4xF8q#-1({+-oHrw!8;mzG#*X0Gb4hR}|39jyBJ*XC2w~+f> zJx?wzX=$iBZ;oxhQsrpOw$}*yoIQ`vYr1V}yJfL$2iMiz?CvyoS|rCd$g9iZEN1m1 zo2Jd8c32Ya?alVK=Gtv?{8XH?yBV*I@2HVG>K8d$%W&&_rrO+Pl^-oly193@<9=1g zv7{S^#82*4wd_yp?W}xycCNeC;3Y{6vX0xLJ28~Xm(il`agG^^bOa?@w0nZyqL^G(=P`Xg`JQgwI zf(VA`Au6@7u#i&7q@adeDxJgOcr+LcGJzl)SL!f@iL5h53@8X;qtc+!V;WQkcoY>m zXaU9riA?`4L8~8>)fp-MQ_=uXD*bP$Ry&9`V(IXUeE(J0n7L99 zQ`2E1T3}GZ1U$kMN)HJPumVF3nJAh+u!}MT#ZV)H>H$Fp3y^DcDzwnpkCsXyiOz^A zbV^tv@S>WRog*q~Vft3(D=3-lKZX@<@vdPu$JT-DIIu!iJPiDamrWBtc54=fSh z@eBt|OH2lB59p(M$$$p(y02S&=hmOrJJ&N(2}VOb(kAIx%EI z@c40K$GjT!O5n=@{(inbqeqQ=X~b~vVO}IsxMMicBcv$LGvj%!Nh2Q?BPHR&$mvU` zM+(DB)*)p6s04{Zk}!%-UJp?hQUZcsH|mKQOuOF@iP$d)4g4FPN<^JJ;MX_bAQ`c+?3tZi#$Gk;;Q)bog=LLD!`-@8g W)|S&N8ir4Z2;kj5H(v&j;{F1P-I>7v literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/71.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/71.gif new file mode 100644 index 0000000000000000000000000000000000000000..62618d65945b362e01a14cccf7a6ae4c75127f81 GIT binary patch literal 1622 zcmZ?wbhEHb6krfwcoxEN@0!u~uaB=>w7Gt6-kaxV@0`oIek%9MvE+Y$|6Dse>)*e> zn-*HGnrVDyf8NJ;cMoh%e{dmT&$`%63k+{wnE&WX;rA~OUfikv`R(DmyXkKpFMRW4 z#os?auOAP8@nF@<+q&Q0&fU4({_63_&(E7~ob&qlq~^i3&^@b6uAFiI_HO!%+nQG| z+5UVt_0mD@Pfu%4Zr9zp+~M3l?`!9M-`!O{xm|njYNMC86Q5nvxqBh=-qplUuV>!4 z5c2Yl!PV2YKi^J1zu))si`EynG(SIYzIZ_6+nYIiRvF#6;B)0j!2A2!?;h5CdQ$!I zQOU>0r7vz^BXQ!4ZB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy z!KT8hBDWwnwIorYA~z?m*s8)-DKRBKDb)(d1_|pcDS(xfWZNn^f+Q3`b~@)5r7D=} z8R#Y(m>DRT8R{7to0yxM>nIo*7#ips80i}t=^C0_85>y{7$`u26417ylr*a#7dNO~ zK%T8qMoCG5mA-y?dAVM>v0i>ry1t>Mr6tG=BO_g)3fZE`@j@w*YQzUa=n7J9^3ax%w4}1^R}11|ToN6#Dw&SDKp( zS6y5Zl!|aKR)dQ}DhpEegHnt0ON)|Ify$LZRuxz|7o{eaQ# zzd*q`*i<1rGcP5-ycn$7*VoE3uec;JFFDoI#a0QZUoSH=#md~&(Z#~t)Wy)*+{Mt) z)xgrp%*ol<&B@H!$kEln)DouGB|o_|H#M&WrZ)wl*A=H;P(sKp0NU)5T9jFqn&MWJ zpQ`}&uvI2*w>aT652`l>w_BWX>eUB2MjsTdNYM-v0;U}h6P{>+9C)%%%>$o>*T>t-)5G1()y3J#(ZSx% z*2db((!$)#)Wp~bn4$D^b+olKHPqEqRg{$!73Ae)Wu&DfCB(%*k?9`G&P4vO15-#h=_FdiVFyc_jX8$iAhav zVU>4go!KNRqiriA+7Y~BrMb6P(8`sJY>Ji|_Kp$~x}HiNZfuMpT(Wk7DyFKg>Q;UR zvRo~U>=s%~R}I+@bn+@Q+-0!g?UmN|(X^Ix@KuoRWbt=5Q*#M0GGXcD)YIV>7Up&` f7E-BFP;6p$@ z$N`GpX{W7ELg{|)@dQ*1((ChZtdKAH?a6dYTNUu;=R`KC+y=+1QcFTaa-$~e>t`NdEumw>fT%D zu6t-2vH#4OGbR@Ou4yNnVh`Hoeb}|T?e!G^gJMNu(SwG_Re=uMm7byPc zj_?goa7ipl1kyJ46$OdO*{LN8NvY|XdA3ULckfqH$V{%1*XSQL?vFu&J=B$SufCElE_U$j!+swyLmIN=(U5O0@#ALBje<3ScEA*|tiK zAPEJKozD41sS2ig2D-@xW(EpohI)p^Cg$emItoSxh6efuM*4y6>v2->ucCj=wc82M7$xklLP0cHT=}kfCb;hX|ln`ti4*$!dV9LNIy>6iT3ec%8XM~C zYHO;iDl5v%N=u513Jdb{a&xk?GBeWCQd5$X5)DCA|t}XLPLUs0t5X0e0{vV zJU!gqTwR=<93AZKY;CNqEG^8{t;OU7;p+<4hSD zDO>A!g9y_^_9g*MDK+1i5Y-F^Ny#{YCPAA}9Y%Xj&UD5no`OwEk>*)%q@~}yu~2H_ zOEO|&;$~pr{$Xav$71**!PP^6=eL1~c1SDd~-$l z-IZmV8vL#;F1WR#^yZ4PmwP(Do}KmW{H%)$^Di&VyL)=)ot32rdm|R+SR9|4bahGL z&X$0^Gm1}6O?a`p$*Zu6I{P?N#NsR+ZmdQ+a=F<;~?KSNARZd}{jDB}MytqJCak z@M3$z^`%8GceN}pcl&p9*^6E6-!II$y?geN3DIX}ras%zdSPDn$Af)0mli(WJMG@; zif1=YeR=ip?98-{ZP7p8KRq=o^X{6;hnwneEib;ZD1UEv&ox1t2j3&l#hD=EpgRdNJLD1hvA&M!(;Fx4~AO*SwyP%typ zGc-0aH#gT&FfuSS&^IvBH#E{UG`BJ~vNAAGfC43;ZAB?*RzWUqP`iLUTcwPWk^(Dz z{qpj1y>er{{GxPyLrY6bkQqisxUThW@d_&g_)D9iHoC!p|iP*p`ojRg@Lh)rManr zrKzcfo28)%Os`9Ra%paAUI|QZ3PP_XPQ9RnkXrz>*(J3ovn(~mttdZN0qkL`Ox$iU z!)YE=ZwhX=nB&x|4|I$^C|Z%C872fwJ0K=J(E>T}WS^P`OzTC!M9ujB-`_vKfBpRN z{oB_spFe&4@c!M~H?Lp4eDVC*(TITuzuazHLF*xT(NxF(j|)*EnF~v-rPB} zXU&{3ecIG1lP67_(BIeF)7{nC(caeD(%jV8P+wPDQ(aYAQC?PBQe0G6ke`>Elbw~B zk)D>ClAM&75FZyC6CD*95gryA5*!p5;P2<_ zVr&G=PT0Sg%1Vj~@^Z2=(o&KV;$osA!a{-q{CvDT++3U->};$o%uI|7 z42nNlfMf%M4ybSf)s_q#Cm9$yWi&RlF$q?4Xo+MvH3~@xi)o24v^%uO39)l!OlWVA z(UfG&onpYiA)zOEH>1<3!BtW;R!pbD@PoG)cRCwS0P}+M^M(y)Yz}-2Lu^RPJB(CmBSdIJ*^gEauXU(B5V literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/74.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/74.gif new file mode 100644 index 0000000000000000000000000000000000000000..18d684e765fd20c5bc1967565b704dc758868ae2 GIT binary patch literal 2105 zcmeHIYamo<7#^CIQqgYhsX3jBlWYX3$#H6hV z$*NUKs5XN!(Ahz zZYQTE8m-^MW2~sCe{?jfq$JPK@a6b;UR70ob#+N|b1R+RVr%=t!=rOxU~tEdo{^De zxm>~JP8~cL788>wlbudWD}D5+sk3t`Hg-}hz5#;D(9oKWjH{W?sn1*aJaza{0~D z(pzO^^<7OW-u^9@`=qBQDLp;m+BIcdoKhz1X0dWBDk@uB z8?3FT($k}ok}?YmpK&-j6&3dy8y|LbOmH}FC6egm)s0LBYWfNF=3FiTc0& z_a|Ve)bVn01sF_(sp@Sui(w|)2SflCxQ{2GVuo(t#Q;1G6|>Xa1@8jWK`w7gpb+#3 z+~&y+^kI`Zn9Z928!<)9hxs7F1jKw_fruieVwfC=1yWRF^)e0vOhXVKDu$-s0Ms$* zkPrmSv3OH9-U1I;5U>Q2nWd$r2|&aX@HjjXMg3cf}i3Z~G7AQORvo)F|abBeB92!TXg2nOgL=D<##fCB}HrqM1g z6i0ywVG7uwBZG=j@v%G}hhk+%##>r2hy=PNgFvvulP!q$G&355Ml@qslFaBcTn5DU z=Ys-dhRgZDCC$lI8-Wk2A~QfCZ$HSf7eahsx?l=#?p*M5>b>W3=FWvMCl{wm2B*H( zzg_dplFB>k;jC#@lUdt?0+rW=DpPAHrzYP`yd57Kee-%`_|;3r(BQy}{=VnEe?05y z?vi(Qv_EZYee$^FQFBvc!^8Tz+M4RB2bC4&Wu+ze?-dsn7Tmp)pLaVqC;QgTtjymt zZphNF|90)_m9*59%gL86CS5q6`0Kf|3BSaji8~z|6MZTw^5lu*KOc)YDh&@i5*i{2 z4*Kcvp&t(h9uNoY_eVrRKNu45eSLo5arb$H95#!&_xtbm?B4b5H(oox-r?!t?&i9E zn~Ss4R>v(4_I3>VS2Wwro2WL{6tb12g}E7tsCuEWrY2u*++e)kXx-X17(?KT&sQ6) zTDe01vrm^V`{d)Ldb&#%FVb1KKwImh`RI9?8YqSCYR^$RZr5Or zAKEQZM?*8aw^Qy^t+Sf4C?}+M`+N<}g}{am4c>fBbgDM(lF=f=RpDHNtt73Apme7o z?U)Q(d+BOJbh(#|b$_|3?p441ASwLv|xQ@G0_;1l@%8)MlaJ^a;9#$HUf<{ z&CUcQwvvU*t>iW_9&)>RxWzVk#!&z*!B)55OMJfYWY~IL6HZw{cWJRP!OCDGlByl9 rZ{)0}{R%#&sRcX@QgqtVB9>{LwL#BA1qJsvYOE!gC5IIRp{)M|*wgu1 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/75.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/75.gif new file mode 100644 index 0000000000000000000000000000000000000000..18a7b9220d64bd13208645722d86fe444c0caaf8 GIT binary patch literal 2075 zcmeHISwIt46paFkVim2nXweSAtu16@O(23KAXozt!X_?+WP}LG#3Y!Aw1Vtd6f9Ce zK{nZ3KoH7KKu{5+5ky%-5(H&aKqzQcnoz-hlz#QI?_=I}&bjx#cV=dfjg>K$st!|! zO~=5dWtV%(`Lf33)If_Hk(LR3Jy9OBGSOkEuWfYTX}XEaCF>bka&;2vrI0f5;NVE}*^$PG?gHC~*AGui;$L@O zY|pdJi!^B~@{(1#bXEI`@;s%bPI*ygcdl4Vi^vUE?Ou1qi*J)h+s@xfb85WiG9^tM zYKfeD;P$d5A}17|6|!r*En=*e(ptdmFSQew(+Z-k#AO~ip*V3RUs6ndHP^fI!_CN&q{ZZ0=WV8C$#0*f=7#IFm-EFH z$0U_Uddm*gr;~eyg2~Rf{!(&InCX-_@oomCIn%nQl+{*re4;yUN_wfM;zUdSf$_)D z*TPLiw>*a$LI%qAKgzWmZi)~lyUxze!v1gn(FthHs=1KJ0Flb0%6n5Y0h>zm26=!7 z=*eK=;jhZ8;Q)hw4(TpEYL<}n}^pircGK)yUYT%PG)B{10wvMerQt{emn zVj=}pHWH0MDN33Ll1Tp!Wil7gT%JAnDc^q-=2A|wL8Lv%g?u?QP!88tgks|e9FWR` zI1~u-nLkCc7sP|OUJx4~I2ZuV3>F>YbLY?`63&Ljnm(w5Z-kE`9M_j2Go1<;frw*ZQ|>o?nuCM=@M5t$eazdypmfI!A8m zC9@yizx(6uo0;j~rzT%djE}u~IXW^tH2C8AK>xEonN-p%?&}Y@br0sEQ%OlZm z%@3OzA2i&*celRoPHl~_x~j6GysWh3*W#kvg$1|r^KRa_el0gAJ1g^QMtWLm%9Z4# z%a;-p;(v*|82j^unCSE8qJBCX84(^98WJ3ICNSXik3aaI@;fQupYY{zImg)$i|ONi zjN#>Z6r|HUsP0D&A3ErEz}3as$&uno zq(#fBz@>Yl6VT2Ys!in3hg)=hn~KAb@|Sn z&4&)%U$Efn(}S6U%QtqnYw1p%r$H7K7G3J$dN6F4^LUQu4Vf4@9Wpk+pyv0qepwroLRYV-?jVq zFWk7Xe*gaa&!5j+v0~%FgC{OsYMnoS?STVbix)qA{d)QK?a$x6`~Bz7t0PAaUAfXc zd-nGqKVH0jo8Q&7_Ta$@D^_ehcIUo-)&qM- zFF8L~zap_f-%!s0@{(ZdJ#@7=v~`_|1H*RNf@a{1E53+K6ZM z9qnzcEzM1h4fS=kHPuy>73F26CB;RB1^IcoIoVm68R==MDalER3Gs2UG0{ zA;Cd`0selzKHgrQ9`0_gF3wJl4)%7oHr7^_7UpKACdNj<45g>5qphW>p{}N?qO7E- zATK8?BP}H`9&m{A4!PtC-^m4 z8mb8k@^Q0r^9c%@S~Yoa7;!Q&NwP}*Qaxbwg0)*u=#WOt4kxF6M~9p@90AJ~xoR_Z t@Jw2i;>}>B;4H?$pe)Fz7;eK5vGbBMr&^aujD_>&XEV8_*jSkutO4FcuPy)p literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/77.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/77.gif new file mode 100644 index 0000000000000000000000000000000000000000..0a996d59e9f3c82f109bb27470b8d2918d3419a8 GIT binary patch literal 1653 zcmZ?wbhEHb6krfwc$UR*!olHZQPCZ5?~`fXpA!u~?25phGeb|Vj9T64yr$FP z!M^Mxi{qc3?RdMxXXU7_@ZcM$j+ILxt-La*KcXlS6TITb7Pw4tSuPg5E|NsAI zpbRMf=Z^3VP;f~sNd(e1_7w$*$=RtT3Q4KynR&KK?|1K4QpilPRSGxtHSjHPPR+>l zs47YguJQ{>uF6ifOi{A8Q?RM9s>m(KO)W`OsL0L9E4HezRZ2|BPfE1{vO&W7N(x{l zCE2!0jvxsIke$x?MX3s=dIq}524)5dW`=r(#wOnqF z1_laHpait7C?(A*$i)q67m#PGlu=SrV5P5LUS6(OZmgGIl&)`RX=w>E!^lV%s6w~6 zGOr}DLN~8i8D@e@YH@N=W?$S+WE4mMQ?&&*57FE0kG_Vu;$%quQQ%u7!7bg@+e>etK6 zOtEq_b27JdayBz`Hg_>JbTx2tax!#sGBPuDGBS5@wKRn3b;(aI%}vcKf$2>_=rzZw z7nBfk3xGDeq!wkCrKY$Q<>xAZJ#3YU+bt$I&4cPq!R;1PoO<VgsyL#pFrHdENpF4Zz^r@34jvqUEVojbN~+qz}* zri~lcuUorj^{SOCmM>enWbvYf3+B(8J7@N+nKPzOn>uCkq=^&y`+9r2yE;4C+ge+i zn;IMH>uPJNt12tX%Sua%iwXi?qaq{1!$L!Xg8~Em z{d|4Ay*xeK-CSLqog5wP?QCtVtt>6f%}h;V~xOjJZzNKk;EkC%s=i<5($jg^I&iIIUp@h1zA%wo_16)>REnt^>sLsnB3KbO3m zJQsg+PnM7rCxHoutG^syuei2GxQ=P4l99T2FOPGEo_>O=VRAH2 zub{D;gI0uRyhVs$udrIAm33N@Pn4Z-FPn#QfMdG3jb#{HuRw6BflE-LnY)TWFE6vE zcc4j}lNU2@kEnvQn5>Mwj8()9hDA*ZTue*?9101IvsgLBxfU!?>viSH(xlmU_E2GB8*J08e3jc>n+a literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/78.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/78.gif new file mode 100644 index 0000000000000000000000000000000000000000..972a21d831e2f75b968722d0079a7ea4e4d2f325 GIT binary patch literal 1662 zcmZ?wbhEHb6krfwc$UF%M9}!(pFcMRjUU^@{rmg(p?lg}ubg`(Vdq-9zX_WhQ8Rte zGWk~L)cN-IPv)=s9$R;M#*E!L`5%N#uD4BiH*586tEh(_>EG@=_*Fgiszt~>%c!?L zc~60+*~b6-`D>q$$-DXMA2=nwo3`TL??0cPJ^TOn@9VyWcbpS`Ojvr=H}!jT?OR!! zgJKp(3|)8Y**r80eqx_+Ti*VOec~l4>;KDlJQX&*ZWj8jd*T0OJASs#{uE#PDY5Rd zru#Wr``x-WUmIuK5;8e2V)i_u=%A?iQ6ZDlHo@mr+-~Xz9@BSyrs4jrXW`?(?AKyu zkEN`R=s91rjr>tJ^_Ga)F=^YULMA7SyuMdYe(9h0!Y}uftlcfWfY+&YpYq#p`=orY zn)K8&{dr``*Vfs`jXh3T_`QxQKX2@J-8}S^b>KNc6v-9O7C~?S5nAKu~iB;^)>J6!V;*iRMRQ;gT;{4L0J^^2{qPNz6-5^>ndS0_xYx%uKOzGBvO?F*mj_bT)S} zG;}qvuy8haHgR@wHF7a9b2T-F>2=9ZF3nBND}m`vLFl!_sTY(GatnYqyQCInmZhe+ z73JqDfIV!LiQ6q^IL(9VO~LIJbDVnhfsWA!MJrM?!-Rlo2gHOYS|A6W>{IiAX}t)T zs2TtN`}^njub)4@fBX97^QVs=-oJbM=Jl(WFP=Yp`sDGWhY#-GyL;#Mt(!NlU%Ptc z@}-Lx&YwGb=JctPCypOGdgSn-g9rBS+q-A?uAMu!Z`-%OrteG>WPn$Yr@}!9q`ulo&y1P0%+S^)NnwuIM>g#H2s;eq1%F9Yi zii-*h^7C?Yva>QX($i8?l9Lh>;^SgtqN5@s!oxyCf`bAB{QZ1=yuCa<+}&JVoShsU z?CorAtgS39%*{+qjE#U9N>5iuTT4?zT}@R*SxHerUQSjdetC||CxrGL+LX&!egcg5*sAw#|mV~`}hFq$pG#i_Bypz>V=}ht!HJi9&;v#Kb7+$=HNa1c0cl9<-|NO<#CQZDVFG)X; z=|5A$kp+(y2s9gbW)(azSjs8H*2dwJvC*lCMa@r5z@Vj#fk~WG=!e6GiORDW1VuDD X1P(k=5aN}ZP~geI#M0Nuz+epkL4;jh literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/79.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/79.gif new file mode 100644 index 0000000000000000000000000000000000000000..3fa89d82e826904f9391ea63e28f4eac3c402dd5 GIT binary patch literal 1672 zcmZ?wbhEHb6krfwcvi~r@6VrqfB!yoPkZZ?^VlZt-Td|ce*U^@5%Ocg(tDOs4_YRF ze)jDD-@o7PJoqMTazxGaoS^YNldxNzQ+Ma&zniuCtxw+9*4e+Rr_Q&xe=>j7Ro~Qi z(^fpTjX&4Y{qOgm2Tn<+XUw?XHsO18?L&|BJI)FFgiIcZnH|%2J)-CQdiwJ7B4)>p zJ-$~>y66%A^VOSMB4*EB)BZ2p@k-YAwW#SODeFtB4hO|7&Z#-x(hK+=TX$5}?umWE zZatgVQRUA<3$BJ{-POUp-;rHj=$4~LK=Va|)_bt3`9{SKM_-o^g zqhjWFj6?3`HT_?{<8fg2VN+Qr`Vq%h+i#(Mch>H3D2mX;thjEr=FDs+o0^GXscbn}XpVJ5hw7AF^F7L;V>=P7_p zOiaozEwNPsx)kDt+yc0Ixnujbty?y4+PGo;y0vRouUffc`Ld-;7B5=3VE(+h zb7s$)Ib-^?sZ%CTnmD1queYbWtFxoMt+l1Osj;EHuC}JSsEZKEj1-MDKQ~FE;c4QDl#HGEHorIC@{d^&)3J>%hSW%&DF)($R2j?$EcLDMHP!OYnG4jEmHq6*;w^%$O16d}fBQ5DzPdqU$jp)r^1^j)WC{4SY5-78#ctQ%+hjsM%B) XFdjJV$Ze1iQ7~D6LqL_8k--`Ox-)gU literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/8.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/8.gif new file mode 100644 index 0000000000000000000000000000000000000000..b573e9b3e645d787ffe7f97e5f6fd9ebfd25e95f GIT binary patch literal 1199 zcmd_p|5sCW9LMp`kfjI|#Vp`(I6zRqF%Ln95NQWQah~2HUz1K@ft)Z7r^6SIkywo_ zz9bz*VTl_YxEOdDCkGZw=YWlk?@W*{V!>!IN*#fO9e1~Txu5W-{)k?G!1IU4Ij=*9 z<0JQGx+8aFl_S|XF=hczKorjjF9G`$@DpHZs4Y3XX#xBQYUp>{DPH0p<^2{{f@AoYG`&&b5zSKi(zFF^@L0e*@W6 zX`lRhOrA@3C$V>dT?Xa>utUIZn9NE()qQfghtJ*zH7TU$GP!?1lj6{pZY(N^V*D$xCQvryu#cflns4k%U)J*J zdnN4ZUE|N`RCkfRzrw0M&HSdoMj)<~nhY(Qt6=K^dLCre1;et)uGTW0vcWo)K#$j3 zrfyhO*;Z8wV}_@i1XA*uNnb@ai0y`qm9Z4ez(h|y9tEPNz}|D584)h)_*PY#y)WN3 z1WYd|u2#|ujm#p@Lt^GZuW9rUbt}{ION#FHHM{`iMK|3%?bMh8+G-*XV7fIA) z`FO186G3W_e_wn>z{M=@Q$Gc!$-{Tc&)zb3PJSbTT;G_okXPnHrrFAqoiP)k@HFE`pXINiurl80EH~*w1qhOUmdtwd24&=lDcnr|9+PJtOO* z6M`2H4!U2cO4d9qvP@ST%^JA5?i>8VF3)!aM?y?UBvi$|RCcju*ookJc#spxzCw;e z#ZiuzUQm6>+j-BM_l2z*pV7J%kv)8{)-k2kKkp=GUv*oOTV=g8)_g!Z>*=qFmeg=P zL=FyTB39R*tZStzboz!q&e4bG_8;Fi#6_;iX^SrkrE!pOr$jF1Zr|x0+GL7N<9a$2 q3p$(ot31MU=cz literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/em/80.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/em/80.gif new file mode 100644 index 0000000000000000000000000000000000000000..84e3ca41744e367487844be77d3216861e897ee5 GIT binary patch literal 1390 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 J!Js3%{{uSJqN@M^ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/fullscreen.png b/AvocadoEdition/plugin/editor/cheditor5/icons/fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..4111243acd7702883ae5efa39d704c86e0c03b56 GIT binary patch literal 1305 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/cross-small.png b/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/cross-small.png new file mode 100644 index 0000000000000000000000000000000000000000..2de4c12037297afcf41ffe8a77f6ce2df813b504 GIT binary patch literal 2938 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_bottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..daa101c00303415ab8f8cbcc4bbbfe972962d982 GIT binary patch literal 43 ucmZ?wbhEHbWMg1tXkcLYpT_Y2|9{1wEQ}050UZV)0Ld^gF}1`qSOWm;KM4l_ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_middle.gif new file mode 100644 index 0000000000000000000000000000000000000000..a854393c40338b80606944f8527c5ab0d6965b09 GIT binary patch literal 49 zcmZ?wbhEHbWMg1qX!y@?;J|_ZX$*=#Sr{3BKnFyCWEhw@ScKA6Oh4to$Y2csJ4FjO literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/marker_top.gif new file mode 100644 index 0000000000000000000000000000000000000000..daa101c00303415ab8f8cbcc4bbbfe972962d982 GIT binary patch literal 43 ucmZ?wbhEHbWMg1tXkcLYpT_Y2|9{1wEQ}050UZV)0Ld^gF}1`qSOWm;KM4l_ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/imageUpload/mouse_drag_img.gif new file mode 100644 index 0000000000000000000000000000000000000000..4cd7fe127695565cd1d0cd7f3038578e83756dce GIT binary patch literal 316 zcmZ?wbhEHb6lM@$xcZ;L)Wl@k)Tsv!95{LM}; zG&I!K*4EV2l$Dhg5)$I&<>lhyVq;@tW@cufHc3iccFHXQfd`jp`ulCzt2wGYWK&wzxL;TGtYOM^SB_x7qXtgA+lW zs1T$X)zZR)c>vF1wZf`li^Zzb>I?=HXtdjH$H?Sn3dL%%n2g5D6iOY1GK?S?SY@?X zVSuOC=`1<9JOF@sEeL@89!j=YP*LVK3T4FC@3*F=3lxe@r{75?_ct`a0N|7r_4M?h z()0#B2H*`{xuVl)UkFE)n_U6etoORR?Kb=E>gqAgcYO^FJ!J}&3WdVIH8youRcUp) z?-dF(mG>JPdCkKUDJj1;H962U+3k@kRSk>=0&BG>CrV{=I2^oY1WmEi>1=Cj)9G}B zgM$D7prNDv|J(mO10-ZhR%#l^=Eykc7!xNKb8@$EWnd0>GhY}BJ!|_G0{MBd(7MP} zTB?}E&F3d?lW;S(t;)>Zwk0g3RfmpzmaX`7CP$*@{VKXq7#X!7OWzmDIC8R3 zI{zgDn=8$g@WnE|NC>(ZIXR*tSuBJq{Z|MA@he)Pl=31RO0Gyim2<>YI)&y6>7`+6 z>VG#C2wquBW$E0%^!`U;Y3BQ4E;XGi6%|Qxxv2Skmn$)YCE;>pB1xu5RQNKBY55|V zNSZGagRBe~3|Yq)=81}>i(c5LrZQ55QW-~>%S~a&LMQ`;&(C8-#)r`(;Ux)CNo*FK zo){h##R^Ldi)SUVVK|btB;qBOEy^ttaD}p$*u1~6tk+^)r63Tap4nUpe=9dHNg@(} zFG6PUU#}(VwS0eK^Ioqd{zy6#-(LIXYFq2qEzMswHC}1Btp4)S7Z)#_|GfUQb7$+$oIX{1^2G6D zpB_DO_|U;m4(#7oquRUY7*vO4`UC^B=uk$-NY`9A8B2?}0wqpfxUgW>gMC4_cKPP}pB~)*>y4yo zevzI1WsCOEy^q3y4>LQP#&0`xtp68GQM`w+UQ%yjtq?Bu6S?ly!|*b zs;s zBij-_?b^p|6<)moH-7h$+ky4z6~=vG7|H0KR7EqM5V=_2&3w2T3)dV(I9m z;@yL@+y9U}y1ah#=!M1_)3f{6tB`rCuU)n1#%@zr4B=}$*;FE_X9D`rZZTwQOtrsk z_nP*MG@_W2qgmMf!Q8&PC#PT@fwd)ASW#QzWo({T;@!IZfs%M_-N};rKxm{g=wLpy zi&&Z5ktH1jHoDJG0QOh*oSk*XgIS61SOs}6IY=5foBxnRBpiVXl5rEteXGFQp#7_G zH6MAeN&CDj0Iw-6C*TQ?((Bz>3B!2h)xoobuKv1xX?U>ztk>#HRWLUC_%7fuQ_Rmk zh#&m%vqN}$=>~5caZL!O(!U_zJEgtfJpd=~ub5fsoyNq_Hnu9K&G2P1&mHns^W6`o z1LcxaipPuUqqiSjTtASFw4T3sY1{6jP|Kt9_TZf(Cg zPnm|(cvh}V)+G93I=>Ul5o<6@t`Zbp83#(PSAph`gK6QP5E5>A-pA`##r4KK#0-30 zsOx>Rt$GMdTTU+ep36r%m_7(-6f50DpkE6iXsd#=dsR)4a{Jd=sM)mK`d zQi{c?<3q&Hm1*rtV5!EP611s&@>0&^D0zb4X&Q#S@)UNhrqj2ZxRY8(nz~-j3LNRH zsQMtDzDlGRXpJ#i;{aAJ@A)|t5`&CO-jiM^%v+*$QRA`tyg_))cw literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_center.png b/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_center.png new file mode 100644 index 0000000000000000000000000000000000000000..d2ee3baad05bcadca8fc39bec512737bbfe5c5e5 GIT binary patch literal 402 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h82?0JKt{2vcT3T9KTU*=O+M1i2ySlontE)RZJI|@&baZr- zmzOs+HMO_54>T}vcXzJ{loEmT3R`lW}W@{++`C zo}QkI8jS872{14)5Ed4mU&p1dum9xa>IcPkxPZ@X?H_mfjP_x38kK5KGk zmy)lq@596D5)u;s|Nl=f&H(wwpd`pI7|10BFeEL#Pyy5%5YXiPriQeh1-s?fq|Jp(n!6evH00;pgjzpu6{1-oD!M<>DsKc literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_left.png b/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_left.png new file mode 100644 index 0000000000000000000000000000000000000000..7195ef77b25df3995c349d6db31ec55db3db698e GIT binary patch literal 396 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8-T<>lq)RB^hxx;i^MJ32a= znwr|%+pDXqHzi023k&P(>*wd^8yFa@o5=m-lulo+!l%apw|3}noTzJJV)FW7^qpNw z2bO4idU|?!dEGf2aBr{jk@dE|zP=9+tG_;LGPj!3-QE4}Zl!;JG8Q!$&9CDMG%%2m zkT|rKuOf`^|NsA|cV3GFI!wPL$S)YkB>^x*Ew%U#)EedK;uunKE9rtWGfxD|6A1?f zPlp&UU(X0RPX}*jpO9EdPlxH@E{;J`o(;Xet{(2f^K~~Ft$HIf=Z?-9pB|wbp$C@i v{81UPakT)0H}|IvS)VnN!W|tL6b>*{OVy1Top ztE-!un##+|dwF@ysp9nT@bLBZEiEl=N{}!xFnE2|^#A|=zvO&L1iH|uB*-rq$R!Oh@CM9y57eFM>EaktaVyEd zg_$RUB}LNVK!8L4^mqZC1l>|vOLwATY;J_UXj{}_wsrsj literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right.png b/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right.png new file mode 100644 index 0000000000000000000000000000000000000000..2705dcb827db708e0052243a19c7b13945ed2b47 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8-T<>lq)RB^hxx;i^MJ32a= znwr|%+pDXqHzi023k&P(>*wd^8yFa@o5=m-lulo+!l%apw|3}noTzJJV)FW7^qpNw z2bO4idU|?!dEGe@aBr{jk@dE|zP=9+tG_;LGPj!3-QE4}Zl!;JG8Q!$&9CDMG%%2m zkT|rKuOf`^|Ns9F&rIhAI!wPL$S)YkB>^x*Ew%U#)Ee#S;uunKE9rtWGmizUgo6X0 zr$daFuV;jur-Qe%Pe`n!r^EDc7snte&xT%KR}XjL-MX8MR=ts#b4TZlPmj=z&;v_$ w{-})DxLSb0oBPv-tk0T{K6CpqHZU+VEM2SCQG4xbI?x&hPgg&ebxsLQ03u_jRR910 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right_wt.png b/AvocadoEdition/plugin/editor/cheditor5/icons/image_align_right_wt.png new file mode 100644 index 0000000000000000000000000000000000000000..16b0cf6d245d39186001536dcdc2e20634a43d07 GIT binary patch literal 454 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8)d4;st{2vcT3T9KTU(o(o7>vjs;jH}`ue)Mx;i^MJ32br z+uO^_%X@ly`uqFOsp1R{4)*f$GBq`IcXtmoFu1cz>A({0rUZ#6r*!V^RX(!bwjzvA zUtfQI9am^*=)XT18z<@p1Oyyf%XfFT(%fp!`uh5H6S;kSeDd@24GatsL@k|NmdhXT!U% zU$uP?)=qo$>HGKA`LC^G@AfSH^z+Xj)9_t|UGM+?`mN7a3+Q_2Zt*VW&C{feo3 zoI2yw?N@*E7EX?wG}|n5&V<7sa#sHD-}is__5XWs{y%Z=wM=-zhKqkX_Z~AW32xea z#&hcbMOS~vEcn0W%Kxj+zZWjwpqZMx{m!fR-~Qiu{r}Os|4yYVf@l4&UU$#2rX{F# z$LjO{58V16I_LkJFJJ!s|8E?6KA`A2(6yg~)^7*;$f+dAFBr(B3^2HefdZ6as;7%% zNX4y~{!qTd0X!^!51olfOM7Jx8UQhHC2BdUrfHR=Vyv-jZObNHzm>ZwHKFFT6Ji09+Y~Y_x5c` zKBr33-r{}c>+UX# Ud+_U9o*)-`y85}Sb4q9e0L%F)H2?qr literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/image_wrap_text.png b/AvocadoEdition/plugin/editor/cheditor5/icons/image_wrap_text.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc2f5a4bb9d2d9e3405c13c47e0f09104667560 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8X#qYVt{2vc+S=M$TU$FjJ3Bf$+S}Wko1443x>{OVy1Top ztE-!un##+|dwF@ysp9nT@bLBZEiEl=N{}!xFnE2|^#A|=zvO&L1iH|uB*-rq$R!Oh@CM9y57eFM>EaktaVyEd zg_$RUB}LNVK!8L4^mqZC1l>|vOLwATY;J_UXj{}_wsrsj literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/magnifier-zoom.png b/AvocadoEdition/plugin/editor/cheditor5/icons/magnifier-zoom.png new file mode 100644 index 0000000000000000000000000000000000000000..77e03059a6845207f6f79e0285f9c4832d21ae18 GIT binary patch literal 2247 zcmaJ@X;>5I8V#$+q96!}h(nOAl7t`x5`hSrut-8Fi|k-X1_+Q$Ohyx+ECS+!RY0m> zFG?*D&`L!R5L6IBkUXpwYr_>OT(+kQ6}h-v#XGTL`{R1&nVD~S&N=VU;fan;BofgMaIhyj5bV*Hgd;jqoJbT0XW-+5 zMWYEh@svQ&>tif*<%Uf}5CMfi5R1il@eVvJOdt@+WU@lT!2yRNaH3Q`!jjVofyE-*4|pb%;>#ByEIu3Z1>LZy0-np|P(0{#CoeMD!PChRtvY>&2i?ONbae6X zAd%^GM^BGcE(o*t^B_L5%H{mU-SJtj!U{YA8X1Iy+yfBDO9=CT4@ahOKc9>JXZ1dE zIiJsk_*pIiO@^Ro?B5!_x`nz&G5us)bn(gf5Fd5B5ViHPC~F3TQQPSYdIU@4Ps3nF zWQalA!r04`hQ{Sv^rCmoT7l8|#2|~KC+ z_`;D6L3(dj%^IQSfutWs&th?FbvKl1JuQ^BYo+(rS2^J9x;LmlG1@(N+WhLj#&%*` zW%X8;wgGhByA?7gzhPV9HRTstBLnW-mz?+w52=LhO+e8 z7|ojAsDL8t1k3RJV`hB9fv^l})5(%6gNNhW4<^1J1=~E&FZmp$N9gUfk(Ulx8OhzV zy=exEr6rX=9;%3%wdv{AsJiH5d9JH7eyX!?S-W7U?ZR8TBDr$mriqffZ#cv^o%f1K zxp@8D<~%j46_@h2_7ye4O?oYh8ee&u#1V7nCJuLe(^sMf+-q(OJ8qoxA8IjJo}npl zgXra~Bk8XiV`EO3TlTw6oTh+>^~4{#+b&-2d35HE zeq9r6byyL*7})q`w=*_X+ktV&%zP%$OJm?Dj#vJGWDu99YdX?b0@=(j*)D>m>#OBc z$tzJwvO25-t+;a|ByF8wgv%^X8Hyu*JM4@{CTq zc0;XxY~1Pgh!f>zK_hDLm;IgAxpmZ`>t=!9$_meQ?5ypI4*!uy0J~qd^gk~#(+=;j z=vegT-xzw;9V;0*l*-WykFyMDx?`)Z(P4K_8T2Am>G`o`l^0cK8jZrUp4VK8SVv2V z`hKfU{>GgR(}(g|DcNRe<*J;U#fzs}@a{l-))U~iu!4`B{C%rR&;CfdtJP*QL#Uol zTNKY2HQYVlFJEaH+c|M#-_ud&*z~z?-oDLwyi2pMepxl6+PC77VOiz*jLVLM-+HQ} zWU?-LAYeRJO#A2D!zZ*6Oxo;d<;$V;!gb8aNY~se^KH>rLM|bp?r9CR(?8doN|Ze6 zV;|2_+X5G7@FR1s_Ryva{efe{{F}BFsxC_+pQ#ACb@K3-&WQuwRL95ZUmO$G)z{~W zDZhV}kwIeyJxJ)8G8xYUBJuiBNtk5U?SW!K!yPR^Jd z&vL%?G;|N`0^OTa31SzuJ?@@}*|Xbzg^_l4@=TVRF~;45yo=#e*rvEz_|pBsTF<>X F{{?ykq2B-i literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/readonlymode.png b/AvocadoEdition/plugin/editor/cheditor5/icons/readonlymode.png new file mode 100644 index 0000000000000000000000000000000000000000..f1c5c2420b5a716fb057a6f49cdcc8106495778f GIT binary patch literal 1983 zcmaJ?dsGv58jWD((F5p85h!9h*vi8^Ax{a}K!^kh&uAhFlEx0Ru6Z7cMJyO!H?snqNA_lab1PJ#|6Vk8aDMhp@yh~da#DTw7OC40eC zP$JLMTmvI97-s+yiV?9OfhmKPc!>jpH!9UA8-s~t8`Tn-0z|M_VWTFB}5RqVw${dxBX=DK}beZVfu}uK5 zFCd751^kwjSdfg3fwdr(f)B^Zh$Ir0O2v~RC{!wGGnPywkqJcfrs7BuObV4rreR-R z02)mz&t|4_c`sw3D;BU1LDWnF!C)}p4dHlLyO%&>Fc=OEG8u;=aJoDdA~E7rx}YTm zE~t}fAvFTQDy&0MB8Bw`3qUjdtpug|m8?ql@|e&ABN!!W0trual(YmC2>w4*seFaj zA*tZ+`TkE~oiI-g5>i1Otk=rW#$^XNLaCWCT2O+(S|JSQES+NVJ{W;@`(QOTCXI>> z7C|aGY|w?gzzYOSzDkEkR5FmyWdW!H9)jddZZwU@rE`dM5;dAciVdeTC>#!hLL|~C zL{c=FzQpCiGQAR1Axm8O?_AQdT!$5uYBVwz)IzzSoTr7A*cT-;p=EPn#4fA%k}F>} z7Y1)xE&)x3;ArfBHF{|ab&q5E%C_j@mGMCp>UJ$^Yk-p;jKQo7=W{ti<7nGyi}Mye=It_<`j$h$rzTSQl-Dl}DRph^XAR|R67~-@ zx<$0Rz2V$me}53b<$NjpW8g*LPsR5r&o_7*JuIc; zx98^SFPE;zxhSkt1s;ytOzjcbT^KP1Ir9HrU<=O%3H&=^w>!6Fndqfvf#|26dW)HT{>`v}l07;1 zR;N4%LPz`KPdpiE@EvT_eBSDHh8BAM+Wnt25+{G&kqS_ zX%Sf+=hrfeR%qtugIk)5!hnDUPZyw^7c`Oel-E&(_;dTb<$u z!`0ajqwep5x1-;?ohpIHbXAqKFbERnTx>9J*;YAUb$Y5*HQ)0U_m-%R_ z2oC?lv14wTb={V}b8kCq6z}AnW1d{>`&atmAN}7YY?Y=|Zj80z0toy{X~H}FCUFIQ z`roRy0!n2~4`vHxVi;#RY8ly4URo<2j*nzmKR&cOD&L#w6FL%O z)~-h$N6QTQn%UWeu~q#~=)CLf(RCR;DScrB`rOkOn%rgI-|Dey`4WBzp#&GQV&tC7 z8WOESW9#|OZ|b`W9%dK}CMsK>(Q$u2(o5gu`dsPO@i*t*QONQ^^g*O6`n`gzh8-s< z&0bfyVpkt0r;T2L(w*E}WLMdwCO)g6altcLd;I6Vna&>;Qcq+BG!(;LGtWD(7xL2l zZ?v^kmUZ@S+MoE^RQFpOh;!L%Mq53s z#lwfQHA%Iij?J+wmd15~3u2Pej-PpK5&)|`4nXlBOc>}l0o;dI!sVv5UjC)}pKx!G zzrq&%;%iAX?asTT?@oHwB<>h+`VsIO|J5f8)8OZmG=$6A?)athV-vY8(OHH60U7Zd ALjV8( literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/remove_col.png b/AvocadoEdition/plugin/editor/cheditor5/icons/remove_col.png new file mode 100644 index 0000000000000000000000000000000000000000..2193adef84b8c5a1ac8458381ec09155f4c6758d GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT)%Ir|Ns9#kOw3M5?ZGLSu7<%e!(C?2d$M~fP4c_ z7srr_TS*DWm?SbZPp~juF`CRN%)lz?*wD$yl8_U`@^MC|&m@(Ovpz|CIRz3J?6sL^ U98o#F1gMw6)78&qol`;+00410$N&HU literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/remove_cols.png b/AvocadoEdition/plugin/editor/cheditor5/icons/remove_cols.png new file mode 100644 index 0000000000000000000000000000000000000000..fdbfcd914d1f2fdbdbc9cfde53da72269fdb1ec0 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT)%Ir|Ns9#kOw3M5?ZGLSu7<%e!(C?2d$M~fP5`a z7srr_TS*DWm?SbZPp~juF`CRN%)lz?*wD$yl8_U`@-kIz<2@D*0|v{L%$?@bQ=b5J OF?hQAxvX&3JhOsGY&n)z4*}Q$iB}r7=3g literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/remove_rows.png b/AvocadoEdition/plugin/editor/cheditor5/icons/remove_rows.png new file mode 100644 index 0000000000000000000000000000000000000000..e2d9588f2491fc5194d23838f1a9f52fe41a07d2 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqJQak|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XcmjMvT)%Ir|Ns9#kOw3M5?ZGLSu7<%e!(C?2d$M~fP8&V z7srr_TS*DWm?SbZPp~juF`CRN%)lz?z%W(CRbchZ9)$*{Nh%#@eUkQa3M4RS`7>9& T)>t_KsFlIf)z4*}Q$iB}v}!os literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/splitter.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/splitter.gif new file mode 100644 index 0000000000000000000000000000000000000000..660bb40df62db15bdd09753b2bd662b5bd08ede2 GIT binary patch literal 177 zcmZ?wbhEHb6ky z0Vx65>Aet+9Gow z4x&p0V%#DjIzvKYCM+mIWOR}OX|z26s>>yF)tMqaW@JK94AW}FDK?EJK5WGyeGx(e`A7k3lF*mhJLmuk zOXxX#HK@krNFjQplt8jevvm5>BE1l%A5I6vRuLs&L`Vp*8c&$aBCCYHsVk!P(Q6hR z*o2Tp68e@?xoQm{#|Q-AGeL$POaXxuHj~ZerKYAP100YIvOo@t&0(-pMO=;u1cB{A zr>qgML8Mh=Y}=wv5_%y?;vyEyVzDqSTqZ^ou-HPOFsi}fFen7WY%`INm0>a;h$$!# zvz|b462(kFR1wO@N=ONv@^mW%BfcYRGH<7eN*K!u;Vd>2jD{2gs@4AuH5zx&W>Skh z_V-_f%{m*7u(XI7D{uk!I;Io ziB_vcDwCOnOnOA6kkBbU6GdT>Knj8!p@1(G@C0nO5|j#fpdbaz5K6fqA5>(-xC%^P zVnj@2j0->JrtHd%Hi8kSEGrNKJ&C{>1ZD&_0~VpX`@-E-Z<`D6?h9{ME{k%86)o#O z${f3*dMCQwXUDx@>atM-^-DZ)NRz2ke!3WG<8XT1?mmxaIS{BxO!NnX zU1MYR!NI_>V?X!zFRZOyb2??tjk(p;Zb*){ft-ajP;F_Eag~JU= zNkdapflw&8vC-sk)LgmJ($llLzP=C)Hg|V_*VcA@Xvliww$QOU;PIq({M9`^-pJ+l zdpuJP$Ar(vzy6?EDlMB?IqkaJ#^u_2?wp+ul-~<2K75$o6CC&XI);ZoS$I^}+&tj* zT5m7S-M|06-9F#j>ogc<#>Psgmv2r@!9)J#VDS9N9}}~)!;_Qu0s+V9==}2X)s7Bv zci@zB_RQe?M}59?H-C3|y}fSt$n^A^ee3nDtuRp>KI#?GliIB8t(*UIrdjyU)>7t1RSK!jdMnTA)^=+4D}AqI*1x`* zsL}iYl09(0Up?)vdGWox%KY)K&(!*7e;IjdOGIOjZHb_qhgt(`f|w$5RAg6Im6fnQGHNP5Cz zT3+9e$v?r;gsfYWcKpV`+ojbLyvB;ES6`}2I=WtWP<8ou;WK%~+&i@h=WLGbptF2d z5O@6ZjJ@SeZ=Ads_Fqb5Cd||?MUEEB^6xUF-?oIG+D{XtiQlQdmNF83lU2$r#Z}n{ G=l%vW5yW2r literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_column.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_column.png new file mode 100644 index 0000000000000000000000000000000000000000..ea515ca894b2c32597aa5f2ac6adb4d5a69b5b79 GIT binary patch literal 1532 zcmcIkeM}o=7_TES%aRFEGnm=ryqdWg+Pn7J(VleB4`7hC!?qKcPAKgG1@5lv9kdXg zk!@xpaWhV*!kp`p>4KA?WQ@<@KIF3y$ASz+M23*bq$5yhX=%LzW&R=l=bOA=Pkz7O z^E~hK z6kMN&X)wL9^iUTT$6|#6CS3-dp;Dp-66flJ7_JRBGi(+sF5YI=8wxQR$iebVgamXp zw}F7kC;`)jDp+NfWBI1NWfn|Zrq&tC3Jqc-7{3RIv!RRtj?sF+h8GbOYLkG=x+rrF znjsKahR}r)a3!b=RT>~CEf^r=!W;v<8wPgsxI9D<8ygz~@L?Vd!F-6v=kQ`tgpa~7 zusT4-o5h%mY7|MUzL=W?%%^EH3PDz@m1{+~q$LmHiN)fe2A|Ji5FDzMp!GHmL9s&$ z3XC#XOlI0d5B?a8PCQDGO&%`_!WYe1=9v2R#6auPL{|&|QH8e$Q zu*dQKt1zW2HDizlqsU^5fhk-rJLt-c$}O0lCM`OWEDF71T0TjWR6c12r8(R#vwr6?pI!{?ezMpP<7FYNh;(C-AHVecF5U&YvAqZei=AfYs{G&aNDBpXi^O z)oA7y7i}ZXlY=ueO66i+UghLm=R?ma1nC$Y>>U_5HsvdA|LvE_N!t%2gZJ+n`&@TN zM-w`|gX81p#(X{;cP1xa0Dyu1{vSt2U74Bk9{+p&4-cO@H8wlj(%Y+W1ezU=!1DOM zJ3-F;99gtRtzEJFUn}c$WmXL1Y9vJ=)!BYlc6S`uAdNV7=M_W^OrE9G<>lgt_s@@> z|Mh?~5LNO{kvnp~_0R_a33uP4rR|e!Mci=T^=~*mO(LfaJgWPY-5hl$z9&5Pb8|&n zD&@s!ukG!U#tgY+f)?^|Sp@~jsQ=1o6o|Len? z^oEyp!ij=sHnc`(PH@=-lyLlTPyNa8jyHTe-+gNTmmlA9M`p8bI%4OFhD4dc|2QR4 Kt*DV@m;Vh$=B+RQ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_row.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_delete_row.png new file mode 100644 index 0000000000000000000000000000000000000000..cb4083c666c83bfb3db4e651ccc69dc5aced8a88 GIT binary patch literal 1562 zcmcgsYfM{Z7_J!xA%QLXVT4F>?EHa|_MG<6mL4dqw8d2^veF1fWt8?53Tsb2J;;GM zrnu=eCd9>M>yXVXSu~6h76Osm7#9h!!nj&4QfRqM#<&eiDHQ4{xA{Z->6d)BH_!9D z@B6)PzHbu~-U;vz_NUQk0n$@qIkg}2&R335YbfJr614>pk`y8d(-65z9Hj}>SUL(w zb;=A>jw;o8pLU>8G};kBt4JYIWbud!(=nA^43pFuC^n526+;@7s%(@1($Ng9UO->0 zYor5OwSb9D(_^B6C=#IrbSR+&NZnbz5g`Ti9bJSv zd(9vn*ntq)0{U)HDY8UBgyAT_VL}WQ#DxGZi^+n+c|2Yiz=l{52(dvHo5A8CFdKm& zU~kYVZ@5~6$i;DczNnjko=Fe}1O#()bD6m?6T>q=7N5`eYOvW13c)bu=?Nvt&>K(e zD~M5}3fCG4Ev5&&ipq2>hY--INOx1v84hIi#=U2v9tU0Na zBOym$#QU$pMn#?h1?8v_%fVGt;WQ__t_+9>N0kJID=_Tr{wpSCVgzQ)#0-Eai322S z^=d5FxPz9-5UJisDD^5-Di+WwK2xhzBSMJ7m2mkSegquOVo4xj1dA_*MXXqe4YP$X zyw4S5svI4vC-%AO7hLY4TyG=j43uXvifcbZ)p0nc19lQdw1>w6AF8*F~Yjbl$cXz+tezEuIpv|Tqbhi%=U-@(Gd&@Gv zY4y^ayJu+V%Nb|kfacip1xaOU!~F1!0@j%HD7eid^NjK-q=W57az_#&Ua4U zsjluBAGZ$-v{@`-vuDHYUT`>^si~&m;2JjDzOqthHWw5Xd3J^`G2-e)8&KU~y4PN$S(E)%QrmR8r8b0PDzk|K5$3D=&{Hf zrGYnD6=$M;tX`Slet#sbBH6Ft8~g|KLxnx0ps?2*@so$sI#>KU#yx(!+;!vacQ1!k e(S1giz=yPtY9v@z^sQ0vZ!MK1h|6Qs3jYR`@7wGE literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_cell.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_cell.png new file mode 100644 index 0000000000000000000000000000000000000000..bc70ca07d159e4ea96739b588704f290741e8014 GIT binary patch literal 1526 zcmcIkYfM{Z7(R2+m`;W+M&06%v*Hh?YkS&KN)ME+rQm94)3uEwQRjL&l*&#|cY0V0 zc$srBAu%|^V!9=6Bbn1l7+QzpX2ZY=r7*@o#{JT*z(%;2u25P}fii!H|NN5g_U3t> z_kF+j%~vFoz8yu`LjeFFN_-_UupQJZGl&dHI;_D^x+;vJTTmm(27sgk7Nbg&jS!$3(di9*>P)Sj z3hK3d>Jg3vk{DBvEd8N898u&+m72V44NprwkPIeSU{U}@2o-2Sj~h&|g->16g~@Z+ z%%Fm65F(pTT@NZlA_G$}9056Wh^B$!AuygvXR_nCT<(651u-E8#9}a6G$t2jvtS4U zHwKmThHEonxhQSJ7kT4Tvk1ZnGZ<#GnQms&F&n z#*J`Am?j5B3`B&headBT$qhFGY9u|25L|x}(Wc=T3a%v#>$i>t+EQSblD^nZ0y6hbtb3UKf@2_uf zZ|LkyX$=;3PQ{jUzMKvnex#18n+b+Ow^~|ioX*6?r8&RfZ+}&>A~Wnuu7_J_kKLKkn0%k zcDtKSwDRj@JJE{_$~VU*8v#%VjoOQj@RGU9GD6p}N}g$B=D!s>|)Rj`&>@cbmGq&)j{)Ygjzkyz;rn_fuWn zCr)?4;{ew_Zyi~7^z_^r9BdyP%o~|I)#hn&x1AgCid>=PKwyuR%BmJld%bmSZDR`y zwJz7EB_*M?@zuF&&yoL!ijYec>z4m-1u9NqOww70SR_zd`rdErk>8fRTri51?L9M; z{~P!Y{ywPSfhj-H*@c9a&e z@*mU&M|qd{aM^BI@}H%)!@8r(dABAW&R@2C-HX;#G`=3~5SXvDv`TJz6Zt&YbLGAA zqxEkI3ir1TtQ09YKYn!K`&Vv=&P}QP;~!FXy&)b8>SVmxUnipb&R>XqCQ5c&_xo#w z+e`!B0#_;NKYtK>VQ;aJQo8d-sNmk^slVRb0aw0y48YIA^X!-APlSJBajH~QAv|{a EZ;bfDr2qf` literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_column.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_insert_column.png new file mode 100644 index 0000000000000000000000000000000000000000..a2f7f5a856d10fce862b3d013efe0b4e9a047381 GIT binary patch literal 1515 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 Gc;au*naoQ7 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_join.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_join.png new file mode 100644 index 0000000000000000000000000000000000000000..a5c0f9db9ada8025525596fc1f9f866ab30553ef GIT binary patch literal 1352 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2v2cW~I!Kh>{3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v)=f4rG*mD%(=#+N zH8V5RQ7|$vG}1Q!A~Rh>6Dw0QDv55FG|-pw6wGYnPFt43sj+7T$xvrSfQI&tPC^3CAB!YD6^m>Ge1uOWMX1cerbuV z640d(FXR@$jm;~D1`{yA^eYkz^bPe4Kwg3=^!3HBG&dKny0|1L72#g21{a4^7NqJ2 zr55Lx79|5CE=?I^Re_arQEFmIeo;t%ehw@Y12XbU@{2R_3lyA#%@j1kGxJjN%ZoL^ z>V18!JoAc667!N%JzZ>-fF|f=W~NvfxjMVLI2o8389Nyp8oC-gIy)LVyEqy;x*3?5 zSQ?wd^t$9Hm*%GCmB93-AoQB!)C)=qxdlL*T~doO%TiO^it=+6z+Se>#O)RnoaRCG zrr>sqDNeomK*#8VA{Hs4VM4&v17gCHEsz6G_^Elo)LsNk)@4)nxdOAqw*a3I*N%7p zPu{w9{Kk!=*RJh3d-lM^i(Rv4fBgCL<+pF&|NPl-@SyF{A5Xq~`S<_-pMU>M_Pk%W zfB%k?CpRBCvU<-RbUZnwKdqNuH=KD|arB{R2_fdeEQ$7KY!kR{hHYP(lYv1+od-yXZ}BZ`t;G~&%4i@ zsq63m|NsBe%05sjv&+-PF{I*F$XQpRLkJnwCK z9d5cQzg_26e7l(vW7@WJv0L|hzB#_ofn}+JbGBi)`|cy(1h}RNn9jHv&Bwm_^qX6e z(t$tr@bEjaIH@?ftml8oWGt`u{q1@IH=m7NUQ18eukzyQmC`SSaD%2=bpj<(qH< Z!;ecQ-+Zp}yaD=x!PC{xWt~$(697vHE64x< literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_join_column.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_join_column.png new file mode 100644 index 0000000000000000000000000000000000000000..830afd95e753e40bb75f7c26cb576bd0ead1ee9e GIT binary patch literal 1419 zcmb_bZA=?w96wz!3ubX~(>dhBc@v$<+PiCMOD_~GJvy4u220IgF2-_wfRpv^xE||^ zo5tzbAnM}Wmw}Fmnkwrv`Ac<@W(=ZIkpg^Hep8{om5I^}O_q_b` z`~Ci}SCM1cy(vB+9zl>zrYzbD&&|F*`9Mr&z09DBe8AGTER87iBWwJ)2*@Y?ylE4WCPAX)ihEgghfaO+bwr1<-AyglUl7ds-aNGAVTKya+2L6<6Jvp3N&yrA}dHN z&!JI8djVf2=`a}SN(xS4O_p=5mI)RN_t*uTloQdEVnDO`zoAa&8rmgU!J~NpRoG?o z3IMkP7hfhauyKVuqOJtWAOgF@i#DF$AFE6LHZOc419+?k^{R0D+dV9x%K|S-w<-WfBcYY0qLX)$z z-GhU=>vI=+dVUWEcUis*FD-=@7gMfGEkz<2eeRp)=JC0?$xtX|@6V?j8eTM>t*Ng+ z)7n~DUES2x)p+gN`S$kFP^jVR)#-(WQ+0LJzAG6$i-CcG+Q!C_>FJkEEoa->@Yin4 zhQrBi6D{4{qcbyOv$LM-Lmxg^P+j`#$n7zGclf>gGgL?LgZ|Of&Y45Q)1ILT_2tQQ z|Ge+sq@y?J?Yisp-#aoEHr!k)zx`+1ty^>;^4rwZ#X#WQzhZ}CtE&h zs%Y9i++0zfl&DF_dOE37#O%`fYcYERTX3~zp>^ZESR`b1+~>#4*lHJVVIP;k5Bu>9^MqQI$_4>)XY2e_}!MNv;ouA2fQ{GqZ Qz$6e;riDJA@z&wL0X6+*!2kdN literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_join_row.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_join_row.png new file mode 100644 index 0000000000000000000000000000000000000000..c77e75c1009d061476dde3f71038fee3a0489abe GIT binary patch literal 1466 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2v2cW`)d{3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v&`mZlGf*%y)H5_T zF*i5YQ7|$vG|)FN(l<2HH8i&}HnK7>P=Ep@plwAdX;wilZcw{`JX@uVl9B=|ef{$C za=mh6z5JqdeM3u2OOP2xM!G;1y2X`wC5aWfdBw^w6I@b@lZ!G7N;32F6hI~>Cgqow z*eU^C3h_d20o>TUVrVb{15Cdnu|VHY&j92lm_lD){7Q3k;i`*Ef>IIg#cFVINM%8) zeo$(0erZuMFyhjbK~@!5ITxiSmgEG&eP`1g19yq1P3sUQj~FEdbi=l3J8mmYU*Ll%J~r_OMkZZnrq$G!Lpb z1-DzAaq86vIz}H9tw_-f69T3k5EGtgfgE_UPt60S^&()RPT}EHXJBAt4e$wZ-E;PA z+od;0uU&IK{jcNQ{{t5I!{9TAE?@rn_wUwY$CO<+&fBoz`=3Aa*Q_~nVeq!v$6rkMerP=RyyoPi%47E{?!7;A=T808Z)W>G+8qAY zdg-;*p|7p4|5O~k*Kp=()$s?-7hcw#esbc*4g2H2svdlFJozW(+}D;@zdwHe{_D@5 zcVEA{ocaIg^XJ`X&eZky{|5u_Fn=Ln2@zfrD+`PD7zrkv6R5 z$MRoT1(+5-et$S&)uM}G;&0jZWTrL?GzxSIEZO_Pa_0(T^=0ec7|OI>Zchr*ln|Df zEaAMVBjI^8$GSC3MCK~ITD#k8b>FAp#XaBW_cJgv%y@0m%06vNBhViVp00i_>zopr E00~@+w*UYD literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/table_split_column.png b/AvocadoEdition/plugin/editor/cheditor5/icons/table_split_column.png new file mode 100644 index 0000000000000000000000000000000000000000..f7dc6c154d46a9fb0b9580c7c97ea82f00503366 GIT binary patch literal 1322 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2v2cW~I!Kh>{3jAFJg2T)jk)8oi3#0-$aN1{?c|g2d$P)DnfH z)bz|eTc!8A_bVx6rr0WloBA5~7C5J7WO`H;r3P2|g(O#HCtIc{+1n}DR9FEG$W1Lt zRH(?!$t$+1uvG$^YXxM3g!Ppaz)DK8ZIvL7itr6kaLzAERWQ{v)=f4rG*mD%(=#+N zH8V5RQ7|$vG}1Q!A~Rh>6Dw0QDv55FG|-pw6wGYnPFt43sj+7T$xvrSfQI&tPC^3CAB!YD6^m>Ge1uOWMX1cerbuV z640d(FXR@$jm;~D1`{yA^eYkz^bPe4Kwg3=^!3HBG&dKny0|1L72#g21{a4^7NqJ2 zr55Lx79|5CE=?I^Re_arQEFmIeo;t%ehw@Y12XbU@{2R_3lyA#%@j1kGxJjN%ZoL^ z>V18!JoAc667!N%JzZ>-fF|f=W~Nw~yBfF{8Ckj*89Nyp8oC-gnK)WF8M(Q+nK@dR zn46oz^t$9Hm*%GCmB93-AoRN8)C)=qxdlL*T~doO%TiO^it=+6z+Se>#O)R*oaRCG zrr>sqGfutwK*#8VA{Hs4VM4&v17gCHEsz6G_^Elo)LsNi*69ad1GB`F0G|-oj(7ic z{5I(ao=9nXkTtbX|N+qXrVH#?pByY<*HtC$1d zzI{7$bxv*F;ump^}g`ThIdj~|4!+v=s;w(U51a@VO-CVSr3KK@ew z^qcA44^_t>RNQ;t`ub1HtKXH!?mM3RlXC8B#nF4s7ham}`&jkhW9y~Y_Q!vH{Qlkf z^uJ$!{(SxU^WE34ZI|BcIeXUS%>SoPpFaBhdH0z!b^ZPS|NpOGZ&?TQ?>bKx$B>F! zA*XJNH3mquJv?ud?!mFJC1B=r&CLAEfA9C#zg4zekEl* r3$Mo2XGvAfpCEVY+2{Vqf1CykZg=%K1I;G4fJ!eeM}p57(T-vLz2ZUSw`kZavaHI(_TMlkM=^>w6sVWMQp2})9BGV;KF)$yB=%l z=F}+!`9l&lnfuV_HsjbLV-krQFh0h|3WdpsOJxfpTXh`>5@<`Iv|bry{vlrO?)Q=B zdEWQ;zE6H17v#URHRs>=;V`YMd@6 zK)n?!C5!}yR~~W^nE;Rgk>(<<$dHFxXe*4xFtEeQ@N59cR5=*TQciGSF;PlVN@%X7 z9Rf*Q2^Go=A_J2}l#w}3mM}T<%@$|5MS(-AePE^o+1AU%7fk5D7@-&z#f}sQ8VvsrwOTjOHqJ;q z&i6lsZRSdb5E=;^UBO!T#+9VTLNRC-OJE$$nrZrAyov>7G)LRYXa>wOAz)e|N#V5J zwr34*Fra$M#$l9&&})?tuK<%Ij>_d4g-ESKBBF#hW7TeO-*`=i$V`Dy_FI9KN7Yc<|SLGcGn*P;y?=4nM zhaD4hnKuHezGe5_yC44Ss~VZU>G2#JxPR0&g?9PhcYBfR^B)ZTS=sxWtnF`n$nWf% zbWYBzUEz-&t~h!o-tz|LgTdu+*dGeb`u$pW)a&(5EiAOS-N)+cqS2@-Nxz@JF9!5l zwb?OlcE5VKs{qgqKlAD2$PV&QVuP;M)Hz;URq6?E(d>NN71=lawe!k_vz1L{kT^o~5dL?e&iA`n>wwdNY;s zCMP}fYsSh#%L}20aP=#r&oPpcQg_c62QGgzfh7Nhj-=dE*W}gY*6helHEydFoLZS# zDiOYHOgXM~r^!z!3Kb`cpX^Sk)66cJ&n0$mpZU_@RO1ahcYS{C`OhdH+yTHEY0lo> RJW1>x)a&xK4Vrh3{{wn6LfHTS literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/title_bar_bg.gif b/AvocadoEdition/plugin/editor/cheditor5/icons/title_bar_bg.gif new file mode 100644 index 0000000000000000000000000000000000000000..13e78660f05a470d14e9baad331f7ac0cb21ca9e GIT binary patch literal 172 zcmZ?wbh9u|lwgoxc+9|X=H8bxx4s+!qHACF0MVs4d(ORCbL`EPM_;Zy`*P>mmoMM` zFdzXP5F4bIfhDovr043nTCdOU{-2;x=9xJ!W7WDfoqGy&&X?rg|H1R7=KcQz3nr9n zNcEpsa`8Zp)%*)-iC$}?*56oDc6zVSz6TpBc;sfBf3cFwhML_WUWzJ5M_{(b?0egQ!NLBWB+AweOb!J%OxVc}sBk>Qb15mC{R(J@gmu`zM+ zG4Tm;2}$vZ$%)CSNhxW`sp-k7X{qU%Dd`!h8JX#s+38u?8Cf}5IeA&Rc{%w73}gWv zkS>s47})+Dm{#DSBh|ZRNzut1v+xTmO1zdXTX$o1*6FuZyH{+e@X?#@|H5R~k-Xja z3wC7st-t+x@g6(>SHJ%^)GIZ&w6?XkD|U7F^!D{BOq?`%%G9ayGiJ`3J!g*G`~?da zEnY0UZ25|nt5(UZUAKP2#*NZjwr<eg)^Y7>7+uPEOVc)QUJ+ zq}nvyAolo8i``TmwywIm zI$|T=jZ<4!Utb^3+9B(`ZB686#!IVWPj6d$dwan{rWxMb*WKM+@%hzNX%+@+0AUL3 A00000 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-background.png b/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-background.png new file mode 100644 index 0000000000000000000000000000000000000000..22de6225b1b6797470833ea5be2f3687017068db GIT binary patch literal 21437 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 HU={LTp8=@F literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png b/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar-wrapper-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..f3c1f7530171b596773a70539e8a0e03fae220d1 GIT binary patch literal 1731 zcmbVNeQXnD7(XafWE30D}dLF6f*i0t*ft0_z{R4I_cwSMLfa8s>W&L;oO{_~vqb-uHgL z=l49%`#kAZNA(LCvlq^WASk1k!~RMbOYkkOBO zF}O11S%cMJ9{+}Qr?FB9k_CcJ7v-{7p*}pM^hg+GEEEB32r4a$MLfQGjDo$`nqb(V z;JUw6z(K!3u|jKC+aqSIE?Ch-V6{!vPG3{Kuf(q?TLzcLP~aehQ64xJY6z2P%%GU? zivn9ZRw>{K2vu)TOa|q$J764_6Hy^bwJH>n@|r-C zR1Nk|7!O2~&J7VvRfCauBjE%05y+h)gW5e@NCJXr(B(uBT#Bc`g8LdnSeUA`7!=@( z(jWArMzz&aWVRqh#U`z_5J8N3z1CvXnzhA6I<-b)oAU8MuEh#q>LQc2$cP};!V+7d z#;iA)Z6>qUgxIuG+{!RXdBQ$yN;fF!PI3z$%0`rS z7{Ex2p@G2yHDCiNmId!5P~drv9vc&YUmhGXEXM*VnjYghZfp#&=@f_+M39mK28&@B zUP7`oO$!n&DT?CmUGXRcP0y~h7@e_%*L~CvI%KvgxvHQ3FAIEpR(sIUCJeYUgi2BYOF?D}o|#&d9;V<#O4% zpKq1VEx&sClJkebWscRiGv?gfvGzcBPwn#Xor`tmPnNVDJD+fUwW_^%nJ#nPhsc&Q z-KG7xZ{0Za8rAXWnZxrE_S&wIqr~9T>u;{!f2s@He#uTHHZJLS&at=VN$gPNBvysZ>7>& KZ8>CeZ}}Tzh2~KJ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar.png b/AvocadoEdition/plugin/editor/cheditor5/icons/toolbar.png new file mode 100644 index 0000000000000000000000000000000000000000..6c81e88250d02abf6a92fed776a0f7037ef5eba6 GIT binary patch literal 13656 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/viewmode_preview.png b/AvocadoEdition/plugin/editor/cheditor5/icons/viewmode_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..bd6df170c067013bae339ace13d842b33d1bc809 GIT binary patch literal 2236 zcmaJ@d0Z1`8V*-Plm(1hLBt_|D+Q8F2!RA5M?yFxf*cZ76hbnPKqeECNJ8qOB9~>W zfLIU_M6ptofTf5EqNvE(1ziuotD+WBil`hSf*q{b{bSwv&CGZFp67Yr_j{i|zCA%3 zd<+fD3@{jsp`R}+7##)Zw?ZF_{ugU=N6^7k;muWqAh8N1PX=K;1xO48_`$q5C>Y`i zk`vn@Hw;DxFAC)c_ z$@wyoR3Snnz?>p42HB=y;L%L~ECH5&mX*jq9TR$BL={g;1PP?MlIDRN&i{wP@MpAK z5e)s6@Bb8*hbBuQVlX5}w#oQt<6^DmLP_aN8N^c{vQPvO&!1wD5K$m-58cA4k05dJn8k|^f6g1@-n7rAp*fTd_;79tw@~-YO+VWfU3@k^BthLSLv1Y{$d18a^hkaz&rntWaKx4X zb8qv~!+q5aIvuy{Okj^A%Z^f8gtyvs%DoO@t6r6zCKd^`zdB}gyFB$csEhNjYb?yt zD_TP}OEAM7g`Y2IzOlUg#ybxy2W@4!?%AzZCKJsY>KkS=M{HgsE^2Kyu^1_MFL8E# z^YC03GP~NbQ&^O-q}MHasJq$d8xu?2h$^bJzT1U|yFtS4AGD*te{jceI4G+iZ^ziW z{+a5{(;GL|t?!v!Axc`+>t<{(kjTs3j5wLhqiJb=(eR})pFEq6e`GSAso-kp-5#Ix{L#I4gH^fF z*uGPXl}CJw)z(hWj!@56+2XQ1jXxCc*k?Z##R$qL9}qya?@6jXcFm62m+~?vvxbTO zB{|kRZ0p9Se##cDq;To5ux`g62A4a$z zJb1ja2wW9bwo|hb4mliKdS%(}_myLPG@` zj9pmcB(b!s0pgwt)@=4Fvu(t6$Hdep4kTr^#78#wnYQEW^ze?Fo&H-e?9$$+J@L;v z?XB*qFN*`h8?lka+ifZ=m%A@b{q=Zi8nBa;k=_-wGQPpw+4lKZj!>{=X;Sx47_?oF zw_?EJ{NVm@zHhqRXj%}zh!uOUyy9OqukDW2*xh~;y8WbmK-%6C*V?3AR&E0Q|3I*~ zc9bs$JZEc&m4b{+pDr z2KAK!HcZ>Zij9mri$5j4gH1nWz&P>qwUC^a_-`Mdy8o>gftoVtP%*O>7p!CTW6>E_ zAts+&^Oebdz1!-6;fhLZqjN~B`)Y1Vmgbk`n&J%q%Il+I8}M&hr4Mtyvs|xYac6tC zIGarmCsdmi`fSRzp=u`|(%R`!*uuqh`#z$?R3Rlj`RV8G_nnFQdsvu5YPfhy<`eo^ zzc-u;HzH_(YY8)6wIAqu^gwHSRipae>)!)Yo}52{x7c50zUIdnrsq^i+4XT|CF9y5y7gP_0#(87Jz(E06T85eKf;{zP_- zj9jW${D?toI}A@*ak1rxnqc)x#)6?9N>iU>&%kW!t>8+3qbHABPacl@cQKpElvwcJ zuN-@IEjchciSF7gk6Mo(sSQ@YB G)IR`M0Hccl literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/icons/watermark.png b/AvocadoEdition/plugin/editor/cheditor5/icons/watermark.png new file mode 100644 index 0000000000000000000000000000000000000000..071fb3fcc215d51dfb5f597491d599b4d28a63ca GIT binary patch literal 13496 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/imageUpload/_common.php b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/_common.php new file mode 100644 index 0000000..9200945 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/imageUpload/config.php b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/config.php new file mode 100644 index 0000000..ac4e495 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/config.php @@ -0,0 +1,71 @@ + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/imageUpload/delete.php b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/delete.php new file mode 100644 index 0000000..0da4fc8 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/delete.php @@ -0,0 +1,49 @@ + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/imageUpload/upload.php b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/upload.php new file mode 100644 index 0000000..73e3700 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/imageUpload/upload.php @@ -0,0 +1,128 @@ + array("imagecreatefromgif", "imagegif"), + "image/jpg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/jpeg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/png" => array("imagecreatefrompng", "imagepng"), + "image/bmp" => array("imagecreatefromwbmp", "imagewbmp") + ); + + // Extracting mime type using getimagesize + try { + $image_info = getimagesize($file_path); + if ($image_info === null) { + //throw new Exception("Invalid image type"); + return false; + } + + $mime_type = $image_info["mime"]; + + if (!array_key_exists($mime_type, $MIME_TYPES_PROCESSORS)) { + //throw new Exception("Invalid image MIME type"); + return false; + } + + $image_from_file = $MIME_TYPES_PROCESSORS[$mime_type][0]; + $image_to_file = $MIME_TYPES_PROCESSORS[$mime_type][1]; + + $reprocessed_image = @$image_from_file($file_path); + + if (!$reprocessed_image) { + //throw new Exception("Unable to create reprocessed image from file"); + return false; + } + + // Calling callback(if set) with path of image as a parameter + if ($callback !== null) { + $callback($reprocessed_image); + } + + // Freeing up memory + imagedestroy($reprocessed_image); + } catch (Exception $e) { + unlink($file_path); + return false; + } + + return true; + } +} + +$is_editor_upload = false; + +$get_nonce = get_session('nonce_'.FT_NONCE_SESSION_KEY); + +if( $get_nonce && ft_nonce_is_valid( $get_nonce, 'cheditor' ) ){ + $is_editor_upload = true; +} + +if( !$is_editor_upload ){ + exit; +} + +//---------------------------------------------------------------------------- +// +// +$tempfile = $_FILES['file']['tmp_name']; +$filename = $_FILES['file']['name']; + +$type = substr($filename, strrpos($filename, ".")+1); +$found = false; +switch ($type) { + case "jpg": + case "jpeg": + case "gif": + case "png": + $found = true; +} + +if ($found != true) { + exit; +} + +// ̸: Ͻú_8 +// 20140327125959_abcdefghi.jpg +// ̸: $_POST["origname"] + +$filename = che_replace_filename($filename); +$savefile = SAVE_DIR . '/' . $filename; + +move_uploaded_file($tempfile, $savefile); +$imgsize = getimagesize($savefile); +$filesize = filesize($savefile); + +if (!$imgsize) { + $filesize = 0; + $random_name = '-ERR'; + unlink($savefile); +}; + +if ( CHE_UPLOAD_IMG_CHECK && ! che_reprocessImage($savefile, null) ){ + $filesize = 0; + $random_name = '-ERR'; + unlink($savefile); +} + +try { + if(defined('G5_FILE_PERMISSION')) chmod($savefile, G5_FILE_PERMISSION); +} catch (Exception $e) { +} + +$rdata = sprintf('{"fileUrl": "%s/%s", "filePath": "%s", "fileName": "%s", "fileSize": "%d" }', + SAVE_URL, + $filename, + $savefile, + $filename, + $filesize ); + +echo $rdata; +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/color_picker.html b/AvocadoEdition/plugin/editor/cheditor5/popup/color_picker.html new file mode 100644 index 0000000..dc972df --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/color_picker.html @@ -0,0 +1,19 @@ + + + +CHEditor + + + + + + + +

    +
    현재 셀 색상:
    +
    + +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/flash.html b/AvocadoEdition/plugin/editor/cheditor5/popup/flash.html new file mode 100644 index 0000000..f0e82b8 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/flash.html @@ -0,0 +1,22 @@ + + + +CHEditor + + + + + + + +
    +
    + <동영상 소스 코드> iframe 또는 object 태그를 입력하세요. +
    + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/flash/ImagePreview.swf b/AvocadoEdition/plugin/editor/cheditor5/popup/flash/ImagePreview.swf new file mode 100644 index 0000000000000000000000000000000000000000..87e4f7558415857f4c7b9507536eaf19b924bff7 GIT binary patch literal 147221 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�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 z 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�QN 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
    ys_faQXjxE@=7{S)C@7i4&kam&u`GN{3_J=^m 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�u92^+f$Z?U2=it6o8S{O2JLc|0Dk$LAUK zv%io3t#?>(bhM~@!$SEEPY``gi@M*m;gQKLp>{`oh* zxcApT{#E)P?j7}w?|kRm-@EO$+rIf-kK!5i!!iFn`Zxc4cly`#>6(fB>R(2U{>4B3 odi1DPjxp+vF{A%gL>~3+TW|Z`t>66icfRGhoyzt90aku9yZOq7fB*mh literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/flash/chximage.swf b/AvocadoEdition/plugin/editor/cheditor5/popup/flash/chximage.swf new file mode 100644 index 0000000000000000000000000000000000000000..f4e11c21c909506561e3a21c651cf5b8c52912bc GIT binary patch literal 63095 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%0Db~~ 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 Op$F>i)L8U8kDejFmPUd+3`QOK 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/google_map.html b/AvocadoEdition/plugin/editor/cheditor5/popup/google_map.html new file mode 100644 index 0000000..5f7ed09 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/google_map.html @@ -0,0 +1,23 @@ + + + + CHEditor + + + + + + + + +
    + 찾을 주소: + + +
    찾으실 도로명 주소, 지번 또는 건물명을 입력하세요.
    +
    +
    +
    +
    + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/icon.html b/AvocadoEdition/plugin/editor/cheditor5/popup/icon.html new file mode 100644 index 0000000..fbddba7 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/icon.html @@ -0,0 +1,15 @@ + + + + CHEditor + + + + + + + +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/image.html b/AvocadoEdition/plugin/editor/cheditor5/popup/image.html new file mode 100644 index 0000000..74df16c --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/image.html @@ -0,0 +1,76 @@ + + + + CHEditor + + + + + + + + +
    +
    +
    + + + + +
    + + +
    +  (사진을 드래그하여 순서를 바꿀 수 있습니다.) + 0장 / 최대 장 사진 +
    +
    +
    +
    +
    사진 정보
    +
    +
    가로: 0
    +
    세로: 0
    +
    이름: 없음
    +
    +
    +
    +
    정렬
    + + + + + + + +
    +
    + +
    +
    + +
    +
    + +
    +
    + 한줄에 한 장씩 넣기 +
    +
    + 사진 여백 넣기 +
    +
    + (전체 사진에 적용됨) +
    + +
    +
    + +
    +
    + +
    +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/image.html5.html b/AvocadoEdition/plugin/editor/cheditor5/popup/image.html5.html new file mode 100644 index 0000000..4ed93ae --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/image.html5.html @@ -0,0 +1,82 @@ + + + + CHEditor + + + + + + + +
    +
    +
    + + + image button + (사진을 점선 안으로 끌어 놓을 수 있습니다.) + 0장 / 최대 장 사진 +
    +
    +
    +
    +
    크기 줄이기
    +
    +
    + 가로: + + 픽셀 + +
    +
    사진 높이는 자동으로 설정됩니다.
    +
    +
    +
    +
    정렬
    +
    + + + + + + +
    +
    + +
    +
    + +
    +
    + +
    +
    + 한줄에 한 장씩 넣기 +
    +
    + 사진 여백 넣기 +
    +
    + (전체 사진에 적용됨) +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/image_url.html b/AvocadoEdition/plugin/editor/cheditor5/popup/image_url.html new file mode 100644 index 0000000..18b76d3 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/image_url.html @@ -0,0 +1,34 @@ + + + + CHEditor + + + + + + + + +
    +
    0 X 0
    +
    +
    사진 URL +
    + +
    +
    +
    +
    레이아웃 +
    +
    + + + +
    +
    +
    +
    +
    + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/AC_OETags.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/AC_OETags.js new file mode 100644 index 0000000..f0bd0d1 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/AC_OETags.js @@ -0,0 +1,247 @@ +// Flash Player Version Detection - Rev 1.5 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +// Modified: chna@chcode.com + +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function errMaxFileSize (MaxFileSize) { + alert("선택하신 파일 크기가 너무 큽니다. 최대 전송 크기는 "+MaxFileSize+" MB 입니다."); +} + +function ControlVersion() +{ + var version = 0; + var axo; +// var e; + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) {} + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + version = "WIN 6,0,21,0"; + axo.AllowScriptAccess = "always"; + version = axo.GetVariable("$version"); + + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) {} + } + + if (!version) + { + try { + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +function GetSwfVer(){ + var flashVer = -1; + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + if ( descArray[3] != "" ) { + tempArrayMinor = descArray[3].split("r"); + } else { + tempArrayMinor = descArray[4].split("r"); + } + var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0; + flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } + else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + var str = ''; + if (isIE && isWin && !isOpera) + { + str += ''; + breakpoint = false; + } + str += ''; + } else { + str += '"); + div.innerHTML = "<" + str.substr(0, pos) + ">"; + embed = div.firstChild; + } else { + div.innerHTML = elem; + object = div.getElementsByTagName('OBJECT')[0]; + if (object && object.hasChildNodes()) { + child = object.firstChild; + movieWidth = (isNaN(object.width) !== true) ? object.width : 320; + movieHeight = (isNaN(object.height) !== true) ? object.height : 240; + + do { + if ((child.nodeName === 'PARAM') && (typeof child.name !== 'undefined') && (typeof child.value !== 'undefined')) { + params.push({key: (child.name == 'movie') ? 'src' : child.name, val: child.value}); + } + child = child.nextSibling; + } while (child); + + if (params.length > 0) { + embed = document.createElement('embed'); + embed.setAttribute("width", movieWidth); + embed.setAttribute("height", movieHeight); + for (i = 0; i < params.length; i++) { + embed.setAttribute(params[i].key, params[i].val); + } + embed.setAttribute("type", "application/x-shockwave-flash"); + } + } + } + + if (embed !== null) { + document.getElementById('fm_player').appendChild(embed); + } +} + +function popupClose() { + document.getElementById('fm_player').innerHTML = ''; + oEditor.popupWinCancel(); +} + +function doSubmit() +{ + var source = String(oEditor.trimSpace(document.getElementById("fm_embed").value)); + if (source === '') { + popupClose(); + } + + if (iframeSource || source.indexOf("iframe") !== -1) { + oEditor.insertHtmlPopup(source); + } else { + oEditor.insertFlash(source); + } + + document.getElementById('fm_player').innerHTML = ''; + oEditor.popupWinClose(); +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/google_map.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/google_map.js new file mode 100644 index 0000000..8bc99eb --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/google_map.js @@ -0,0 +1,143 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +var oEditor = null, + centerLat = 0, + centerLng = 0, + latlng = 0, + setZoom = 14, + marker_lat = 0, + marker_lng = 0, + mapType = "roadmap", + map, + mapWidth = 512, + mapHeight = 320, + panorama, + panoramaVisible = false; + +function doSubmit() { + var mapImg = document.createElement("img"), + panoramaPitch, panoramaHeading, panoramaZoom, panoramaPosition; + + if (marker_lat === 0) { + marker_lat = centerLat; + } + if (marker_lng === 0) { + marker_lng = centerLng; + } + + mapImg.style.width = mapWidth + 'px'; + mapImg.style.height = mapHeight + 'px'; + mapImg.style.border = '1px #000 solid'; + mapImg.setAttribute("alt", "Google Map"); + mapImg.onload = function () { + oEditor.insertHtmlPopup(mapImg); + oEditor.setImageEvent(true); + oEditor.popupWinClose(); + }; + + if (panoramaVisible) { + panoramaPitch = panorama.getPov().pitch; + panoramaHeading = panorama.getPov().heading; + panoramaZoom = panorama.getPov().zoom; + panoramaPosition = panorama.getPosition(); + + mapImg.src = "http://maps.googleapis.com/maps/api/streetview?location=" + panoramaPosition + + "&pitch=" + panoramaPitch + + "&heading=" + panoramaHeading + + "&size=" + mapWidth + 'x' + mapHeight + + "&zoom=" + panoramaZoom + + "&sensor=false" + + "®ion=KR"; + } else { + mapImg.src = "http://maps.google.com/maps/api/staticmap?center=" + centerLat + ',' + centerLng + + "&zoom=" + setZoom + + "&size=" + mapWidth + 'x' + mapHeight + + "&maptype=" + mapType + + //"&markers=" + marker_lat + ',' + marker_lng + + "&sensor=false" + + "&language=ko" + + "®ion=KR"; + } +} + +function searchAddress() { + var address = document.getElementById('fm_address').value, + geocoder = new google.maps.Geocoder(); + //var results, status; + //var marker = new google.maps.Marker({ 'map': map, 'draggable': true }); + + geocoder.geocode({'address' : address}, + function (results, status) { + if (status === google.maps.GeocoderStatus.OK) { + centerLat = results[0].geometry.location.lat(); + centerLng = results[0].geometry.location.lng(); + latlng = new google.maps.LatLng(centerLat, centerLng); + map.setCenter(latlng); + map.setZoom(setZoom); + } + }); +} + +function initMap(zoom) { + var mapOptions = { + zoom: zoom || setZoom, + panControl: true, + zoomControl: true, + scaleControl: true, + center: new google.maps.LatLng(37.566, 126.977), + disableDefaultUI: false, + streetViewControl: true, + mapTypeId: google.maps.MapTypeId.ROADMAP + }; + + map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions); + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + + google.maps.event.addListener(map, 'dragend', function () { + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + }); + + google.maps.event.addListener(map, 'maptypeid_changed', function () { + mapType = map.getMapTypeId(); + }); + + google.maps.event.addListener(map, 'zoom_changed', function () { + centerLat = map.getCenter().lat(); + centerLng = map.getCenter().lng(); + }); + + panorama = map.getStreetView(); + google.maps.event.addListener(panorama, 'visible_changed', function () { + panoramaVisible = panorama.getVisible(); + }); +} + +function popupClose() { + oEditor.popupWinCancel(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor), + button = [ + { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } + ], + buttonUrl = oEditor.config.iconPath + 'button/map_address.gif', + search = new Image(); + + dlg.showButton(button); + + search.src = buttonUrl; + search.onclick = function () { + searchAddress(); + }; + search.className = 'button'; + document.getElementById('map_search').appendChild(search); + dlg.setDialogHeight(); +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/icon.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/icon.js new file mode 100644 index 0000000..a90850f --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/icon.js @@ -0,0 +1,54 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var oEditor = null; + +function popupClose() { + oEditor.popupWinCancel(); +} + +function insertIcon() { + this.removeAttribute("className"); + this.removeAttribute("class"); + this.style.margin = '1px 4px'; + oEditor.insertHtmlPopup(this.cloneNode(false)); + oEditor.popupWinClose(); +} + +function showContents() { + var block = document.getElementById('iconBlock'), + path = oEditor.config.iconPath + 'em/', + num = 80, i, br, img; + + for (i = 40; i < num; i++) { + if (i > 40 && (i % 10) === 0) { + br = document.createElement('br'); + block.appendChild(br); + } + + img = new Image(); + img.src = path + (i + 1) + ".gif"; + img.style.width = '16px'; + img.style.height = '16px'; + img.style.margin = '5px 4px'; + img.style.verticalAlign = 'middle'; + img.setAttribute('alt', 'Emotion Icon'); + img.setAttribute('border', "0"); + img.className = 'handCursor'; + img.onclick = insertIcon; + block.appendChild(img); + } +} + +function init(dialog) { + var button, dlg; + + oEditor = this; + oEditor.dialog = dialog; + button = [{ alt : "", img : 'cancel.gif', cmd : popupClose }]; + + dlg = new Dialog(oEditor); + showContents(); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.html5.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.html5.js new file mode 100644 index 0000000..10b67ce --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.html5.js @@ -0,0 +1,1348 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var activeImage = null, + browser = null, + button, + debug = false, + destinationObject = null, + divHeight = [], + divWidth = [], + divXPositions = [], + divYPositions = [], + dragDropDiv, + eventDiff_x = 0, + eventDiff_y = 0, + fileTypeRe = /^image\/(png|jpeg|gif)$/i, + geckoOffsetX_marker = -3, + geckoOffsetY_marker = -1, + imageCompleted = 0, + imageCompletedList = [], + imageListWrapper, + imageResizeInput, + imageResizeWidth = 0, + insertionMarker, + inputFileName = 'file', + modifyImages = [], + moveTimer = -1, + oEditor = null, + offsetX_marker = -3, + offsetY_marker = -3, + readyToMove = false, + selectedFilesNum = 0, + showThumbnailSize = { width: 120, height: 90 }, + tmpLeft = 0, + tmpTop = 0, + uploadImagePath = '', + uploadMaxNumber = 12, + uploadScript; +// deleteScript; + +function createInsertionMaker() { + var wrapper = document.getElementById('insertionMarker'), + topIco = new Image(), + middleIco = new Image(), + bottomIco = new Image(); + + topIco.src = uploadImagePath + '/marker_top.gif'; + topIco.style.width = '6px'; + topIco.style.height = '1px'; + wrapper.appendChild(topIco); + + middleIco.src = uploadImagePath + '/marker_middle.gif'; + middleIco.style.height = '96px'; + middleIco.style.width = '6px'; + wrapper.appendChild(middleIco); + + bottomIco.src = uploadImagePath + '/marker_bottom.gif'; + bottomIco.style.width = '6px'; + bottomIco.style.height = '1px'; + wrapper.appendChild(bottomIco); +} + +function popupClose() { + oEditor.popupWinCancel(); +} + +function showContents() { + var spacer = function (id) { + var clear = document.createElement('div'); + clear.style.height = '0px'; + clear.style.width = '0px'; + clear.className = 'clear'; + clear.id = 'spacer' + id; + return clear; + }, + spacerNo = 1, i, imgBox, theImg, lastSpacer; + + for (i = 0; i < uploadMaxNumber; i++) { + if (i > 0 && ((i % 4) === 0)) { + imageListWrapper.appendChild(spacer(spacerNo++)); + } + + imgBox = document.createElement('div'); + imgBox.id = 'imgBox' + i; + imgBox.className = 'imageBox'; + theImg = document.createElement('div'); + theImg.id = 'img_' + i; + theImg.className = 'imageBox_theImage'; + imgBox.appendChild(theImg); + + imageListWrapper.appendChild(imgBox); + if (i === (uploadMaxNumber - 1)) { + lastSpacer = spacer(spacerNo); + lastSpacer.style.height = "7px"; + imageListWrapper.appendChild(lastSpacer); + } + } + + imageListWrapper.style.padding = '5px 7px 0px 5px'; + document.getElementById('imageInfoBox').style.height = '298px'; + document.getElementById('imageInfoBox').style.width = '130px'; +} + +function setImageCount() { + imageCompleted++; + document.getElementById('imageCount').innerHTML = imageCompleted.toString(); +} + +function getImageCount() { + return imageCompleted; +} + +function allowedMaxImage() { + return uploadMaxNumber - getImageCount(); +} + +function getUploadedCount() { + return imageListWrapper.getElementsByTagName('img').length; +} + +function uploadedImageCount() { + imageCompleted = getUploadedCount(); + document.getElementById('imageCount').innerHTML = imageCompleted.toString(); +} + +function getTopPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetTop; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.tagName.toLowerCase() !== 'html') { + returnValue += (inputObj.offsetTop - inputObj.scrollTop); + if (browser.msie) { + returnValue += inputObj.clientTop; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getLeftPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetLeft; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.id !== 'imageListWrapper') { + returnValue += inputObj.offsetLeft; + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getDivCoordinates() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('DIV'), + i = 0; + + for (; i < imgBox.length; i++) { + if ((imgBox[i].className === 'imageBox' || imgBox[i].className === 'imageBoxHighlighted') && imgBox[i].id) { + divXPositions[imgBox[i].id] = getLeftPos(imgBox[i]); + divYPositions[imgBox[i].id] = getTopPos(imgBox[i]); + divWidth[imgBox[i].id] = imgBox[i].offsetWidth; + divHeight[imgBox[i].id] = imgBox[i].offsetHeight; + } + } +} + +function reOrder() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('div'), + imgNum = 0, i, spacer, breakline = []; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].id.indexOf('imgBox') === -1) { + continue; + } + + imgBox[i].className = 'imageBox'; + imgBox[i].firstChild.className = 'imageBox_theImage'; + + if (imgNum > 0 && (imgNum % 4) === 0) { + breakline.push(imgBox[i].id); + } + + imgNum++; + } + + for (i = 0; i < breakline.length; i++) { + spacer = document.getElementById('spacer' + (i + 1)); + if (i + 1 === breakline.length) { + imageListWrapper.appendChild(spacer); + } else { + imageListWrapper.insertBefore(spacer, document.getElementById(breakline[i])); + } + } +} + +function img_delete_post(el){ + if( el.firstChild.tagName.toLowerCase() === 'img' ){ + var src = el.firstChild.getAttribute('src'), + filesrc = src.replace(/^.*[\\\/]/, ''), + data = "filesrc="+filesrc; + + var xhr = new XMLHttpRequest(); + xhr.open('POST', deleteScript, true); + //Send the proper header information along with the request + xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + + xhr.addEventListener("error", function (evt) { + try { + console.log("파일 전송 중 오류: " + evt.target.error.code); + } catch(ex) { + } + }, false); + + xhr.send(data); + } +} + +function showDelete() { + var self = this, btn; + + if (readyToMove) { + return; + } + + getDivCoordinates(); + self.className = 'imageBox_theImage_over'; + btn = document.getElementById('removeImageButton'); + btn.style.left = (showThumbnailSize.width - parseInt(btn.style.width, 10) - 1) + 'px'; + btn.style.top = '-1px'; + + self.appendChild(btn); + btn.style.display = 'block'; + + btn.onmouseover = function (ev) { + oEditor.stopEvent(ev); + this.style.display = 'block'; + this.className = 'removeButton_over'; + self.className = 'imageBox_theImage_over'; + }; + btn.onmouseout = function () { + this.className = 'removeButton'; + }; + btn.onmousedown = function (ev) { + var images = self.getElementsByTagName('img'), i, moveobj, target; + + for (i = 0; i < images.length; i++) { + img_delete_post(self); + self.removeChild(images[i]); + } + + self.removeChild(self.firstChild); + self.className = 'imageBox_theImage'; + + if (self.parentNode.nextSibling && self.parentNode.nextSibling.id) { + moveobj = self.parentNode.nextSibling; + target = self.parentNode; + + while (moveobj !== null) { + if (moveobj.firstChild && !moveobj.firstChild.firstChild) { + break; + } + if (/^spacer/.test(moveobj.id)) { + moveobj = moveobj.nextSibling; + continue; + } + imageListWrapper.insertBefore(moveobj, target); + moveobj = target.nextSibling; + } + } + + reOrder(); + uploadedImageCount(); + this.style.display = 'none'; + document.body.appendChild(ev.target); + oEditor.removeEvent(self, 'mouseover', showDelete); + }; +} + +function hideDelete() { + // ---------------------------------------------------------------------------------- + document.getElementById('removeImageButton').style.display = 'none'; +} + +function startUpload(list) { + // ---------------------------------------------------------------------------------- + var el = imageListWrapper.getElementsByTagName('div'), i, imgBox, + count = 0, len = list.length; + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + if (count === len) { + break; + } + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + imgBox.style.backgroundImage = "url('" + uploadImagePath + "/loader.gif')"; + list[count++].boxElem = imgBox; + } + } +} + +function fileFilterError(file) { + alert("선택하신 '" + file + "' 파일은 전송할 수 없습니다.\n" + + "gif, png, jpg 사진 파일만 전송할 수 있습니다."); +} + +function imgComplete(img, imgSize, boxId) { + var resizeW, resizeH, M, elem; + img.setAttribute("border", '0'); + + if (imgSize.width > showThumbnailSize.width || imgSize.height > showThumbnailSize.height) { + if (imgSize.width > imgSize.height) { + resizeW = (imgSize.width > showThumbnailSize.width) ? showThumbnailSize.width : imgSize.width; + resizeH = Math.round((imgSize.height * resizeW) / imgSize.width); + } else { + resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height; + resizeW = Math.round((imgSize.width * resizeH) / imgSize.height); + } + + if (resizeH > showThumbnailSize.height) { + resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height; + resizeW = Math.round((imgSize.width * resizeH) / imgSize.height); + } + + } else { + resizeW = imgSize.width; + resizeH = imgSize.height; + } + + img.style.width = resizeW - 2 + 'px'; + img.style.height = resizeH - 2 + 'px'; + img.style.margin = "1px"; + + if (resizeW < showThumbnailSize.width) { + M = showThumbnailSize.width - resizeW; + img.style.marginLeft = Math.round(M / 2) + 'px'; + } + + if (resizeH < showThumbnailSize.height) { + M = showThumbnailSize.height - resizeH; + img.style.marginTop = Math.round(M / 2) + 'px'; + } + + elem = document.getElementById(boxId); + boxId = boxId.replace(/img_/, ''); + + if (boxId % 12 === 0) { + imageListWrapper.scrollTop = elem.offsetTop - 6; + } + + elem.style.backgroundImage = "url('" + uploadImagePath + "/dot.gif')"; + oEditor.addEvent(elem, 'mouseover', showDelete); + elem.onmouseout = function () { + this.className = 'imageBox_theImage'; + hideDelete(); + }; + + setImageCount(); +} + +function showUploadWindow() { + // ---------------------------------------------------------------------------------- + var uploadWindow = document.getElementById("uploadWindow"), + uploadWindowWidth = 700, + winWidth, el, i, j, imgBox, img; + + if (!(oEditor.undefined(window.innerWidth))) { + winWidth = window.innerWidth; + } else if (document.documentElement && + (!(oEditor.undefined(document.documentElement.clientWidth))) && + document.documentElement.clientWidth !== 0) { + winWidth = document.documentElement.clientWidth; + } else if (document.body && (!(oEditor.undefined(document.body.clientWidth)))) { + winWidth = document.body.clientWidth; + } else { + alert('현재 브라우저를 지원하지 않습니다.'); + return; + } + + uploadWindow.style.left = winWidth / 2 - (uploadWindowWidth / 2) + 'px'; + uploadWindow.style.display = "block"; + uploadWindow.style.width = uploadWindowWidth + 'px'; + + if (modifyImages.length > 0) { + el = imageListWrapper.getElementsByTagName('div'); + for (i = 0; i < modifyImages.length; i++) { + if (i > 7) { + break; + } + + for (j = 0; j < el.length; j++) { + imgBox = el[j]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (imgBox.firstChild && (imgBox.firstChild.src === modifyImages[i])) { + break; + } + + if (imgBox.firstChild === null) { + img = new Image(); + img.src = modifyImages[i]; + img.border = 0; + img.alt = ''; + img.style.width = '120px'; + img.style.height = '90px'; + imgBox.appendChild(img); + break; + } + } + } + } +} + +function removeImages() { + var images = [], i, j, theImage, img, remove; + document.body.appendChild(document.getElementById('removeImageButton')); + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + images.push(theImage); + } + } + + for (i = 0; i < images.length; i++) { + img = images[i]; + if (img.firstChild !== null) { + oEditor.removeEvent(img, 'mouseover', showDelete); + remove = img.getElementsByTagName('img'); + + for (j = 0; j < remove.length; j++) { + img_delete_post(img); + img.removeChild(remove[j]); + } + + img.parentNode.className = 'imageBox'; + oEditor.removeEvent(img, 'mouseover', showDelete); + } + } + uploadedImageCount(); + imageCompletedList = []; +} + +function removeImage() { + // ---------------------------------------------------------------------------------- + var i, theImage, found = false; + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + found = true; + break; + } + } + + if (found) { + if (!confirm('추가하신 사진이 있습니다. 사진 넣기를 취소하시겠습니까?')) { + return false; + } + removeImages(); + } + + return true; +} + +function closeWindow() { + // ---------------------------------------------------------------------------------- + if (removeImage()) { + popupClose(); + } +} + +function cancelEvent() { + // ---------------------------------------------------------------------------------- + return false; +} + +function startMoveTimer() { + // ---------------------------------------------------------------------------------- + var subElements, newDiv; + + if (moveTimer >= 0 && moveTimer < 10) { + moveTimer++; + setTimeout('startMoveTimer()', 8); + } + + if (moveTimer === 5) { + getDivCoordinates(); + subElements = dragDropDiv.getElementsByTagName('div'); + if (subElements.length > 0) { + dragDropDiv.removeChild(subElements[0]); + } + + dragDropDiv.style.display = 'block'; + newDiv = activeImage.cloneNode(true); + newDiv.className = 'imageBox'; + newDiv.style.opacity = 0.5; + + newDiv.id = ''; + newDiv.style.padding = '2px'; + dragDropDiv.appendChild(newDiv); + + dragDropDiv.style.top = tmpTop + 'px'; + dragDropDiv.style.left = tmpLeft + 'px'; + } + + return false; +} + +function getMouseButtn(e) { + var code; + e = e || window.event; + code = e.button; + + if (code) { + if (browser.msie && browser.version < 9) { + code = code === 1 ? 0 : (code === 4 ? 1 : code); + } + } + + return code; +} + +function selectImage(e) { + // ---------------------------------------------------------------------------------- + var el = this.parentNode.firstChild.firstChild, obj; + + if (!el) { + return; + } + + e = e || window.event; + if (getMouseButtn(e) === 2) { + return; + } + + obj = this.parentNode; + hideDelete(); + + obj.className = 'imageBoxHighlighted'; + activeImage = obj; + readyToMove = true; + moveTimer = 0; + + tmpLeft = e.clientX + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + tmpTop = e.clientY + Math.max(document.body.scrollTop, document.documentElement.scrollTop); + + startMoveTimer(); + return false; +} + +function dragDropEnd() { + // ---------------------------------------------------------------------------------- + var parentObj, chkObj, turn = false; + + readyToMove = false; + moveTimer = -1; + dragDropDiv.style.display = 'none'; + insertionMarker.style.display = 'none'; + + if (!activeImage) { + return; + } + + if (destinationObject && destinationObject !== activeImage) { + parentObj = destinationObject.parentNode; + chkObj = destinationObject.previousSibling; + turn = false; + + if (chkObj === null) { + chkObj = imageListWrapper.firstChild; + turn = true; + } + + if (chkObj.id.indexOf('spacer') !== -1) { + chkObj = chkObj.previousSibling; + } + + if (chkObj.firstChild.firstChild === null) { + reOrder(); + return; + } + + if (chkObj && chkObj.id !== null) { + while (chkObj) { + if (chkObj.firstChild.firstChild !== null) { + break; + } + chkObj = chkObj.previousSibling; + } + destinationObject = turn ? chkObj : chkObj.nextSibling; + } + + parentObj.insertBefore(activeImage, destinationObject); + reOrder(); + + activeImage = null; + destinationObject = null; + getDivCoordinates(); + + return false; + } + + activeImage.className = "imageBox"; + return true; +} + +function dragDropMove(e) { + // ---------------------------------------------------------------------------------- + var elementFound = false, prop, offsetX, offsetY, leftPos, topPos; + + if (moveTimer === -1 || !readyToMove) { + return; + } + + e = e || window.event; + + leftPos = e.clientX + document.documentElement.scrollLeft - eventDiff_x; + topPos = e.clientY + document.documentElement.scrollTop - eventDiff_y; + + dragDropDiv.style.top = topPos + 'px'; + dragDropDiv.style.left = leftPos + 'px'; + + leftPos = leftPos + eventDiff_x; + topPos = topPos + eventDiff_y; + + if (getMouseButtn(e) !== 0) { + dragDropEnd(); + } + + for (prop in divXPositions) { + if (!divXPositions.hasOwnProperty(prop) || divXPositions[prop].className === 'clear') { + continue; + } + + if (divXPositions[prop] < leftPos && + (divXPositions[prop] + divWidth[prop] * 0.7) > leftPos && + divYPositions[prop] < topPos && + (divYPositions[prop] + divWidth[prop]) > topPos) { + if (browser.msie) { + offsetX = offsetX_marker; + offsetY = offsetY_marker; + } else { + offsetX = geckoOffsetX_marker; + offsetY = geckoOffsetY_marker; + } + + insertionMarker.style.top = divYPositions[prop] + offsetY + 'px'; + insertionMarker.style.left = divXPositions[prop] + offsetX + 'px'; + insertionMarker.style.display = 'block'; + destinationObject = document.getElementById(prop); + elementFound = true; + break; + } + } + + if (!elementFound) { + insertionMarker.style.display = 'none'; + destinationObject = false; + } + + return false; +} + +function initGallery() { + // ---------------------------------------------------------------------------------- + var imgBox = imageListWrapper.getElementsByTagName('div'), + i; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].className === 'imageBox_theImage') { + imgBox[i].onmousedown = selectImage; + } + } + + document.body.onselectstart = cancelEvent; + document.body.ondragstart = cancelEvent; + document.body.onmouseup = dragDropEnd; + document.body.onmousemove = dragDropMove; + + dragDropDiv = document.getElementById('dragDropContent'); + insertionMarker = document.getElementById('insertionMarker'); + getDivCoordinates(); +} + +function doSubmit() { + // ---------------------------------------------------------------------------------- + var el = imageListWrapper.getElementsByTagName('div'), + imageArray = [], + num = 0, + elem = document.getElementById('id_alignment').elements, + imgParagraph = false, + useSpacer = false, + imgAlign = 'top', i, imgBox, input; + + for (i = 0; i < elem.length; i++) { + input = elem[i]; + switch (input.name) { + case "alignment" : + if (input.checked) { + imgAlign = input.value; + } + break; + case "para" : + imgParagraph = input.checked; + break; + case "use_spacer" : + useSpacer = input.checked; + break; + } + } + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== "imageBox_theImage") { + continue; + } + + if (imgBox.firstChild !== null) { + imageArray[num] = imageCompletedList[imgBox.id]; + + if (imgAlign === "break") { + imageArray[num].alt = "break"; + } else { + imageArray[num].alt = ''; + imageArray[num].align = imgAlign; + } + + num++; + } + } + + if (imageArray.length > 0) { + oEditor.doInsertImage(imageArray, imgParagraph, useSpacer); + } + oEditor.popupWinClose(); +} + +function selectedFiles(evt) { + var upload = new DoUpload(), + files = evt.target.files || []; + + oEditor.stopEvent(evt); + if (files) { + upload.select(files); + } +} + +function DoUpload() { + this.list = []; + this.reader = new FileReader(); + this.URL = window.URL || window.webkitURL; + + this.reader.onprogress = null; + this.reader.onloadstart = null; + this.reader.onabort = null; + this.reader.onerror = null; + + this.MyBlob = (function () { + var key, blob, self = this; + function MYBLOB(blob) { + var url = null; + this.blob = blob; + blob = null; + + this.getURL = function () { + if (url) { + return url; + } + url = self.URL.createObjectURL(this.blob); + return url; + }; + this.dispose = function () { + if (url) { + url = self.URL.revokeObjectURL(url); + } + if (typeof this.blob.msClose !== 'undefined') { + this.blob.msClose(); + } + this.blob = null; + if (debug) { + console.log("Blob Data Clear"); + } + }; + } + + blob = new Blob(); + for (key in blob) { + if (blob.hasOwnProperty(key)) { + (function (key) { + Object.defineProperty(MYBLOB.prototype, + key, + { + enumerable: true, + configurable: true, + get: function () { + return this.blob[key]; + } + } + ); + }(key)); + } + } + + key = undefined; + return MYBLOB; + }()); + + return this; +} + +DoUpload.prototype = { + select: function (files) { + var self = this, + num = files.length, + i = 0, + file = null; + + if (num > allowedMaxImage()) { + num = allowedMaxImage(); + } + + for (; i < num; i++) { + file = files[i]; + + if (!file.type.match(fileTypeRe)) { + fileFilterError(file.name); + continue; + } + this.list.push(file); + } + + if (this.list.length < 1) { + return; + } + + this.reader.addEventListener("error", function (evt) { + self.onReadDataErrorHandler(evt); + }, false); + + this.reader.onloadend = function (evt) { + self.dataLoadHandler(evt); + }; + + setResizeWidth(); + startUpload(this.list); + + this.load(); + }, + + getDateTime : function () { + var date = new Date(), + year = date.getFullYear(), + month = date.getMonth() + 1, + day = date.getDate(), + hours = date.getHours(), + minutes = date.getMinutes(), + seconds = date.getSeconds(); + + return String(10000 * year + 100 * month + day + + ('0' + hours).slice(-2) + ('0' + minutes).slice(-2) + ('0' + seconds).slice(-2)); + }, + + makeFilename : function (type) { + var chars = "abcdefghiklmnopqrstuvwxyz", + len = 8, clen = chars.length, rData = '', i, rnum; + + for (i = 0; i < len; i++) { + rnum = Math.floor(Math.random() * clen); + rData += chars.substring(rnum, rnum + 1); + } + + if (type !== '') { + rData += type.toLowerCase(); + } + + return this.getDateTime() + '_' + rData; + }, + + getOrientation : function (data) { + var view = new DataView(data), + length = view.byteLength, + offset = 2, + marker, little, tags, i; + + if (view.getUint16(0, false) !== 0xffd8) { + return -2; + } + + while (offset < length) { + marker = view.getUint16(offset, false); + offset += 2; + + if (marker === 0xffe1) { + if (view.getUint32(offset += 2, false) !== 0x45786966) { + return -1; + } + + little = view.getUint16(offset += 6, false) === 0x4949; + offset += view.getUint32(offset + 4, little); + tags = view.getUint16(offset, little); + offset += 2; + + for (i = 0; i < tags; i++) { + if (view.getUint16(offset + (i * 12), little) === 0x0112) { + return view.getUint16(offset + (i * 12) + 8, little); + } + } + } else if ((marker & 0xff00) !== 0xff00) { + break; + } else { + offset += view.getUint16(offset, false); + } + } + + return -1; + }, + + NewBlob : function (data, datatype) { + var blob = null, blobb; + try { + blob = new Blob([data], {type: datatype}); + } catch (e) { + window.BlobBuilder = window.BlobBuilder + || window.WebKitBlobBuilder + || window.MozBlobBuilder + || window.MSBlobBuilder; + + if (e.name === 'TypeError' && window.BlobBuilder) { + blobb = new BlobBuilder(); + blobb.append(data); + blob = blobb.getBlob(datatype); + console.log("TypeError"); + } else if (e.name === "InvalidStateError") { + console.log("InvalidStateError"); + } else { + console.log("Error"); + } + } + return blob; + }, + + imageResize : function (image, filetype, resizeWidth, orientation, addWaterMark) { + var canvas = document.createElement("canvas"), + width = image.width, + height = image.height, + bitmapData, ctx, rotateImg, rotateW, rotateH, angle, step, offcanvas, offctx, dHeight, dWidth; + + + + // 카메라를 돌려서 찍은 경우, 높이를 가로 사이즈로 정한 다음 리사이징 처리. 이 경우, 파일 크기와 처리 속도가 + // 증가한다. + + // if (orientation === 6 || orientation === 8) { + // var ratio = resizeWidth / height; + // dHeight = height * ratio; + // dWidth = width * ratio; + // } else { + dHeight = Math.ceil(resizeWidth / width * height); + dWidth = resizeWidth; + // } + + canvas.width = dWidth; + canvas.height = dHeight; + ctx = canvas.getContext("2d"); + + step = Math.ceil(Math.log(image.width / resizeWidth) / Math.log(2)); + + if (step > 1) { + offcanvas = document.createElement('canvas'); + offctx = offcanvas.getContext('2d'); + offcanvas.width = width / 2; + offcanvas.height = height / 2; + + offctx.drawImage(image, 0, 0, offcanvas.width, offcanvas.height); + offctx.drawImage(offcanvas, 0, 0, offcanvas.width / 2, offcanvas.height / 2); + ctx.drawImage(offcanvas, 0, 0, offcanvas.width / 2, offcanvas.height / 2, 0, 0, dWidth, dHeight); + } else { + ctx.drawImage(image, 0, 0, dWidth, dHeight); + } + + if (orientation === 6 || orientation === 8 || orientation === 3) { + angle = orientation === 6 ? Math.PI / 2 : (orientation === 8 ? -Math.PI / 2 : 180 * Math.PI / 2); + bitmapData = canvas.toDataURL(filetype, oEditor.config.imgJpegQuality); + + rotateImg = new Image(); + rotateImg.src = bitmapData; + rotateW = orientation !== 3 ? dHeight : dWidth; + rotateH = orientation !== 3 ? dWidth : dHeight; + + canvas.width = rotateW; + canvas.height = rotateH; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.save(); + ctx.translate(canvas.width / 2, canvas.height / 2); + ctx.rotate(angle); + ctx.drawImage(rotateImg, -dWidth / 2, -dHeight / 2); + ctx.restore(); + } + + if (this.reader.watermark && addWaterMark) { + ctx.globalAlpha = oEditor.config.imgWaterMarkAlpha; + ctx.drawImage(this.reader.watermark, + canvas.width - this.reader.watermark.width, canvas.height - this.reader.watermark.height); + } + return canvas.toDataURL(filetype, oEditor.config.imgJpegQuality); + }, + + canvasToBlob : function (bitmapData, mimetype) { + var raw = atob(bitmapData.split(',')[1]), + intArray = [], + len = bitmapData.length, + i = 0; + + for (; i < len; i++) { + intArray.push(raw.charCodeAt(i)); + } + return new Blob([new Uint8Array(intArray)], {type: mimetype}); + }, + + makeThumbnail : function (image, type, name, orientation) { + var canvas = document.createElement("canvas"), + width, + xhr = new XMLHttpRequest(), + data = new FormData(), + bitmapData, file; + + xhr.open('POST', uploadScript, true); + width = oEditor.config.thumbnailWidth; + + bitmapData = this.imageResize(image, type, width, orientation); + file = this.canvasToBlob(bitmapData, type); + + data.append(inputFileName, file, 'thumb_' + name); // RFC Level 2 + + xhr.addEventListener("loadend", function () { + + }, false); + + xhr.addEventListener("error", function () { + alert("Thumbnail 파일 전송 중 오류:"); + }, false); + + xhr.send(data); + }, + + dataLoadHandler: function (evt) { + var self = this, + filename = evt.target.file.name, + filetype = evt.target.file.type, + file = evt.target.file, + blob, image, orientation = 1; + + if (evt.target.readyState === FileReader.DONE) { + blob = new self.MyBlob(self.NewBlob(evt.target.result, filetype)); + try { + orientation = self.getOrientation(evt.target.result.slice(0, 64 * 1024)); + } catch(err) { + + } + image = new Image(); + + image.onload = function () { + var bitmapData = null, + canvas = document.createElement("canvas"), + data = new FormData(), + fileFormat, + imgBox = file.boxElem, + imgInfo = {}, + randomName, + xhr = new XMLHttpRequest(); + + xhr.open('POST', uploadScript, true); + + if (imageResizeWidth > 0 && this.width > imageResizeWidth) { + bitmapData = self.imageResize(this, filetype, imageResizeWidth, orientation, true); + file = self.canvasToBlob(bitmapData, filetype); + } + + fileFormat = filename.substring(filename.lastIndexOf('.')); + randomName = self.makeFilename(fileFormat); + + data.append('origname', filename); + data.append(inputFileName, file, randomName); // RFC Level 2 + + if (debug) { + console.log('Successed: ' + filename); + } + + xhr.addEventListener("error", function (evt) { + alert("파일 전송 중 오류: " + evt.target.error.code); + }, false); + + xhr.addEventListener("loadend", function onLoadendImageHandler(xhrevt) { + if (xhrevt.target.readyState === xhrevt.target.DONE) { + if (oEditor.config.makeThumbnail) { + self.makeThumbnail(image, filetype, randomName, orientation, false); + } + } + image.src = ''; + image = null; + }, false); + + xhr.addEventListener("load", function (xhrevt) { + var jsonText, jsonData, img, onLoadHandler; + data = null; + + if (xhrevt.target.status === 200) { + jsonText = decodeURI(oEditor.trimSpace(this.responseText)); + jsonText = jsonText.replace(/\+/g, ' ').replace(/\\/g, '\\\\'); + jsonData = JSON.parse(jsonText); + + onLoadHandler = function () { + imgInfo = { + fileName: jsonData.fileName, + filePath: jsonData.filePath, + fileSize: jsonData.fileSize, + fileUrl: jsonData.fileUrl, + origName: filename, + origSize: file.size, + height: img.height, + width: img.width + }; + + imageCompletedList[imgBox.id] = imgInfo; + imgComplete(this, imgInfo, imgBox.id); + imgBox.appendChild(img); + + if (debug) { + console.log('Image URL: ' + img.src + ', size:' + file.size); + } + + setTimeout(function () { + self.load(); + }, 100); + + if (debug) { + console.log('Uploaded'); + } + }; + img = new Image(); + img.onload = onLoadHandler; + img.src = decodeURIComponent(jsonData.fileUrl); + } else { + alert("HTTP 오류: " + xhr.status); + } + }, false); + + blob.dispose(); + blob = null; + xhr.send(data); + }; + + image.src = blob.getURL(); + } + }, + + onReadDataErrorHandler: function (evt) { + var status = ''; + switch (evt.target.error.code) { + case evt.target.error.NOT_FOUND_ERR: + status = "파일을 찾을 수 없습니다."; + break; + case evt.target.error.NOT_READABLE_ERR: + status = "파일을 읽을 수 없습니다."; + break; + case evt.target.error.ABORT_ERR: + status = "파일 읽기가 중지되었습니다."; + break; + case evt.target.error.SECURITY_ERR: + status = "파일이 잠겨 있습니다."; + break; + case evt.target.error.ENCODING_ERR: + status = "data:// URL의 파일 인코딩 길이가 너무 깁니다."; + break; + default: + status = "파일 읽기 오류: " + evt.target.error.code; + } + this.removeEventListener('error', this.onReadDataErrorHandler); + alert("'" + evt.target.filename + "' " + status); + }, + + load: function () { + var file = this.list.shift(), self = this, watermark = null; + + if (file) { + if (debug) { + console.log('File ' + this.index + ', Name: ' + file.name + ', Size: ' + file.size); + } + this.reader.file = file; + this.reader.watermark = null; + + if (oEditor.config.imgWaterMarkUrl !== '' && oEditor.config.imgWaterMarkUrl !== null) { + watermark = new Image(); + watermark.onerror = function () { + alert('워터마크 이미지를 읽을 수 없습니다. (' + oEditor.config.imgWaterMarkUrl + ')'); + self.reader.readAsArrayBuffer(file); + }; + watermark.onload = function () { + self.reader.watermark = this; + self.reader.readAsArrayBuffer(file); + }; + watermark.src = oEditor.config.imgWaterMarkUrl; + } else { + this.reader.readAsArrayBuffer(file); + } + } else { + this.clear(); + } + }, + + clear: function () { + var inputFile = document.getElementById('inputImageUpload'), + theForm = document.createElement('form'), + fileSelectButton = document.getElementById('fileSelectButton'); + + this.list = []; + + theForm.appendChild(inputFile); + theForm.reset(); + fileSelectButton.parentNode.insertBefore(inputFile, fileSelectButton); + fileSelectButton.style.marginLeft = '-1px'; + } +}; + +function fileSelectDrop(evt) { + var files, + upload = new DoUpload(); + + oEditor.stopEvent(evt); + this.className = "imageListWrapperHtml5"; + + files = evt.dataTransfer.files; + upload.select(files); +} + +function dragOver(ev) { + oEditor.stopEvent(ev); + this.className = "dragOver"; +} + +function dragOut(ev) { + oEditor.stopEvent(ev); + this.className = "imageListWrapperHtml5"; +} + +function setResizeWidth() { + var value = oEditor.trimSpace(imageResizeInput.value); + if (value) { + value = Math.ceil(parseInt(value, 10)); + if (!isNaN(value) && value < oEditor.config.imgMaxWidth) { + imageResizeWidth = value; + } else { + imageResizeInput.value = ''; + imageResizeInput.setAttribute('placeholder', oEditor.config.imgMaxWidth.toString()); + } + } +} + +function init(dialog) { + var dlg, i, elem, input, select, value, name; + + oEditor = this; + oEditor.dialog = dialog; + dlg = new Dialog(oEditor); + browser = oEditor.getBrowser(); + + uploadImagePath = oEditor.config.iconPath + 'imageUpload'; + uploadMaxNumber = oEditor.config.imgUploadNumber; + uploadScript = oEditor.config.editorPath + 'imageUpload/upload.php'; + deleteScript = oEditor.config.editorPath + 'imageUpload/delete.php'; + imageListWrapper = document.getElementById("imageListWrapper"); + + imageResizeWidth = oEditor.config.imgMaxWidth; + imageResizeInput = document.getElementById('idResizeWidth'); + select = document.getElementById('idResizeSelectBox'); + + if (imageResizeWidth > 0) { + for (i = 0; i < oEditor.config.imgResizeValue.length; i++) { + name = value = oEditor.config.imgResizeValue[i]; + if (value > oEditor.config.imgMaxWidth) { + continue; + } + if (value === -1) { + name = '<입력>'; + } + select.options[select.options.length] = new Option(name, value, false, value === oEditor.config.imgResizeSelected); + } + select.onchange = function () { + if (this.value < 0) { + document.getElementById('idUserInputWrapper').style.display = ''; + } else { + document.getElementById('idUserInputWrapper').style.display = 'none'; + imageResizeWidth = this.value; + } + }; + imageResizeInput.setAttribute('placeholder', imageResizeWidth.toString()); + imageResizeWidth = select.value; + } else { + select.options[0] = new Option('원본', 0); + select.setAttribute('disabled', 'disabled'); + imageResizeWidth = 0; + } + + document.getElementById("maxImageNum").appendChild(document.createTextNode(uploadMaxNumber.toString())); + + button = [ + { alt: "", img: 'submit.gif', cmd: doSubmit, hspace: 2 }, + { alt: "", img: 'cancel.gif', cmd: closeWindow, hspace: 2 } + ]; + + dlg.setDialogHeight(370); + dlg.showButton(button); + showContents(); + initGallery(); + showUploadWindow(); + createInsertionMaker(); + selectedFilesNum = 0; + + oEditor.addEvent(imageListWrapper, 'dragover', dragOver); + oEditor.addEvent(imageListWrapper, 'dragleave', dragOut); + oEditor.addEvent(imageListWrapper, 'drop', fileSelectDrop); + + elem = document.getElementById('id_alignment').elements; + + for (i = 0; i < elem.length; i++) { + if (elem[i].name === "alignment" && elem[i].value === oEditor.config.imgDefaultAlign) { + elem[i].checked = "checked"; + break; + } + } + + if (browser.mobile) { + input = document.getElementById('inputImageUpload'); + input.setAttribute('capture', 'gallery'); + } +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.js new file mode 100644 index 0000000..39128c6 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image.js @@ -0,0 +1,890 @@ +// ================================================================ +// CHEditor 5 +// ================================================================ +var uploadScript = '', + deleteScript = '', + AppID = 'chximage', + AppSRC = '', + activeImage = null, + destinationObject = null, + readyToMove = false, + moveTimer = -1, + dragDropDiv, + insertionMarker, + offsetX_marker = -4, + offsetY_marker = -3, + geckoOffsetX_marker = 4, + geckoOffsetY_marker = -2, + divXPositions = [], + divYPositions = [], + divWidth = [], + divHeight = [], + tmpLeft = 0, + tmpTop = 0, + eventDiff_x = 0, + eventDiff_y = 0, + modifyImages = [], + uploadMaxNumber = 12, + imageCompleted = 0, + imageCompletedList = [], + uploadButton = '', + uploadImagePath = '', + showThumbnailSize = { width: 120, height: 90 }, + oEditor = null, + button, + imageResizeWidth = 0, + makeThumbnail = true, + makeThumbnailWidth = 120, + makeThumbnailHeight = 90, + sortOnName = false, + browser = null; + +function createInsertionMaker() { + var wrapper = document.getElementById('insertionMarker'), + topIco = new Image(), + middleIco = new Image(), + bottomIco = new Image(); + + topIco.src = uploadImagePath + '/marker_top.gif'; + topIco.style.width = '6px'; + topIco.style.height = '1px'; + wrapper.appendChild(topIco); + + middleIco.src = uploadImagePath + '/marker_middle.gif'; + middleIco.style.height = '96px'; + middleIco.style.width = '6px'; + wrapper.appendChild(middleIco); + + bottomIco.src = uploadImagePath + '/marker_bottom.gif'; + bottomIco.style.width = '6px'; + bottomIco.style.height = '1px'; + wrapper.appendChild(bottomIco); +} + +function popupClose() { + // ---------------------------------------------------------------------------------- + swfobject.removeSWF(AppID); + oEditor.popupWinCancel(); +} + +function showContents() { + var spacer = function (id) { + var clear = document.createElement('span'); + clear.style.height = '0'; + clear.style.width = '0'; + clear.className = 'clear'; + clear.id = 'spacer' + id; + return clear; + }, spacerNo = 1, i, imgBox, theImg, lastSpacer; + + for (i = 0; i < uploadMaxNumber; i++) { + if (i > 0 && ((i % 4) === 0)) { + document.getElementById('imageListWrapper').appendChild(spacer(spacerNo++)); + } + + imgBox = document.createElement('div'); + imgBox.id = 'imgBox' + i; + imgBox.className = 'imageBox'; + theImg = document.createElement('div'); + theImg.id = 'img_' + i; + theImg.className = 'imageBox_theImage'; + imgBox.appendChild(theImg); + + document.getElementById('imageListWrapper').appendChild(imgBox); + if (i === (uploadMaxNumber - 1)) { + lastSpacer = spacer(spacerNo); + lastSpacer.style.height = "7px"; + document.getElementById('imageListWrapper').appendChild(lastSpacer); + } + } + + if (browser.msie && browser.ver < 7) { + document.getElementById('imageListWrapper').style.padding = '5px 2px 5px 2px'; + document.getElementById('imageInfoBox').style.height = '302px'; + document.getElementById('imageInfoBox').style.width = '124px'; + } else { + document.getElementById('imageListWrapper').style.padding = '5px 7px 0 5px'; + document.getElementById('imageInfoBox').style.height = '298px'; + document.getElementById('imageInfoBox').style.width = '130px'; + } +} + +function openFiles() { + // ---------------------------------------------------------------------------------- + var elem = browser.msie ? document.getElementById(AppID) : document[AppID]; + elem.AddFiles(); +} + +function setImageCount() { + imageCompleted++; + document.getElementById('imageCount').innerHTML = imageCompleted; +} + +function getImageCount() { + return imageCompleted; +} + +function allowedMaxImage() { + return uploadMaxNumber - getImageCount(); +} + +function getUploadedCount() { + return document.getElementById('imageListWrapper').getElementsByTagName('img').length; +} + +function uploadedImageCount() { + imageCompleted = getUploadedCount(); + document.getElementById('imageCount').innerHTML = imageCompleted; +} + +function uploadError(msg) { + alert(msg); +} + +function imageDelete(filePath) { + var chximage = document.getElementById(AppID); + chximage.ImageDelete(encodeURI(filePath)); +} + +function getTopPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetTop; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.tagName.toLowerCase() !== 'html') { + returnValue += (inputObj.offsetTop - inputObj.scrollTop); + if (browser.msie) { + returnValue += inputObj.clientTop; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getLeftPos(inputObj) { + // ---------------------------------------------------------------------------------- + var returnValue = inputObj.offsetLeft; + + inputObj = inputObj.offsetParent; + while (inputObj) { + if (inputObj.id !== 'imageListWrapper') { + returnValue += inputObj.offsetLeft; + if (browser.msie) { + returnValue += inputObj.clientLeft; + } + } + inputObj = inputObj.offsetParent; + } + return returnValue; +} + +function getDivCoordinates() { + // ---------------------------------------------------------------------------------- + var imgBox = document.getElementById('imageListWrapper').getElementsByTagName('DIV'), + i = 0; + + for (; i < imgBox.length; i++) { + if ((imgBox[i].className === 'imageBox' || imgBox[i].className === 'imageBoxHighlighted') && imgBox[i].id) { + divXPositions[imgBox[i].id] = getLeftPos(imgBox[i]); + divYPositions[imgBox[i].id] = getTopPos(imgBox[i]); + divWidth[imgBox[i].id] = imgBox[i].offsetWidth; + divHeight[imgBox[i].id] = imgBox[i].offsetHeight; + } + } +} + +function reOrder() { + // ---------------------------------------------------------------------------------- + var wrapper = document.getElementById('imageListWrapper'), + imgBox = wrapper.getElementsByTagName('div'), + imgNum = 0, i, spacer, breakline = []; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].id.indexOf('imgBox') === -1) { + continue; + } + + imgBox[i].className = 'imageBox'; + imgBox[i].firstChild.className = 'imageBox_theImage'; + + if (imgNum > 0 && (imgNum % 4) === 0) { + breakline.push(imgBox[i].id); + } + + imgNum++; + } + + for (i = 0; i < breakline.length; i++) { + spacer = document.getElementById('spacer' + (i + 1)); + if (i + 1 === breakline.length) { + wrapper.appendChild(spacer); + } else { + wrapper.insertBefore(spacer, document.getElementById(breakline[i])); + } + } +} + +function setImageInfo(id) { + var elem; + if (!id) { + document.getElementById('selectedImageWidth').innerHTML = '0'; + document.getElementById('selectedImageHeight').innerHTML = '0'; + document.getElementById('selectedImageName').innerHTML = "없음"; + } else { + elem = imageCompletedList[id]; + document.getElementById('selectedImageWidth').innerHTML = elem.width; + document.getElementById('selectedImageHeight').innerHTML = elem.height; + document.getElementById('selectedImageName').innerHTML = elem.origName; + } +} + +function showDelete() { + // ---------------------------------------------------------------------------------- + var self = this, btn; + + if (readyToMove) { + return; + } + + getDivCoordinates(); + self.className = 'imageBox_theImage_over'; + btn = document.getElementById('removeImageButton'); + btn.style.left = (showThumbnailSize.width - parseInt(btn.style.width, 10) - 1) + 'px'; + btn.style.top = '-1px'; + + self.appendChild(btn); + btn.style.display = 'block'; + + btn.onmouseover = function (ev) { + ev = ev || window.event; + ev.cancelBubble = true; + this.style.display = 'block'; + setImageInfo(self.id); + this.className = 'removeButton_over'; + self.className = 'imageBox_theImage_over'; + }; + btn.onmouseout = function () { + this.className = 'removeButton'; + }; + btn.onmousedown = function () { + var images = self.getElementsByTagName('img'), i, wrapper, moveobj, target; + + for (i = 0; i < images.length; i++) { + self.removeChild(images[i]); + } + + self.removeChild(self.firstChild); + self.className = 'imageBox_theImage'; + + if (self.parentNode.nextSibling && self.parentNode.nextSibling.id) { + wrapper = document.getElementById('imageListWrapper'); + moveobj = self.parentNode.nextSibling; + target = self.parentNode; + + while (moveobj !== null) { + if (moveobj.firstChild && !moveobj.firstChild.firstChild) { + break; + } + if (/^spacer/.test(moveobj.id)) { + moveobj = moveobj.nextSibling; + continue; + } + wrapper.insertBefore(moveobj, target); + moveobj = target.nextSibling; + } + } + + reOrder(); + uploadedImageCount(); + setImageInfo(0); + this.style.display = 'none'; + document.body.appendChild(this); + self.onmouseout = self.onmouseover = null; + }; + + setImageInfo(self.id); +} + +function hideDelete() { + // ---------------------------------------------------------------------------------- + document.getElementById('removeImageButton').style.display = 'none'; +} + +function startUpload(count) { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), i, imgBox; + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (count === 0) { + break; + } + + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + imgBox.style.backgroundImage = "url('" + uploadImagePath + "/loader.gif')"; + count--; + } + } +} + +function fileFilterError(file) { + alert("선택하신 '" + file + "' 파일은 전송할 수 없습니다.\n" + + "gif, png, jpg, 그림 파일만 전송할 수 있습니다."); +} + +function imgComplete(img, imgSize, boxId) { + var resizeW, resizeH, M, elem; + img.setAttribute("border", '0'); + + if (imgSize.width > showThumbnailSize.width || imgSize.height > showThumbnailSize.height) { + if (imgSize.width > imgSize.height) { + resizeW = (imgSize.width > showThumbnailSize.width) ? showThumbnailSize.width : imgSize.width; + resizeH = Math.round((imgSize.height * resizeW) / imgSize.width); + } else { + resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height; + resizeW = Math.round((imgSize.width * resizeH) / imgSize.height); + } + + if (resizeH > showThumbnailSize.height) { + resizeH = (imgSize.height > showThumbnailSize.height) ? showThumbnailSize.height : imgSize.height; + resizeW = Math.round((imgSize.width * resizeH) / imgSize.height); + } + + } else { + resizeW = imgSize.width; + resizeH = imgSize.height; + } + + img.style.width = resizeW - 2 + 'px'; + img.style.height = resizeH - 2 + 'px'; + img.style.margin = "1px"; + + if (resizeW < showThumbnailSize.width) { + M = showThumbnailSize.width - resizeW; + img.style.marginLeft = Math.round(M / 2) + 'px'; + } + + if (resizeH < showThumbnailSize.height) { + M = showThumbnailSize.height - resizeH; + img.style.marginTop = Math.round(M / 2) + 'px'; + } + + elem = document.getElementById(boxId); + elem.style.backgroundImage = "url('" + uploadImagePath + "/dot.gif')"; + elem.onmouseover = showDelete; + elem.onmouseout = function() { + this.className = 'imageBox_theImage'; + setImageInfo(0); + hideDelete(); + }; + + setImageCount(); +} + +function uploadComplete(image) { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), + imgBox = null, tmpImg, i, imgInfo, + imgOnLoad = function () { + imgInfo = { "width": image.width, "height": image.height, "fileSize": image.fileSize, + "fileUrl": image.fileUrl, "fileName": image.fileName, "filePath": image.filePath, "origName": image.origName }; + + imageCompletedList[imgBox.id] = imgInfo; + imgComplete(this, imgInfo, imgBox.id); + }; + + image.filePath = decodeURI(image.filePath); + image.origName = decodeURI(image.origName); + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (!imgBox.firstChild || imgBox.firstChild.tagName.toLowerCase() !== 'img') { + tmpImg = new Image(); + tmpImg.style.width = "0px"; + tmpImg.style.height = "0px"; + tmpImg.setAttribute("alt", image.origName); + tmpImg.onload = imgOnLoad; + tmpImg.src = image.fileUrl; + imgBox.appendChild(tmpImg); + break; + } + } +} + +function showUploadWindow() { + // ---------------------------------------------------------------------------------- + var uploadWindow = document.getElementById("uploadWindow"), + uploadWindowWidth = 700, + winWidth, el, i, j, imgBox, img; + + if (!(oEditor.undefined(window.innerWidth))) { + winWidth = window.innerWidth; + } else if (document.documentElement && + (!(oEditor.undefined(document.documentElement.clientWidth))) && + document.documentElement.clientWidth !== 0) { + winWidth = document.documentElement.clientWidth; + } else if (document.body && (!(oEditor.undefined(document.body.clientWidth)))) { + winWidth = document.body.clientWidth; + } else { + alert('현재 브라우저를 지원하지 않습니다.'); + return; + } + + uploadWindow.style.left = winWidth / 2 - (uploadWindowWidth / 2) + 'px'; + uploadWindow.style.display = "block"; + uploadWindow.style.width = uploadWindowWidth + 'px'; + + if (modifyImages.length > 0) { + el = document.getElementById('imageListWrapper').getElementsByTagName('div'); + for (i = 0; i < modifyImages.length; i++) { + if (i > 7) { + break; + } + + for (j = 0; j < el.length; j++) { + imgBox = el[j]; + if (imgBox.className !== 'imageBox_theImage') { + continue; + } + + if (imgBox.firstChild && (imgBox.firstChild.src === modifyImages[i])) { + break; + } + + if (imgBox.firstChild === null) { + img = new Image(); + img.src = modifyImages[i]; + img.border = 0; + img.alt = ''; + img.style.width = '120px'; + img.style.height = '90px'; + imgBox.appendChild(img); + break; + } + } + } + } +} + +function removeImages() { + var images = [], i, j, theImage, img, remove; + document.body.appendChild(document.getElementById('removeImageButton')); + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + images.push(theImage); + } + } + + for (i = 0; i < images.length; i++) { + img = images[i]; + if (img.firstChild !== null) { + oEditor.removeEvent(img, 'mouseover', showDelete); + remove = img.getElementsByTagName('img'); + + for (j = 0; j < remove.length; j++) { + img.removeChild(remove[j]); + } + + img.parentNode.className = 'imageBox'; + oEditor.removeEvent(img, 'mouseover', showDelete); + } + } + uploadedImageCount(); + imageCompletedList = []; +} + +function removeImage() { + // ---------------------------------------------------------------------------------- + var i, theImage, found = false; + + for (i = 0; i < uploadMaxNumber; i++) { + theImage = document.getElementById('img_' + i); + if (theImage.hasChildNodes() && theImage.firstChild.tagName.toLowerCase() === 'img') { + found = true; + break; + } + } + + if (found) { + if (!confirm('추가하신 사진이 있습니다. 사진 넣기를 취소하시겠습니까?')) { + return false; + } + removeImages(); + } + + return true; +} + +function closeWindow() { + // ---------------------------------------------------------------------------------- + if (removeImage()) { + popupClose(); + } +} + +function cancelEvent() { + // ---------------------------------------------------------------------------------- + return false; +} + +function startMoveTimer() { + // ---------------------------------------------------------------------------------- + var subElements, newDiv; + + if (moveTimer >= 0 && moveTimer < 10) { + moveTimer++; + setTimeout('startMoveTimer()', 8); + } + + if (moveTimer === 5) { + getDivCoordinates(); + subElements = dragDropDiv.getElementsByTagName('div'); + if (subElements.length > 0) { + dragDropDiv.removeChild(subElements[0]); + } + + dragDropDiv.style.display = 'block'; + newDiv = activeImage.cloneNode(true); + newDiv.className = 'imageBox'; + newDiv.style.opacity = 0.5; + + newDiv.id = ''; + newDiv.style.padding = '2px'; + dragDropDiv.appendChild(newDiv); + + dragDropDiv.style.top = tmpTop + 'px'; + dragDropDiv.style.left = tmpLeft + 'px'; + } + + return false; +} + +function getMouseButtn(e) { + var code; + e = e || window.event; + code = e.button; + + if (code) { + if (browser.msie && browser.version < 9) { + code = code === 1 ? 0 : (code === 4 ? 1 : code); + } + } + + return code; +} + +function selectImage(e) { + // ---------------------------------------------------------------------------------- + var el = this.parentNode.firstChild.firstChild, obj; + + if (!el) { + return; + } + + e = e || window.event; + if (getMouseButtn(e) === 2) { + return; + } + + obj = this.parentNode; + hideDelete(); + + obj.className = 'imageBoxHighlighted'; + activeImage = obj; + readyToMove = true; + moveTimer = 0; + + tmpLeft = e.clientX + Math.max(document.body.scrollLeft, document.documentElement.scrollLeft); + tmpTop = e.clientY + Math.max(document.body.scrollTop, document.documentElement.scrollTop); + + startMoveTimer(); + return false; +} + +function dragDropEnd() { + // ---------------------------------------------------------------------------------- + var parentObj, chkObj, turn = false; + + readyToMove = false; + moveTimer = -1; + dragDropDiv.style.display = 'none'; + insertionMarker.style.display = 'none'; + + if (!activeImage) { + return; + } + + if (destinationObject && destinationObject !== activeImage) { + parentObj = destinationObject.parentNode; + chkObj = destinationObject.previousSibling; + turn = false; + + if (chkObj === null) { + chkObj = document.getElementById('imageListWrapper').firstChild; + turn = true; + } + + if (chkObj.id.indexOf('spacer') !== -1) { + chkObj = chkObj.previousSibling; + } + + if (chkObj.firstChild.firstChild === null) { + reOrder(); + return; + } + + if (chkObj && chkObj.id !== null) { + while (chkObj) { + if (chkObj.firstChild.firstChild !== null) { + break; + } + chkObj = chkObj.previousSibling; + } + destinationObject = turn ? chkObj : chkObj.nextSibling; + } + + parentObj.insertBefore(activeImage, destinationObject); + reOrder(); + + activeImage = null; + destinationObject = null; + getDivCoordinates(); + + return false; + } + + activeImage.className = 'imageBox'; + return true; +} + +function dragDropMove(e) { + // ---------------------------------------------------------------------------------- + var elementFound = false, prop, offsetX, offsetY, leftPos, topPos, btnCode; + + if (moveTimer === -1 || !readyToMove) { + return; + } + + e = e || window.event; + + leftPos = e.clientX + document.documentElement.scrollLeft - eventDiff_x; + topPos = e.clientY + document.documentElement.scrollTop - eventDiff_y; + + dragDropDiv.style.top = topPos + 'px'; + dragDropDiv.style.left = leftPos + 'px'; + + leftPos = leftPos + eventDiff_x; + topPos = topPos + eventDiff_y; + + if (getMouseButtn(e) !== 0) { + dragDropEnd(); + } + + for (prop in divXPositions) { + if (!divXPositions.hasOwnProperty(prop) || divXPositions[prop].className === 'clear') { + continue; + } + + if (divXPositions[prop] < leftPos && + (divXPositions[prop] + divWidth[prop] * 0.7) > leftPos && + divYPositions[prop] < topPos && + (divYPositions[prop] + divWidth[prop]) > topPos) { + if (browser.msie) { + offsetX = offsetX_marker; + offsetY = offsetY_marker; + } else { + offsetX = geckoOffsetX_marker; + offsetY = geckoOffsetY_marker; + } + + insertionMarker.style.top = divYPositions[prop] + offsetY + 'px'; + insertionMarker.style.left = divXPositions[prop] + offsetX + 'px'; + insertionMarker.style.display = 'block'; + destinationObject = document.getElementById(prop); + elementFound = true; + break; + } + } + + if (!elementFound) { + insertionMarker.style.display = 'none'; + destinationObject = null; + } + + return false; +} + +function saveImageOrder() { + // ---------------------------------------------------------------------------------- + var rData = [], + objects = document.getElementById('imageListWrapper').getElementsByTagName('div'), + i; + + for (i = 0; i < objects.length; i++) { + if (objects[i].className === 'imageBox' || + objects[i].className === 'imageBoxHighlighted') { + rData.push(objects[i].id); + } + } + + return rData; +} + +function initGallery() { + // ---------------------------------------------------------------------------------- + var imgBox = document.getElementById('imageListWrapper').getElementsByTagName('div'), + i; + + for (i = 0; i < imgBox.length; i++) { + if (imgBox[i].className === 'imageBox_theImage') { + imgBox[i].onmousedown = selectImage; + } + } + + document.body.onselectstart = cancelEvent; + document.body.ondragstart = cancelEvent; + document.body.onmouseup = dragDropEnd; + document.body.onmousemove = dragDropMove; + + dragDropDiv = document.getElementById('dragDropContent'); + insertionMarker = document.getElementById('insertionMarker'); + getDivCoordinates(); +} + +function doSubmit() { + // ---------------------------------------------------------------------------------- + var el = document.getElementById('imageListWrapper').getElementsByTagName('div'), + imageArray = [], + num = 0, + elem = document.getElementById('id_alignment').elements, + imgParagraph = false, + useSpacer = false, + imgAlign = 'top', i, imgBox, input; + + for (i = 0; i < elem.length; i++) { + input = elem[i]; + switch (input.name) { + case "alignment" : + if (input.checked) { + imgAlign = input.value; + } + break; + case "para" : + imgParagraph = input.checked; + break; + case "use_spacer" : + useSpacer = input.checked; + break; + } + } + + for (i = 0; i < el.length; i++) { + imgBox = el[i]; + if (imgBox.className !== "imageBox_theImage") { + continue; + } + + if (imgBox.firstChild !== null) { + imageArray[num] = imageCompletedList[imgBox.id]; + + if (imgAlign === "break") { + imageArray[num].alt = "break"; + } else { + imageArray[num].alt = ''; + imageArray[num].align = imgAlign; + } + + num++; + } + } + + if (imageArray.length > 0) { + oEditor.doInsertImage(imageArray, imgParagraph, useSpacer); + } + oEditor.popupWinClose(); +} + +function initEvent() { + var swfVersionStr = "11.1.0", + xiSwfUrlStr = "http://get.adobe.com/kr/flashplayer/", + flashvars = { + UploadScript: uploadScript, + DeleteScript: deleteScript, + UploadButton: uploadButton, + MakeThumbnail: makeThumbnail, + ThumbnailWidth: makeThumbnailWidth, + ThumbnailHeight: makeThumbnailHeight, + ImageResizeWidth: imageResizeWidth, + loadPolicyFile: true, + SortOnName: sortOnName + }, + params = { + quality: "high", + bgcolor: "#ffffff", + allowscriptaccess: "Always", + allowfullscreen: "false", + //allowNetworking: "all", + wmode: "transparent" + }, + attributes = { id: AppID, name: AppID, align: "middle" }; + + swfobject.embedSWF(AppSRC, "oFlashButton", "93", "22", swfVersionStr, xiSwfUrlStr, flashvars, params, attributes); +} + +function init(dialog) { + var dlg = new Dialog(this), + elem = document.getElementById('id_alignment').elements, + i; + + oEditor = this; + oEditor.dialog = dialog; + + browser = oEditor.getBrowser(); + + uploadImagePath = oEditor.config.iconPath + 'imageUpload'; + uploadButton = '../icons/imageUpload/add.gif'; + AppSRC = oEditor.config.popupPath + 'flash/chximage.swf'; + uploadMaxNumber = oEditor.config.imgUploadNumber; + uploadScript = oEditor.config.editorPath + 'imageUpload/upload.php'; + deleteScript = oEditor.config.editorPath + 'imageUpload/delete.php'; + + imageResizeWidth = oEditor.config.imgMaxWidth; + makeThumbnail = oEditor.config.makeThumbnail; + sortOnName = oEditor.config.imgUploadSortName; + makeThumbnailWidth = oEditor.config.thumbnailWidth; + makeThumbnailHeight = oEditor.config.thumbnailHeight; + + document.getElementById("maxImageNum").appendChild(document.createTextNode(uploadMaxNumber)); + + button = [ + { alt: "", img: 'submit.gif', cmd: doSubmit, hspace: 2 }, + { alt: "", img: 'cancel.gif', cmd: closeWindow, hspace: 2 } + ]; + + dlg.setDialogHeight(370); + dlg.showButton(button); + showContents(); + initGallery(); + showUploadWindow(); + initEvent(); + createInsertionMaker(); + + for (i = 0; i < elem.length; i++) { + if (elem[i].name === "alignment" && elem[i].value === oEditor.config.imgDefaultAlign) { + elem[i].checked = "checked"; + break; + } + } +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_upload_flash.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_upload_flash.js new file mode 100644 index 0000000..0708a56 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_upload_flash.js @@ -0,0 +1,279 @@ +// Flash Player Version Detection - Rev 1.6 +// Detect Client Browser type +// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved. +var isIE = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false; +var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false; +var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false; + +function ControlVersion() +{ + var version = 0; + var axo; +// var e; + + // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry + + try { + // version will be set for 7.X or greater players + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); + version = axo.GetVariable("$version"); + } catch (e) { + } + + if (!version) + { + try { + // version will be set for 6.X players only + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); + + // installed player is some revision of 6.0 + // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29, + // so we have to be careful. + + // default to the first public version + version = "WIN 6,0,21,0"; + + // throws if AllowScripAccess does not exist (introduced in 6.0r47) + axo.AllowScriptAccess = "always"; + + // safe to call for 6.0r47 or greater + version = axo.GetVariable("$version"); + + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 4.X or 5.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = axo.GetVariable("$version"); + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 3.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3"); + version = "WIN 3,0,18,0"; + } catch (e) { + } + } + + if (!version) + { + try { + // version will be set for 2.X player + axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); + version = "WIN 2,0,0,11"; + } catch (e) { + version = -1; + } + } + + return version; +} + +// JavaScript helper required to detect Flash Player PlugIn version information +function GetSwfVer(){ + // NS/Opera version >= 3 check for Flash plugin in plugin array + var flashVer = -1; + + if (navigator.plugins != null && navigator.plugins.length > 0) { + if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) { + var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : ""; + var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description; + var descArray = flashDescription.split(" "); + var tempArrayMajor = descArray[2].split("."); + var versionMajor = tempArrayMajor[0]; + var versionMinor = tempArrayMajor[1]; + var versionRevision = descArray[3]; + if (versionRevision == "") { + versionRevision = descArray[4]; + } + if (versionRevision[0] == "d") { + versionRevision = versionRevision.substring(1); + } else if (versionRevision[0] == "r") { + versionRevision = versionRevision.substring(1); + if (versionRevision.indexOf("d") > 0) { + versionRevision = versionRevision.substring(0, versionRevision.indexOf("d")); + } + } else if (versionRevision[0] == "b") { + versionRevision = versionRevision.substring(1); + } + flashVer = versionMajor + "." + versionMinor + "." + versionRevision; + } + } + // MSN/WebTV 2.6 supports Flash 4 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4; + // WebTV 2.5 supports Flash 3 + else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3; + // older WebTV supports Flash 2 + else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2; + else if ( isIE && isWin && !isOpera ) { + flashVer = ControlVersion(); + } + return flashVer; +} + +// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available +function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision) +{ + versionStr = GetSwfVer(); + if (versionStr == -1 ) { + return false; + } else if (versionStr != 0) { + if(isIE && isWin && !isOpera) { + // Given "WIN 2,0,0,11" + tempArray = versionStr.split(" "); // ["WIN", "2,0,0,11"] + tempString = tempArray[1]; // "2,0,0,11" + versionArray = tempString.split(","); // ['2', '0', '0', '11'] + } else { + versionArray = versionStr.split("."); + } + var versionMajor = versionArray[0]; + var versionMinor = versionArray[1]; + var versionRevision = versionArray[2]; + + // is the major.revision >= requested major.revision AND the minor version >= requested minor + if (versionMajor > parseFloat(reqMajorVer)) { + return true; + } else if (versionMajor == parseFloat(reqMajorVer)) { + if (versionMinor > parseFloat(reqMinorVer)) + return true; + else if (versionMinor == parseFloat(reqMinorVer)) { + if (versionRevision >= parseFloat(reqRevision)) + return true; + } + } + return false; + } +} + +function AC_AddExtension(src, ext) +{ + if (src.indexOf('?') != -1) + return src.replace(/\?/, ext+'?'); + else + return src + ext; +} + +function AC_Generateobj(objAttrs, params, embedAttrs) +{ + if (isIE && isWin && !isOpera) + { + var str = ' '; + str += ''; + document.getElementById("oFlash").innerHTML = str; + } + else { + var oFlash = document.getElementById("oFlash"); + var embed = document.createElement('embed'); + for (var i in embedAttrs) { + embed.setAttribute(i, embedAttrs[i]); + } + oFlash.appendChild(embed); + } +} + +function CHXImageRUN(){ + var ret = + AC_GetArgs + ( arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" + , "application/x-shockwave-flash" + ); + AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs); +} + +function AC_GetArgs(args, ext, srcParamName, classid, mimeType){ + var ret = new Object(); + ret.embedAttrs = new Object(); + ret.params = new Object(); + ret.objAttrs = new Object(); + for (var i=0; i < args.length; i=i+2){ + var currArg = args[i].toLowerCase(); + + switch (currArg){ + case "classid": + break; + case "pluginspage": + ret.embedAttrs[args[i]] = args[i+1]; + break; + case "src": + case "movie": + args[i+1] = AC_AddExtension(args[i+1], ext); + ret.embedAttrs["src"] = args[i+1]; + ret.params[srcParamName] = args[i+1]; + break; + case "onafterupdate": + case "onbeforeupdate": + case "onblur": + case "oncellchange": + case "onclick": + case "ondblClick": + case "ondrag": + case "ondragend": + case "ondragenter": + case "ondragleave": + case "ondragover": + case "ondrop": + case "onfinish": + case "onfocus": + case "onhelp": + case "onmousedown": + case "onmouseup": + case "onmouseover": + case "onmousemove": + case "onmouseout": + case "onkeypress": + case "onkeydown": + case "onkeyup": + case "onload": + case "onlosecapture": + case "onpropertychange": + case "onreadystatechange": + case "onrowsdelete": + case "onrowenter": + case "onrowexit": + case "onrowsinserted": + case "onstart": + case "onscroll": + case "onbeforeeditfocus": + case "onactivate": + case "onbeforedeactivate": + case "ondeactivate": + case "type": + case "codebase": + ret.objAttrs[args[i]] = args[i+1]; + break; + case "id": + case "width": + case "height": + case "align": + case "vspace": + case "hspace": + case "class": + case "title": + case "accesskey": + case "name": + case "tabindex": + ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1]; + break; + default: + ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1]; + } + } + ret.objAttrs["classid"] = classid; + if (mimeType) ret.embedAttrs["type"] = mimeType; + return ret; +} + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_url.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_url.js new file mode 100644 index 0000000..0ea3458 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/image_url.js @@ -0,0 +1,244 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var AppWidth = "250"; +var AppHeight = "175"; +var AppID = "cheditorPreview"; +var oEditor = null; +var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; +var newImage = null; + +function CHEditorImagePreview () { +// ---------------------------------------------------------------------------------- +// callBack function + + document.getElementById(AppID).CHEditorImagePreview("1", "1"); +} + +function CHXUploadRUN(src) { +// ---------------------------------------------------------------------------------- +// Preview +// + chxupload_RUN("src", src, + "width", AppWidth, + "height", AppHeight, + "align", "middle", + "id", AppID, + "classid", AppID, + "quality", "high", + "bgcolor", "#ebe9ed", + "name", AppID, + "wmode", "transparent", + "allowScriptAccess","Always", + "type", "application/x-shockwave-flash", + "pluginspage", "http://www.adobe.com/go/getflashplayer"); +} + +function getFilename (file) { + while (file.indexOf("/") != -1) { + file = file.slice(file.indexOf("/") + 1); + } + return file; +} + +function popupClose() +{ + oEditor.popupWinCancel(); +} + +function chkImgFormat (url) +{ + var imageName = getFilename(url); + var allowSubmit = false; + var extArray = [".gif", ".jpg", ".jpeg", ".png"]; + + extArray.join(" "); + if (imageName === "") { + return false; + } + + var ext = imageName.slice(imageName.lastIndexOf(".")).toLowerCase(); + var i; + + for (i = 0; i < extArray.length; i++) { + if (extArray[i] == ext) { + allowSubmit = true; + break; + } + } + + if (!allowSubmit) { + alert("사진은 GIF, JPG, PNG 형식만 넣을 수 있습니다."); + return false; + } + + return imageName; +} + +function previewImage (source) { + if (navigator.appName.indexOf("microsoft") != -1) { + window[AppID].CHEditorImagePreview(source, 0, 0); + } + else { + document[AppID].CHEditorImagePreview(source, 0, 0); + } +} + +function checkImageComplete (img) { + if (img.complete != true) { + setTimeout("checkImageComplete(document.getElementById('"+img.id+"'))", 250); + } + else { + document.getElementById('imageSize').innerHTML = ''; + + newImage = new Image(); + newImage.style.width = img.width + 'px'; + newImage.style.height = img.height + 'px'; + newImage.setAttribute("src", img.src); + newImage.setAttribute("alt", getFilename(img.src)); + } +} + +function doPreview () { + var imgurl = document.getElementById('fm_imageUrl').value; + var fileName = chkImgFormat(imgurl); + if (!fileName) { + return; + } + + var img = new Image(); + img.src = imgurl; + img.id = fileName; + + document.getElementById('tmpImage').appendChild(img); + checkImageComplete(img); + previewImage(img.src); +} + +function getElementById(id) { + var el = null; + try { + el = document.getElementById(id); + } + catch (ignore) {} + return el; +} + +function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + var i; + for (i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } +} + +function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (oEditor.getBrowser().msie) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } +} + +function doSubmit () +{ + if (newImage == null) { + alert("미리 보기 버튼을 클릭하여 이미지를 확인해 주십시오."); + return; + } + + if (navigator.userAgent.toLowerCase().indexOf("msie") != -1) { + document.getElementById(AppID).style.display = 'none'; + } + + var fm_align = document.getElementById('fm_align').alignment; + var align = 'center'; + var i; + + for (i=0; i 0) { + datum = ""; + } else { + datum = protocol[0].replace(/^\/\/\//, "//"); + } + } + + document.getElementById("fm_link_value").value = selectedItemValue + datum; + document.getElementById("fm_link_value").focus(); +} + +function returnSelected() { + var text, target = '', title = ''; + + if (document.getElementById("fm_link_value").value !== "") { + text = document.getElementById("fm_link_value").value; + } else { + alert("링크 URL을 입력하여 주십시오."); + return false; + } + + if (document.getElementById("fm_target").value !== "") { + target = document.getElementById("fm_target").value; + } + + if (document.getElementById("fm_title").value !== "") { + title = document.getElementById("fm_title").value; + } + + if ((/^(http|https|file|ftp|mailto|gopher|news|telnet|):\/\//i.test(text)) === false && + (/^(wias|javascript):/i.test(text) === false)) + { + text = "http://" + text; + } + + oEditor.hyperLink(text, target, title); + oEditor.popupWinClose(); +} + +function getSelected() { + var rng = oEditor.range, link = null, protocol, protocolSel, i, oldTarget, targetSel, j; + + if (window.getSelection) { + link = oEditor.getElement(rng.startContainer, "A"); + } else { + link = rng.parentElement ? oEditor.getElement(rng.parentElement(), "A") : oEditor.getElement(rng.item(0), "A"); + } + + if (link === null || link.nodeName.toLowerCase() !== 'a') { + return; + } + + protocol = link.href.split(":"); + + if (protocol[0]) { + protocolSel = document.getElementById("fm_protocol"); + for (i = 0; i < protocolSel.length; i++) { + if (protocolSel[i].value.indexOf(protocol[0].toLowerCase()) !== -1) { + oldTarget = link.target; + targetSel = document.getElementById("fm_target"); + + if (oldTarget) { + for (j = 0; j < targetSel.length; j++) { + if (targetSel[j].value === oldTarget.toLowerCase()) { + targetSel[j].selected = true; + break; + } + } + } else { + targetSel[0].selected = true; + } + + protocolSel[i].selected = true; + + if (link.title) { + document.getElementById("fm_title").value = link.title; + } + break; + } + } + } + document.getElementById("fm_link_value").value = link.href; +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + resetValues(); + getSelected(); + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/media.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/media.js new file mode 100644 index 0000000..5c54db9 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/media.js @@ -0,0 +1,46 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var button = [ + { alt : "", img : 'play.gif', cmd : play }, + { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } +]; + +var oEditor = null; + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + + dlg.setDialogHeight(); +} + +function play() +{ + var file = document.getElementById("fm_linkurl"); + if (!file.value) + return; + + var mediaobj = ""; + var obj = document.getElementById("play"); + obj.innerHTML = mediaobj; +} + +function doSubmit() +{ + var file = document.getElementById("fm_linkurl"); + var media = ""; + oEditor.insertHtmlPopup(media); + oEditor.popupWinClose(); +} + +function popupClose() { + oEditor.popupWinCancel(); +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/swfobject.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/swfobject.js new file mode 100644 index 0000000..9059c2a --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/swfobject.js @@ -0,0 +1,779 @@ +/*! SWFObject v2.2 + is released under the MIT License +*/ + +var swfobject = function() { + + var UNDEF = "undefined", + OBJECT = "object", + SHOCKWAVE_FLASH = "Shockwave Flash", + SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash", + FLASH_MIME_TYPE = "application/x-shockwave-flash", + EXPRESS_INSTALL_ID = "SWFObjectExprInst", + ON_READY_STATE_CHANGE = "onreadystatechange", + + win = window, + doc = document, + nav = navigator, + + plugin = false, + domLoadFnArr = [main], + regObjArr = [], + objIdArr = [], + listenersArr = [], + storedAltContent, + storedAltContentId, + storedCallbackFn, + storedCallbackObj, + isDomLoaded = false, + isExpressInstallActive = false, + dynamicStylesheet, + dynamicStylesheetMedia, + autoHideShow = true, + + /* Centralized function for browser feature detection + - User agent string detection is only used when no good alternative is possible + - Is executed directly for optimal performance + */ + ua = function() { + var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF, + u = nav.userAgent.toLowerCase(), + p = nav.platform.toLowerCase(), + windows = p ? /win/.test(p) : /win/.test(u), + mac = p ? /mac/.test(p) : /mac/.test(u), + webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false, // returns either the webkit version or false if not webkit + ie = !+"\v1", // feature detection based on Andrea Giammarchi's solution: http://webreflection.blogspot.com/2009/01/32-bytes-to-know-if-your-browser-is-ie.html + playerVersion = [0,0,0], + d = null; + if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) { + d = nav.plugins[SHOCKWAVE_FLASH].description; + if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) { // navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin indicates whether plug-ins are enabled or disabled in Safari 3+ + plugin = true; + ie = false; // cascaded feature detection for Internet Explorer + d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1"); + playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10); + playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10); + playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0; + } + } + else if (typeof win.ActiveXObject != UNDEF) { + try { + var a = new ActiveXObject(SHOCKWAVE_FLASH_AX); + if (a) { // a will return null when ActiveX is disabled + d = a.GetVariable("$version"); + if (d) { + ie = true; // cascaded feature detection for Internet Explorer + d = d.split(" ")[1].split(","); + playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + } + catch(e) {} + } + return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac }; + }(), + + /* Cross-browser onDomLoad + - Will fire an event as soon as the DOM of a web page is loaded + - Internet Explorer workaround based on Diego Perini's solution: http://javascript.nwbox.com/IEContentLoaded/ + - Regular onload serves as fallback + */ + onDomLoad = function() { + if (!ua.w3) { return; } + if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) { // function is fired after onload, e.g. when script is inserted dynamically + callDomLoadFunctions(); + } + if (!isDomLoaded) { + if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false); + } + if (ua.ie && ua.win) { + doc.attachEvent(ON_READY_STATE_CHANGE, function() { + if (doc.readyState == "complete") { + doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee); + callDomLoadFunctions(); + } + }); + if (win == top) { // if not inside an iframe + (function(){ + if (isDomLoaded) { return; } + try { + doc.documentElement.doScroll("left"); + } + catch(e) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + } + if (ua.wk) { + (function(){ + if (isDomLoaded) { return; } + if (!/loaded|complete/.test(doc.readyState)) { + setTimeout(arguments.callee, 0); + return; + } + callDomLoadFunctions(); + })(); + } + addLoadEvent(callDomLoadFunctions); + } + }(); + + function callDomLoadFunctions() { + if (isDomLoaded) { return; } + try { // test if we can really add/remove elements to/from the DOM; we don't want to fire it too early + var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span")); + t.parentNode.removeChild(t); + } + catch (e) { return; } + isDomLoaded = true; + var dl = domLoadFnArr.length; + for (var i = 0; i < dl; i++) { + domLoadFnArr[i](); + } + } + + function addDomLoadEvent(fn) { + if (isDomLoaded) { + fn(); + } + else { + domLoadFnArr[domLoadFnArr.length] = fn; // Array.push() is only available in IE5.5+ + } + } + + /* Cross-browser onload + - Based on James Edwards' solution: http://brothercake.com/site/resources/scripts/onload/ + - Will fire an event as soon as a web page including all of its assets are loaded + */ + function addLoadEvent(fn) { + if (typeof win.addEventListener != UNDEF) { + win.addEventListener("load", fn, false); + } + else if (typeof doc.addEventListener != UNDEF) { + doc.addEventListener("load", fn, false); + } + else if (typeof win.attachEvent != UNDEF) { + addListener(win, "onload", fn); + } + else if (typeof win.onload == "function") { + var fnOld = win.onload; + win.onload = function() { + fnOld(); + fn(); + }; + } + else { + win.onload = fn; + } + } + + /* Main function + - Will preferably execute onDomLoad, otherwise onload (as a fallback) + */ + function main() { + if (plugin) { + testPlayerVersion(); + } + else { + matchVersions(); + } + } + + /* Detect the Flash Player version for non-Internet Explorer browsers + - Detecting the plug-in version via the object element is more precise than using the plugins collection item's description: + a. Both release and build numbers can be detected + b. Avoid wrong descriptions by corrupt installers provided by Adobe + c. Avoid wrong descriptions by multiple Flash Player entries in the plugin Array, caused by incorrect browser imports + - Disadvantage of this method is that it depends on the availability of the DOM, while the plugins collection is immediately available + */ + function testPlayerVersion() { + var b = doc.getElementsByTagName("body")[0]; + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + var t = b.appendChild(o); + if (t) { + var counter = 0; + (function(){ + if (typeof t.GetVariable != UNDEF) { + var d = t.GetVariable("$version"); + if (d) { + d = d.split(" ")[1].split(","); + ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)]; + } + } + else if (counter < 10) { + counter++; + setTimeout(arguments.callee, 10); + return; + } + b.removeChild(o); + t = null; + matchVersions(); + })(); + } + else { + matchVersions(); + } + } + + /* Perform Flash Player and SWF version matching; static publishing only + */ + function matchVersions() { + var rl = regObjArr.length; + if (rl > 0) { + for (var i = 0; i < rl; i++) { // for each registered object element + var id = regObjArr[i].id; + var cb = regObjArr[i].callbackFn; + var cbObj = {success:false, id:id}; + if (ua.pv[0] > 0) { + var obj = getElementById(id); + if (obj) { + if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) { // Flash Player version >= published SWF version: Houston, we have a match! + setVisibility(id, true); + if (cb) { + cbObj.success = true; + cbObj.ref = getObjectById(id); + cb(cbObj); + } + } + else if (regObjArr[i].expressInstall && canExpressInstall()) { // show the Adobe Express Install dialog if set by the web page author and if supported + var att = {}; + att.data = regObjArr[i].expressInstall; + att.width = obj.getAttribute("width") || "0"; + att.height = obj.getAttribute("height") || "0"; + if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); } + if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); } + // parse HTML object param element's name-value pairs + var par = {}; + var p = obj.getElementsByTagName("param"); + var pl = p.length; + for (var j = 0; j < pl; j++) { + if (p[j].getAttribute("name").toLowerCase() != "movie") { + par[p[j].getAttribute("name")] = p[j].getAttribute("value"); + } + } + showExpressInstall(att, par, id, cb); + } + else { // Flash Player and SWF version mismatch or an older Webkit engine that ignores the HTML object element's nested param elements: display alternative content instead of SWF + displayAltContent(obj); + if (cb) { cb(cbObj); } + } + } + } + else { // if no Flash Player is installed or the fp version cannot be detected we let the HTML object element do its job (either show a SWF or alternative content) + setVisibility(id, true); + if (cb) { + var o = getObjectById(id); // test whether there is an HTML object element or not + if (o && typeof o.SetVariable != UNDEF) { + cbObj.success = true; + cbObj.ref = o; + } + cb(cbObj); + } + } + } + } + } + + function getObjectById(objectIdStr) { + var r = null; + var o = getElementById(objectIdStr); + if (o && o.nodeName == "OBJECT") { + if (typeof o.SetVariable != UNDEF) { + r = o; + } + else { + var n = o.getElementsByTagName(OBJECT)[0]; + if (n) { + r = n; + } + } + } + return r; + } + + /* Requirements for Adobe Express Install + - only one instance can be active at a time + - fp 6.0.65 or higher + - Win/Mac OS only + - no Webkit engines older than version 312 + */ + function canExpressInstall() { + return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312); + } + + /* Show the Adobe Express Install dialog + - Reference: http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=6a253b75 + */ + function showExpressInstall(att, par, replaceElemIdStr, callbackFn) { + isExpressInstallActive = true; + storedCallbackFn = callbackFn || null; + storedCallbackObj = {success:false, id:replaceElemIdStr}; + var obj = getElementById(replaceElemIdStr); + if (obj) { + if (obj.nodeName == "OBJECT") { // static publishing + storedAltContent = abstractAltContent(obj); + storedAltContentId = null; + } + else { // dynamic publishing + storedAltContent = obj; + storedAltContentId = replaceElemIdStr; + } + att.id = EXPRESS_INSTALL_ID; + if (typeof att.width == UNDEF || (!/%$/.test(att.width) && parseInt(att.width, 10) < 310)) { att.width = "310"; } + if (typeof att.height == UNDEF || (!/%$/.test(att.height) && parseInt(att.height, 10) < 137)) { att.height = "137"; } + doc.title = doc.title.slice(0, 47) + " - Flash Player Installation"; + var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn", + fv = "MMredirectURL=" + encodeURI(window.location).toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title; + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + fv; + } + else { + par.flashvars = fv; + } + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + if (ua.ie && ua.win && obj.readyState != 4) { + var newObj = createElement("div"); + replaceElemIdStr += "SWFObjectNew"; + newObj.setAttribute("id", replaceElemIdStr); + obj.parentNode.insertBefore(newObj, obj); // insert placeholder div that will be replaced by the object element that loads expressinstall.swf + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + createSWF(att, par, replaceElemIdStr); + } + } + + /* Functions to abstract and display alternative content + */ + function displayAltContent(obj) { + if (ua.ie && ua.win && obj.readyState != 4) { + // IE only: when a SWF is loading (AND: not available in cache) wait for the readyState of the object element to become 4 before removing it, + // because you cannot properly cancel a loading SWF file without breaking browser load references, also obj.onreadystatechange doesn't work + var el = createElement("div"); + obj.parentNode.insertBefore(el, obj); // insert placeholder div that will be replaced by the alternative content + el.parentNode.replaceChild(abstractAltContent(obj), el); + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + obj.parentNode.removeChild(obj); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.replaceChild(abstractAltContent(obj), obj); + } + } + + function abstractAltContent(obj) { + var ac = createElement("div"); + if (ua.win && ua.ie) { + ac.innerHTML = obj.innerHTML; + } + else { + var nestedObj = obj.getElementsByTagName(OBJECT)[0]; + if (nestedObj) { + var c = nestedObj.childNodes; + if (c) { + var cl = c.length; + for (var i = 0; i < cl; i++) { + if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) { + ac.appendChild(c[i].cloneNode(true)); + } + } + } + } + } + return ac; + } + + /* Cross-browser dynamic SWF creation + */ + function createSWF(attObj, parObj, id) { + var r, el = getElementById(id); + if (ua.wk && ua.wk < 312) { return r; } + if (el) { + if (typeof attObj.id == UNDEF) { // if no 'id' is defined for the object element, it will inherit the 'id' from the alternative content + attObj.id = id; + } + if (ua.ie && ua.win) { // Internet Explorer + the HTML object element + W3C DOM methods do not combine: fall back to outerHTML + var att = ""; + for (var i in attObj) { + if (attObj[i] != Object.prototype[i]) { // filter out prototype additions from other potential libraries + if (i.toLowerCase() == "data") { + parObj.movie = attObj[i]; + } + else if (i.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + att += ' class="' + attObj[i] + '"'; + } + else if (i.toLowerCase() != "classid") { + att += ' ' + i + '="' + attObj[i] + '"'; + } + } + } + var par = ""; + for (var j in parObj) { + if (parObj[j] != Object.prototype[j]) { // filter out prototype additions from other potential libraries + par += ''; + } + } + el.outerHTML = '' + par + ''; + objIdArr[objIdArr.length] = attObj.id; // stored to fix object 'leaks' on unload (dynamic publishing only) + r = getElementById(attObj.id); + } + else { // well-behaving browsers + var o = createElement(OBJECT); + o.setAttribute("type", FLASH_MIME_TYPE); + for (var m in attObj) { + if (attObj[m] != Object.prototype[m]) { // filter out prototype additions from other potential libraries + if (m.toLowerCase() == "styleclass") { // 'class' is an ECMA4 reserved keyword + o.setAttribute("class", attObj[m]); + } + else if (m.toLowerCase() != "classid") { // filter out IE specific attribute + o.setAttribute(m, attObj[m]); + } + } + } + for (var n in parObj) { + if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") { // filter out prototype additions from other potential libraries and IE specific param element + createObjParam(o, n, parObj[n]); + } + } + el.parentNode.replaceChild(o, el); + r = o; + } + } + return r; + } + + function createObjParam(el, pName, pValue) { + var p = createElement("param"); + p.setAttribute("name", pName); + p.setAttribute("value", pValue); + el.appendChild(p); + } + + /* Cross-browser SWF removal + - Especially needed to safely and completely remove a SWF in Internet Explorer + */ + function removeSWF(id) { + var obj = getElementById(id); + if (obj && obj.nodeName == "OBJECT") { + if (ua.ie && ua.win) { + obj.style.display = "none"; + (function(){ + if (obj.readyState == 4) { + removeObjectInIE(id); + } + else { + setTimeout(arguments.callee, 10); + } + })(); + } + else { + obj.parentNode.removeChild(obj); + } + } + } + + function removeObjectInIE(id) { + var obj = getElementById(id); + if (obj) { + for (var i in obj) { + if (typeof obj[i] == "function") { + obj[i] = null; + } + } + obj.parentNode.removeChild(obj); + } + } + + /* Functions to optimize JavaScript compression + */ + function getElementById(id) { + var el = null; + try { + el = doc.getElementById(id); + } + catch (e) {} + return el; + } + + function createElement(el) { + return doc.createElement(el); + } + + /* Updated attachEvent function for Internet Explorer + - Stores attachEvent information in an Array, so on unload the detachEvent functions can be called to avoid memory leaks + */ + function addListener(target, eventType, fn) { + target.attachEvent(eventType, fn); + listenersArr[listenersArr.length] = [target, eventType, fn]; + } + + /* Flash Player and SWF content version matching + */ + function hasPlayerVersion(rv) { + var pv = ua.pv, v = rv.split("."); + v[0] = parseInt(v[0], 10); + v[1] = parseInt(v[1], 10) || 0; // supports short notation, e.g. "9" instead of "9.0.0" + v[2] = parseInt(v[2], 10) || 0; + return (pv[0] > v[0] || (pv[0] == v[0] && pv[1] > v[1]) || (pv[0] == v[0] && pv[1] == v[1] && pv[2] >= v[2])) ? true : false; + } + + /* Cross-browser dynamic CSS creation + - Based on Bobby van der Sluis' solution: http://www.bobbyvandersluis.com/articles/dynamicCSS.php + */ + function createCSS(sel, decl, media, newStyle) { + if (ua.ie && ua.mac) { return; } + var h = doc.getElementsByTagName("head")[0]; + if (!h) { return; } // to also support badly authored HTML pages that lack a head element + var m = (media && typeof media == "string") ? media : "screen"; + if (newStyle) { + dynamicStylesheet = null; + dynamicStylesheetMedia = null; + } + if (!dynamicStylesheet || dynamicStylesheetMedia != m) { + // create dynamic stylesheet + get a global reference to it + var s = createElement("style"); + s.setAttribute("type", "text/css"); + s.setAttribute("media", m); + dynamicStylesheet = h.appendChild(s); + if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) { + dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1]; + } + dynamicStylesheetMedia = m; + } + // add style rule + if (ua.ie && ua.win) { + if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) { + dynamicStylesheet.addRule(sel, decl); + } + } + else { + if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) { + dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}")); + } + } + } + + function setVisibility(id, isVisible) { + if (!autoHideShow) { return; } + var v = isVisible ? "visible" : "hidden"; + if (isDomLoaded && getElementById(id)) { + getElementById(id).style.visibility = v; + } + else { + createCSS("#" + id, "visibility:" + v); + } + } + + /* Filter to avoid XSS attacks + */ + function urlEncodeIfNecessary(s) { + var regex = /[\\\"<>\.;]/; + var hasBadChars = regex.exec(s) != null; + return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s; + } + + /* Release memory to avoid memory leaks caused by closures, fix hanging audio/video threads and force open sockets/NetConnections to disconnect (Internet Explorer only) + */ + var cleanup = function() { + if (ua.ie && ua.win) { + window.attachEvent("onunload", function() { + // remove listeners to avoid memory leaks + var ll = listenersArr.length; + for (var i = 0; i < ll; i++) { + listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]); + } + // cleanup dynamically embedded objects to fix audio/video threads and force open sockets and NetConnections to disconnect + var il = objIdArr.length; + for (var j = 0; j < il; j++) { + removeSWF(objIdArr[j]); + } + // cleanup library's main closures to avoid memory leaks + for (var k in ua) { + ua[k] = null; + } + ua = null; + for (var l in swfobject) { + swfobject[l] = null; + } + swfobject = null; + }); + } + }(); + + return { + /* Public API + - Reference: http://code.google.com/p/swfobject/wiki/documentation + */ + registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) { + if (ua.w3 && objectIdStr && swfVersionStr) { + var regObj = {}; + regObj.id = objectIdStr; + regObj.swfVersion = swfVersionStr; + regObj.expressInstall = xiSwfUrlStr; + regObj.callbackFn = callbackFn; + regObjArr[regObjArr.length] = regObj; + setVisibility(objectIdStr, false); + } + else if (callbackFn) { + callbackFn({success:false, id:objectIdStr}); + } + }, + + getObjectById: function(objectIdStr) { + if (ua.w3) { + return getObjectById(objectIdStr); + } + }, + + embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) { + var callbackObj = {success:false, id:replaceElemIdStr}; + if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) { + setVisibility(replaceElemIdStr, false); + addDomLoadEvent(function() { + widthStr += ""; // auto-convert to string + heightStr += ""; + var att = {}; + if (attObj && typeof attObj === OBJECT) { + for (var i in attObj) { // copy object to avoid the use of references, because web authors often reuse attObj for multiple SWFs + att[i] = attObj[i]; + } + } + att.data = swfUrlStr; + att.width = widthStr; + att.height = heightStr; + var par = {}; + if (parObj && typeof parObj === OBJECT) { + for (var j in parObj) { // copy object to avoid the use of references, because web authors often reuse parObj for multiple SWFs + par[j] = parObj[j]; + } + } + if (flashvarsObj && typeof flashvarsObj === OBJECT) { + for (var k in flashvarsObj) { // copy object to avoid the use of references, because web authors often reuse flashvarsObj for multiple SWFs + if (typeof par.flashvars != UNDEF) { + par.flashvars += "&" + k + "=" + flashvarsObj[k]; + } + else { + par.flashvars = k + "=" + flashvarsObj[k]; + } + } + } + if (hasPlayerVersion(swfVersionStr)) { // create SWF + var obj = createSWF(att, par, replaceElemIdStr); + if (att.id == replaceElemIdStr) { + setVisibility(replaceElemIdStr, true); + } + callbackObj.success = true; + callbackObj.ref = obj; + } + else if (xiSwfUrlStr) { // show Adobe Express Install + if (confirm("Adobe Flash Player "+swfVersionStr+" 이상 버전이 필요합니다.\nCHEditor는 자동으로 Flash Player를 설치하지 않습니다.\n" + + "Adobe Flash Player 다운로드 웹사이트를 방문하시겠습니까?")) { + window.open(xiSwfUrlStr); + } + return; + } + else { // show alternative content + setVisibility(replaceElemIdStr, true); + } + if (callbackFn) { callbackFn(callbackObj); } + }); + } + else if (callbackFn) { callbackFn(callbackObj); } + }, + + switchOffAutoHideShow: function() { + autoHideShow = false; + }, + + ua: ua, + + getFlashPlayerVersion: function() { + return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] }; + }, + + hasFlashPlayerVersion: hasPlayerVersion, + + createSWF: function(attObj, parObj, replaceElemIdStr) { + if (ua.w3) { + return createSWF(attObj, parObj, replaceElemIdStr); + } + else { + return undefined; + } + }, + + showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) { + if (ua.w3 && canExpressInstall()) { + showExpressInstall(att, par, replaceElemIdStr, callbackFn); + } + }, + + removeSWF: function(objElemIdStr) { + if (ua.w3) { + removeSWF(objElemIdStr); + } + }, + + createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) { + if (ua.w3) { + createCSS(selStr, declStr, mediaStr, newStyleBoolean); + } + }, + + addDomLoadEvent: addDomLoadEvent, + + addLoadEvent: addLoadEvent, + + getQueryParamValue: function(param) { + var q = doc.location.search || doc.location.hash; + if (q) { + if (/\?/.test(q)) { q = q.split("?")[1]; } // strip question mark + if (param == null) { + return urlEncodeIfNecessary(q); + } + var pairs = q.split("&"); + for (var i = 0; i < pairs.length; i++) { + if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) { + return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1))); + } + } + } + return ""; + }, + + // For internal usage only + expressInstallCallback: function() { + if (isExpressInstallActive) { + var obj = getElementById(EXPRESS_INSTALL_ID); + if (obj && storedAltContent) { + obj.parentNode.replaceChild(storedAltContent, obj); + if (storedAltContentId) { + setVisibility(storedAltContentId, true); + if (ua.ie && ua.win) { storedAltContent.style.display = "block"; } + } + if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); } + } + isExpressInstallActive = false; + } + } + }; +}(); diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/symbol.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/symbol.js new file mode 100644 index 0000000..56e3b35 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/symbol.js @@ -0,0 +1,167 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var c = null; +var curView = null; +var S1 = '" ( ) [ ] { } ‘ ’ “ ” 〔 〕 〈 〉 《 》 「 」 『 』 【 】 § ※ ☆ ★ ○ ● ■ △ ▲ ▽ ▼ → 〓 ◁ ◀ ▷ ▶ ♤ ♣ ⊙ ◈ ▣ ◐ ◑ ▧ ▦ ▩ ♨ ☏ ☎ ‡ ㉿ ↕ ↗ ↙ ↖ ↘ ㈜ № ㏇ ™ ㏂ + - < = > ± × ÷ ≠ ≤ ≥ ∞ ∴ ♂ ♀ ∠ ⊥ ⌒ ∂ ∇ ≡ ≒ ≪ ≫ √ ∽ ∝ ∵ ∫ ∬ ∈ ∋ ⊆ ⊇ ⊂ ⊃ ∮ ∪ ∩ ∑ ∏ ∧ ∨ ¬ ⇒ ⇔ ∀ ∃'; +var S2 = '─ │ ┌ ┐ ┘ └ ├ ┬ ┤ ┴ ┼ ━ ┃ ┏ ┓ ┛ ┗ ┣ ┳ ┫ ┻ ╋ ┠ ┯ ┨ ┷ ┿ ┝ ┰ ┥ ┸ ╂ ┒ ┑ ┚ ┙ ┖ ┕ ┎ ┍ ┞ ┟ ┡ ┢ ┦ ┧ ┩ ┪ ┭ ┮ ┱ ┲ ┵ ┶ ┹ ┺ ┽ ┾ ╀ ╁ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊'; +var S3 = '½ ⅓ ⅔ ¼ ¾ ⅛ ⅜ ⅝ ⅞ ¹ ² ³ ⁴ ⁿ ₁ ₂ ₃ ₄ 0 1 2 3 4 5 6 7 8 9 ⅰ ⅱ ⅲ ⅳ ⅴ ⅵ ⅶ ⅷ ⅸ ⅹ Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ $ % ₩ ° ′ ″ ℃ Å ¢ £ ¥ ¤ ℉ ‰ ㎕ ㎖ ㎗ ℓ ㎘ ㏄ ㎣ ㎤ ㎥ ㎦ ㎙ ㎚ ㎛ ㎜ ㎝ ㎞ ㎟ ㎠ ㎡ ㎢ ㏊ ㎍ ㎎ ㎏ ㏏ ㎈ ㎉ ㏈ ㎧ ㎨ ㎰ ㎱ ㎲ ㎳ ㎴ ㎵ ㎶ ㎷ ㎸ ㎹ ㎀ ㎁ ㎂ ㎃ ㎄ ㎺ ㎻ ㎼ ㎽ ㎾ ㎿ ㎐ ㎑ ㎒ ㎓ ㎔ Ω ㏀ ㏁ ㎊ ㎋ ㎌ ㏖ ㏅ ㎭ ㎮ ㎯ ㏛ ㎩ ㎪ ㎫ ㎬ ㏝ ㏐ ㏓ ㏉ ㏜ ㏆'; +var S4 = 'ㅥ ㅦ ㅧ ㅨ ㅩ ㅪ ㅫ ㅬ ㅭ ㅮ ㅰ ㅯ ㅱ ㅲ ㅳ ㅴ ㅵ ㅶ ㅷ ㅸ ㅹ ㅺ ㅻ ㅼ ㅽ ㅾ ㅿ ㆀ ㆁ ㆂ ㆃ ㆄ ㆅ ㆆ ㆇ ㆈ ㆉ ㆊ ㆋ ㆌ ㆍ ㆎ'; +var S5 = '㉠ ㉡ ㉢ ㉣ ㉤ ㉥ ㉦ ㉧ ㉨ ㉩ ㉪ ㉫ ㉬ ㉭ ㉮ ㉯ ㉰ ㉱ ㉲ ㉳ ㉴ ㉶ ㉶ ㉷ ㉸ ㉹ ㉺ ㉻ ㈀ ㈁ ㈂ ㈃ ㈄ ㈅ ㈆ ㈇ ㈈ ㈉ ㈊ ㈋ ㈌ ㈍ ㈎ ㈏ ㈐ ㈑ ㈒ ㈓ ㈔ ㈕ ㈖ ㈗ ㈘ ㈙ ㈚ ㈛ ⓐ ⓑ ⓒ ⓓ ⓔ ⓕ ⓖ ⓗ ⓘ ⓙ ⓚ ⓛ ⓜ ⓝ ⓞ ⓟ ⓠ ⓡ ⓢ ⓣ ⓤ ⓥ ⓦ ⓧ ⓨ ⓩ ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ ⑪ ⑫ ⑬ ⑭ ⑮ ⒜ ⒝ ⒞ ⒟ ⒠ ⒡ ⒢ ⒣ ⒤ ⒥ ⒦ ⒧ ⒨ ⒩ ⒪ ⒫ ⒬ ⒭ ⒮ ⒯ ⒰ ⒱ ⒲ ⒳ ⒴ ⒵ ⑴ ⑵ ⑶ ⑷ ⑸ ⑹ ⑺ ⑻ ⑼ ⑽ ⑾ ⑿ ⒀ ⒁ ⒂'; +var japan1 = 'ぁ か さ た ど び ぽ ょ ゑ あ が ざ だ な ぴ ま よ を ぃ き し ち に ふ み ら ん い ぎ じ ぢ ぬ ぶ む り ぅ く す っ ね ぷ め る う ぐ ず つ の へ も れ ぇ け せ づ は べ ゃ ろ え げ ぜ て ば ぺ や ゎ ぉ こ そ で ぱ ほ ゅ わ お ご ぞ と ひ ぼ ゆ ゐ'; +var japan2 = 'ァ カ サ タ ド ビ ポ ョ ヱ ア ガ ザ ダ ナ ピ マ ヨ ヲ ィ キ シ チ ニ フ ミ ラ ン イ ギ ジ ヂ ヌ ブ ム リ ヴ ゥ ク ス ッ ネ プ メ ル ヵ ウ グ ズ ツ ノ ヘ モ レ ヶ ェ ケ セ ヅ ハ ベ ャ ロ エ ゲ ゼ テ バ ペ ヤ ヮ ォ コ ソ デ パ ホ ュ ワ オ ゴ ゾ ト ヒ ボ ユ ヰ'; + +c = S1.split(' '); +var button = [ { alt : "", img : 'input.gif', cmd : inputChar }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + +var oEditor = null; + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + + setupEvent(); + dlg.setDialogHeight(); +} + +function hover(obj, val) { + obj.style.backgroundColor = val ? "#5579aa" : "#fff"; + obj.style.color = val ? "#fff" : "#000"; +} + +function showTable() { + var k = 0; + var len = c.length; + var w = 9; + var h = 20; + var span, i, j, tr, td; + + var table = document.createElement('table'); + table.border = 0; + table.cellSpacing = 1; + table.cellPadding = 0; + table.align = 'center'; + + var getChar = function() { + document.getElementById('fm_input').value = document.getElementById('fm_input').value + c[this.id]; + }; + var mouseOver = function() { + hover(this, true); + }; + var mouseOut = function() { + hover(this, false); + }; + for (i=0; i < w; i++) { + tr = table.insertRow(i); + for (j = 0; j < h; j++) { + td = tr.insertCell(j); + td.className = 'schar'; + + if ( len < k+1) { + td.appendChild(document.createTextNode('\u00a0')); + } + else { + td.style.cursor = 'pointer'; + td.id = k; + td.onclick = getChar; + td.onmouseover = mouseOver; + td.onmouseout = mouseOut; + span = document.createElement("span"); + span.style.fontSize = "13px"; + span.appendChild(document.createTextNode(c[k])); + td.appendChild(span); + } + k++; + } + } + + var output = document.getElementById('output'); + if (output.hasChildNodes()) { + for (i=0; i 0) { + cell = createHeadCell('col'); + } + else { + cell = document.createElement('td'); + } + } + else if (header === 'row' && j === 0) { + cell = createHeadCell('row'); + } + else { + cell = document.createElement('td'); + } + + if (border) { + cell.style.borderStyle = 'solid'; + cell.style.borderWidth = table.style.borderWidth; + cell.style.borderColor = table.style.borderColor; + } +// cell.setAttribute("width", cellWidth); + cell.appendChild(document.createTextNode('\u00a0')); + row.appendChild(cell); + } + } + + if (oHead.hasChildNodes()) { + table.appendChild(oHead); + } + + table.appendChild(oBody); + + if (summaryValue !== '') { + table.setAttribute('summary', summaryValue); + } + if (width) { + table.style.width = width; + } + if (height) { + table.style.height = height; + } + if (align) { + table.setAttribute("align", align); + } + if (bgcolor) { + table.setAttribute("bgcolor", bgcolor); + } + + table.setAttribute("cellpadding", cellpd); + table.setAttribute("cellspacing", cellsp); + + if (captionValue !== '') { + var hideCaption, tableCaption; + tableCaption = table.createCaption(); + tableCaption.appendChild(document.createTextNode(captionValue)); + + hideCaption = document.getElementById('hideCaption'); + if (hideCaption.checked === true) { + tableCaption.style.visibility = 'hidden'; + tableCaption.style.overFlow = 'hidden'; + tableCaption.style.lineHeight = '0px'; + tableCaption.style.position = 'absolute'; + tableCaption.style.display = 'none'; + } + } + + table.id = oEditor.makeRandomString(); + oEditor.insertHtmlPopup(table.cloneNode(true)); + var newTable = oEditor.$(table.id); + newTable.removeAttribute('id'); + + if (cssclass) { + newTable.className = cssclass; + } + if (cssid) { + newTable.id = cssid; + } + + var focusCell = newTable.getElementsByTagName('th')[0]; + if (oEditor.undefined(focusCell)) { + focusCell = newTable.getElementsByTagName('td')[0]; + } + + if (oEditor.getBrowser().msie) { + var cursor = oEditor.doc.body.createTextRange(); + cursor.moveToElementText(focusCell); + cursor.collapse(false); + cursor.select(); + oEditor.backupRange(oEditor.getRange()); + } + else { + var selection = oEditor.getSelection(); + var range = oEditor.getRange(); + range.selectNodeContents(focusCell); + range.collapse(false); + selection.removeAllRanges(); + selection.addRange(range); + } + + oEditor.popupWinClose(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); +} diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/js/table_modify.js b/AvocadoEdition/plugin/editor/cheditor5/popup/js/table_modify.js new file mode 100644 index 0000000..3e95fd2 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/js/table_modify.js @@ -0,0 +1,640 @@ +// ================================================================ +// CHEditor 5 +// ---------------------------------------------------------------- +// Homepage: http://www.chcode.com +// Copyright (c) 1997-2014 CHSOFT +// ================================================================ +var oEditor = null; +var button = [ { alt : "", img : 'submit.gif', cmd : doSubmit }, + { alt : "", img : 'cancel.gif', cmd : popupClose } ]; + +var colour = ["ffffcc","ffcc66","ff9900","ffcc99","ff6633","ffcccc","cc9999","ff6699","ff99cc","ff66cc","ffccff","cc99cc","cc66ff","cc99ff","9966cc","ccccff","9999cc","3333ff","6699ff","0066ff","99ccff","66ccff","99cccc","ccffff","99ffcc","66cc99","66ff99","99ff99","ccffcc","33ff33","66ff00","ccff99","99ff00","ccff66","cccc66","ffffff", + "ffff99","ffcc00","ff9933","ff9966","cc3300","ff9999","cc6666","ff3366","ff3399","ff00cc","ff99ff","cc66cc","cc33ff","9933cc","9966ff","9999ff","6666ff","3300ff","3366ff","0066cc","3399ff","33ccff","66cccc","99ffff","66ffcc","33cc99","33ff99","66ff66","99cc99","00ff33","66ff33","99ff66","99ff33","ccff00","cccc33","cccccc", + "ffff66","ffcc33","cc9966","ff6600","ff3300","ff6666","cc3333","ff0066","ff0099","ff33cc","ff66ff","cc00cc","cc00ff","9933ff","6600cc","6633ff","6666cc","3300cc","0000ff","3366cc","0099ff","00ccff","339999","66ffff","33ffcc","00cc99","00ff99","33ff66","66cc66","00ff00","33ff00","66cc00","99cc66","ccff33","999966","999999", + "ffff33","cc9900","cc6600","cc6633","ff0000","ff3333","993333","cc3366","cc0066","cc6699","ff33ff","cc33cc","9900cc","9900ff","6633cc","6600ff","666699","3333cc","0000cc","0033ff","6699cc","3399cc","669999","33ffff","00ffcc","339966","33cc66","00ff66","669966","00cc00","33cc00","66cc33","99cc00","cccc99","999933","666666", + "ffff00","cc9933","996633","993300","cc0000","ff0033","990033","996666","993366","cc0099","ff00ff","990099","996699","660099","663399","330099","333399","000099","0033cc","003399","336699","0099cc","006666","00ffff","33cccc","009966","00cc66","339933","336633","33cc33","339900","669933","99cc33","666633","999900","333333", + "cccc00","996600","663300","660000","990000","cc0033","330000","663333","660033","990066","cc3399","993399","660066","663366","330033","330066","333366","000066","000033","003366","006699","003333","336666","00cccc","009999","006633","009933","006600","003300","00cc33","009900","336600","669900","333300","666600","000000"]; + +var none = '없음'; +var modifyTable; +var beforeHeaderType; +var whichColor = null; + +function popupClose() { + oEditor.popupWinCancel(); +} + +function isError() { + alert('표 정보를 얻을 수 없습니다. 수정하실 표을 다시 한 번 선택해 주십시오.'); + popupClose(); +} + +function init(dialog) { + oEditor = this; + oEditor.dialog = dialog; + + var dlg = new Dialog(oEditor); + dlg.showButton(button); + dlg.setDialogHeight(); + + var rng = oEditor.range, pNode; + + if (oEditor.W3CRange) { + pNode = rng.commonAncestorContainer; + if (!rng.collapsed && + rng.startContainer === rng.endContainer && + rng.startOffset - rng.endOffset < 2 && + rng.startContainer.hasChildNodes()) + { + pNode = rng.startContainer.childNodes[rng.startOffset]; + } + + while (pNode.nodeType === 3) { + pNode = pNode.parentNode; + } + + if (pNode.nodeName !== 'TD' && pNode.nodeName !== 'TH' && pNode.nodeName !== 'CAPTION' && pNode.nodeName !== 'TABLE') + { + isError(); + return; + } + } + else { + if (rng.item) { + pNode = rng.item(0); + if (pNode.nodeName.toLowerCase() !== 'table') { + isError(); + return; + } + } + else { + pNode = rng.parentElement(); + } + } + + while (pNode && pNode.nodeName.toLowerCase() !== 'table') { + pNode = pNode.parentNode; + } + + if (pNode.nodeName.toLowerCase() !== 'table') { + isError(); + return; + } + + modifyTable = pNode; + var border, el_size, fm_size, el_type, fm_type, cellpd, cellsp, bgcolor, idbgcolor, + bordercolor, idbordercolor, captionValue, summaryValue, caption, captionInput, summary; + + border = modifyTable.getAttribute('border'); + if (!border || isNaN(border)) { + border = parseInt(modifyTable.style.borderWidth, 10); + if (!border) { + border = 0; + } + } + document.getElementById("bordersize").value = border; + + if (modifyTable.className !== '') { + document.getElementById('cssClass').value = modifyTable.className; + } + if (modifyTable.id !== '') { + document.getElementById('cssId').value = modifyTable.id; + } + + el_size = modifyTable.getAttribute('width'); + if (!el_size) { + el_size = modifyTable.style.width; + } + + fm_size = document.getElementById("width"); + el_type = 'px'; + fm_type = document.getElementById("widthtype"); + + if (el_size) { + el_type = (/%$/.test(el_size)) ? '%' : 'px'; + el_size = parseInt(el_size, 10); + if (isNaN(el_size)) { + el_size = ''; + } + } + else { + el_size = ''; + } + + fm_size.value = el_size; + fm_type.value = el_type; + + el_size = modifyTable.getAttribute('height'); + if (!el_size) { + el_size = modifyTable.style.height; + } + fm_size = document.getElementById("height"); + el_type = 'px'; + fm_type = document.getElementById("heighttype"); + + if (el_size) { + el_type = (/\%$/.test(el_size)) ? '%' : 'px'; + el_size = parseInt(el_size, 10); + if (isNaN(el_size)) { + el_size = ''; + } + } + else { + el_size = ''; + } + + fm_size.value = el_size; + fm_type.value = el_type; + + fm_type = modifyTable.getAttribute('align'); + if (!fm_type) { + fm_type = 'none'; + } + document.getElementById("talign").value = fm_type; + + cellpd = modifyTable.getAttribute('cellpadding'); + if (isNaN(cellpd)) { + cellpd = 0; + } + document.getElementById("cellpd").value = cellpd || 0; + + cellsp = modifyTable.getAttribute('cellspacing'); + if (isNaN(cellsp)) { + cellsp = 0; + } + document.getElementById("cellsp").value = cellsp || 0; + + bgcolor = modifyTable.getAttribute('bgcolor'); + idbgcolor = document.getElementById("idbgcolor"); + if (bgcolor) { + if (/rgb/.test(bgcolor)) { + bgcolor = oEditor.colorConvert(bgcolor, 'hex'); + } + idbgcolor.value = bgcolor.toLowerCase(); + idbgcolor.style.backgroundColor = idbgcolor.value; + } + else { + idbgcolor.value = none; + } + + bordercolor = modifyTable.getAttribute('bordercolor'); + if (!bordercolor) { + bordercolor = modifyTable.style.borderColor; + if (bordercolor) { + bordercolor = oEditor.colorConvert(bordercolor, 'hex'); + } + else { + bordercolor = null; + } + } + + idbordercolor = document.getElementById("idbordercolor"); + if (bordercolor) { + if (/rgb/.test(bordercolor)) { + bordercolor = oEditor.colorConvert(bordercolor, 'hex'); + } + idbordercolor.value = bordercolor.toLowerCase(); + idbordercolor.style.backgroundColor = idbordercolor.value; + } + else { + idbordercolor.value = none; + } + + caption = modifyTable.getElementsByTagName('caption')[0]; + if (caption) { + captionValue = oEditor.trimSpace(caption.innerHTML); + if (captionValue !== '') { + captionInput = document.getElementById('tableCaption'); + captionInput.value = captionValue; + + if (caption.style.visibility === 'hidden') { + document.getElementById('hideCaption').checked = 'checked'; + } + } + } + + summaryValue = modifyTable.getAttribute('summary'); + if (summaryValue) { + summaryValue = oEditor.trimSpace(summaryValue); + if (summaryValue !== '') { + summary = document.getElementById('tableSummary'); + summary.value = summaryValue; + } + } + + var tableHeader, rows, i, j, cells, headCol, headRow, rowLength, rowCellLength, cellLength, header, headTagName; + headCol = headRow = null; + headTagName = 'th'; + + tableHeader = document.getElementById('tableHeader'); + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? modifyTable.rows : modifyTable.getElementsByTagName('tr'); + rowLength = rows.length; + + document.getElementById('numrows').appendChild(document.createTextNode(rowLength)); + + if (rowLength > 0) { + cells = rows[0].cells; + cellLength = cells.length; + if (cellLength > 0) { + for (j=0; j < cellLength; j++) { + if (cells[j].tagName.toLowerCase() === headTagName) { + headCol = 'col'; + } + else { + headCol = null; + break; + } + } + } + + rowCellLength = 0; + for (i=0; i < rowLength; i++) { + headRow = (rows[i].cells[0] && rows[i].cells[0].tagName.toLowerCase() === headTagName) ? 'row' : null; + if (rowCellLength < rows[i].cells.length) { + rowCellLength = rows[i].cells.length; + } + } + + if (headRow && headCol && cellLength === 1) { + headCol = null; + } + document.getElementById('numcols').appendChild(document.createTextNode(rowCellLength)); + } + + header = (headCol && headRow) ? 'all' : headCol || headRow || 'none'; + tableHeader.value = beforeHeaderType = header; +} + +function getColor() +{ + var color = this.bgColor; + var input = document.getElementById("id"+whichColor); + input.style.backgroundColor = input.value = color; +} + +function drawColor() { + var table, tr, td, insideTable, k = 0, i, j, tr2, td2; + + table = document.createElement('table'); + table.cellPadding = 0; + table.cellSpacing = 0; + table.border = 0; + table.align = 'center'; + tr = table.insertRow(0); + td = tr.insertCell(0); + td.style.backgroundColor = '#fff'; + + insideTable = document.createElement('table'); + insideTable.border = 0; + insideTable.cellSpacing = 1; + insideTable.cellPadding = 0; + insideTable.align = 'center'; + + var onMouseOver = function() { this.className = 'colorCellMouseOver'; }; + var onMouseOut = function() { this.className = 'colorCellMouseOut'; }; + + for (i = 0; i < 6; i++) { + tr2 = insideTable.insertRow(i); + for (j = 0; j < 36; j++) { + td2 = tr2.insertCell(j); + td2.setAttribute('bgColor', '#' + colour[k]); + td2.className = 'colorCellMouseOut'; + td2.onclick = getColor; + td2.appendChild(document.createTextNode('\u00a0')); + td2.onmouseover = onMouseOver; + td2.onmouseout = onMouseOut; + k++; + } + } + + td.appendChild(insideTable); + document.getElementById('colorWrapper').appendChild(table); +} + +function setColor(which) { + whichColor = which; +} + +function doSubmit() +{ + var width, widthType, widthValue, cellWidth, i, j, row, rows, cell; + width = document.getElementById("width"); + widthType = document.getElementById("widthtype").value; + if (width) { + widthValue = parseInt(oEditor.trimSpace(width.value), 10); + if (isNaN(widthValue)) { + cellWidth = widthValue = null; + } + else { + modifyTable.removeAttribute('width'); + modifyTable.style.width = widthValue + widthType; + rows = modifyTable.rows; + if (rows.length > 0) { + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cellWidth = parseInt(widthValue/row.cells.length, 10) + widthType; + cell = row.cells[j]; + cell.setAttribute("width", cellWidth); + } + } + } + } + } + + var height, heightValue; + height = document.getElementById("height"); + if (height) { + heightValue = parseInt(oEditor.trimSpace(height.value), 10); + if (isNaN(heightValue)) { + heightValue = null; + } + else { + heightValue += document.getElementById("heighttype").value; + modifyTable.removeAttribute('height'); + modifyTable.style.height = heightValue; + } + } + + var cellpadding, cellpaddingValue; + cellpadding = document.getElementById("cellpd"); + if (cellpadding) { + cellpaddingValue = oEditor.trimSpace(cellpadding.value); + if (!cellpaddingValue || isNaN(cellpaddingValue)) { + cellpaddingValue = 0; + } + else { + cellpaddingValue = parseInt(cellpaddingValue, 10); + } + modifyTable.setAttribute('cellpadding', cellpaddingValue); + } + + var cellspacing, cellspacingValue; + cellspacing = document.getElementById("cellsp"); + if (cellspacing) { + cellspacingValue = oEditor.trimSpace(cellspacing.value); + if (!cellspacingValue || isNaN(cellspacingValue)) { + cellspacingValue = 0; + } + else { + cellspacingValue = parseInt(cellspacingValue, 10); + } + modifyTable.setAttribute('cellspacing', cellspacingValue); + } + + var bgcolor, bgcolorValue; + bgcolor = document.getElementById("idbgcolor"); + if (bgcolor) { + bgcolorValue = oEditor.trimSpace(bgcolor.value); + if (bgcolorValue !== '' && bgcolorValue !== none) { + modifyTable.removeAttribute('bgcolor'); + modifyTable.bgColor = bgcolorValue; + } + } + + var align, alignValue; + align = document.getElementById("talign"); + if (align) { + alignValue = align.value; + if (alignValue !== 'none') { + modifyTable.removeAttribute('align'); + modifyTable.setAttribute('align', alignValue); + } + } + + var cssclass, cssclassValue, cssid, cssidValue; + cssclass = document.getElementById('cssClass'); + cssclassValue = oEditor.trimSpace(cssclass.value); + if (cssclassValue !== '') { + modifyTable.className = cssclassValue; + } + else { + modifyTable.removeAttribute('class'); + } + + cssid = document.getElementById('cssId'); + cssidValue = oEditor.trimSpace(cssid.value); + if (cssidValue !== '') { + modifyTable.id = cssidValue; + } + else { + modifyTable.removeAttribute('id'); + } + + var caption = document.getElementById('tableCaption'); + var captionValue = oEditor.trimSpace(caption.value); + var summary = document.getElementById('tableSummary'); + var summaryValue = oEditor.trimSpace(summary.value); + var oCaption; + + if (summaryValue !== '') { + modifyTable.setAttribute('summary', summaryValue); + } + if (captionValue !== '') { + var hideCaption, tableCaption; + tableCaption = modifyTable.createCaption(); + tableCaption.innerHTML = captionValue; + + hideCaption = document.getElementById('hideCaption'); + if (hideCaption.checked === true) { + tableCaption.style.visibility = 'hidden'; + tableCaption.style.overFlow = 'hidden'; + tableCaption.style.lineHeight = '0px'; + tableCaption.style.position = 'absolute'; + tableCaption.style.display = 'none'; + } + else { + tableCaption.removeAttribute('style'); + } + } + else { + oCaption = modifyTable.getElementsByTagName('caption')[0]; + if (oCaption) { + modifyTable.removeChild(oCaption); + } + } + + var copyAttribute = function(target, source) { + var attr, attrValue, nodeName; + attr = source.attributes; + for (i=0; i= 0; j--) { + row.deleteCell(j); + } + + for (j=0; j < newCells.length; j++) { + row.appendChild(newCells[j]); + } + + if (newTagName === 'th') { + oHead = modifyTable.getElementsByTagName('thead')[0]; + if (!oHead) { + oHead = document.createElement('thead'); + modifyTable.insertBefore(oHead, modifyTable.firstChild); + oHead.appendChild(row); + } + } + else if (row.parentNode.nodeName.toLowerCase() === 'thead') { + oHead = row.parentNode; + if (rows[1]) { + rows[1].parentNode.insertBefore(row, rows[1]); + } + else { + modifyTable.insertBefore(row, oHead); + } + modifyTable.removeChild(oHead); + } + }; + + var replaceRow = function (rows, newTagName) { + var len, newCell, sourceCell; + len = rows.length; + for (i=0; i < len; i++) { + row = rows[i]; + sourceCell = row.cells[0]; + newCell = document.createElement(newTagName); + + if (newTagName === 'th') { + newCell.setAttribute('scope', 'row'); + } + else { + sourceCell.removeAttribute('scope'); + } + + row.insertBefore(newCell, sourceCell); + copyAttribute(newCell, sourceCell); + copyChildNodes(newCell, sourceCell); + row.deleteCell(1); + } + }; + + var border, borderValue; + if (beforeHeaderType !== tableHeader) { + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? + modifyTable.rows : + modifyTable.getElementsByTagName('tr'); + + if (tableHeader === 'col') { + replaceRow(rows, 'td'); + replaceCol(rows, 'th'); + } + else if (tableHeader === 'row') { + replaceCol(rows, 'td'); + replaceRow(rows, 'th'); + } + else if (tableHeader === 'all') { + replaceCol(rows, 'th'); + replaceRow(rows, 'th'); + } + else if (tableHeader === 'none') { + replaceCol(rows, 'td'); + replaceRow(rows, 'td'); + } + + oCaption = modifyTable.getElementsByTagName('caption')[0]; + if (oCaption && oCaption !== modifyTable.firstChild) { + modifyTable.insertBefore(oCaption, modifyTable.firstChild); + } + } + + + border = document.getElementById("bordersize"); + if (border) { + borderValue = oEditor.trimSpace(border.value); + if (isNaN(borderValue) === false) { + var borderColor, borderColorValue; + borderValue = parseInt(borderValue, 10); + rows = (modifyTable.rows && modifyTable.rows.length > 0) ? + modifyTable.rows : + modifyTable.getElementsByTagName('tr'); + + if (borderValue) { + borderColor = document.getElementById("idbordercolor"); + if (borderColor) { + borderColorValue = oEditor.trimSpace(borderColor.value); + } + if (!borderColorValue || borderColorValue === none) { + borderColorValue = '#000000'; + } + + borderColorValue = oEditor.colorConvert(borderColorValue, 'rgb'); + + modifyTable.style.border = borderValue + 'px solid ' + borderColorValue; + modifyTable.style.borderCollapse = "collapse"; + modifyTable.removeAttribute('border'); + + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cell = row.cells[j]; + cell.style.border = borderValue + 'px solid ' + borderColorValue; + } + } + } + else if (borderValue === 0) { + modifyTable.removeAttribute('border'); + modifyTable.style.border = ''; + modifyTable.style.borderCollapse = ''; + for (i=0; i < rows.length; i++) { + row = rows[i]; + for (j=0; j < row.cells.length; j++) { + cell = row.cells[j]; + cell.style.border = ''; + } + } + } + } + } + + oEditor.editArea.focus(); + oEditor.backupRange(oEditor.restoreRange()); + oEditor.clearStoredSelections(); + oEditor.popupWinClose(); +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/link.html b/AvocadoEdition/plugin/editor/cheditor5/popup/link.html new file mode 100644 index 0000000..11a55cb --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/link.html @@ -0,0 +1,70 @@ + + + + CHEditor + + + + + + + +
    +
    + + + + + +
    + + + + + + + + + + + + + + + +
    유형: + + + 타겟: + + +
    URL: + + +
    타이틀: + + +
    +
    +
    +
    +
    + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/media.html b/AvocadoEdition/plugin/editor/cheditor5/popup/media.html new file mode 100644 index 0000000..a2addd7 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/media.html @@ -0,0 +1,40 @@ + + + + CHEditor + + + + + + + +
    +
    미디어 재생 + + + + +
    +
    +
    +
    +
    +
    미디어 파일 URL + + + + + + + +
    + URL 입력: +
    + +
    +
    +
    +
    + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/symbol.html b/AvocadoEdition/plugin/editor/cheditor5/popup/symbol.html new file mode 100644 index 0000000..f7576fb --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/symbol.html @@ -0,0 +1,26 @@ + + + + CHEditor + + + + + + + + | + | + | + | + | + +
    + +
    +
    + 선택한 문자: +
    +
    + + diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/table.html b/AvocadoEdition/plugin/editor/cheditor5/popup/table.html new file mode 100644 index 0000000..a35b258 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/table.html @@ -0,0 +1,178 @@ + + + + CHEditor + + + + + + + +
    표 속성 +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    줄 수: + + 칸 수: + +

    너비: + + + + 높이: + + + +
    셀 안 여백: + + 셀 간격: + +
    테두리 굵기: +  픽셀 + 정렬: + +

    표 제목: + + 표 제목 숨김: +
    표 요약: + + 표 헤더: + +

    CSS class: + + CSS id: + +
    +
    +
    +
    +
    색 지정 +
    + + + + + + + +
    테두리 색: + +
    + +
    +
     
    +
    표 배경색: + +
    + +
    +
     
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/popup/table_modify.html b/AvocadoEdition/plugin/editor/cheditor5/popup/table_modify.html new file mode 100644 index 0000000..4a84260 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/popup/table_modify.html @@ -0,0 +1,180 @@ + + + + CHEditor + + + + + + + +
    표 속성 +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    줄 수: + + 칸 수: + +

    너비: + + + + 높이: + + + +
    셀 안 여백: + + 셀 간격: + +
    테두리 굵기: + + 정렬: + +

    표 제목: + + 표 제목 숨김: + +
    표 요약: + + 표 헤더: + +

    CSS class: + + CSS id: + +
    +
    +
    +
    +
    색 지정 +
    + + + + + + + +
    테두리 색: + +
    + +
    +
     
    +
    표 배경색: + +
    + +
    +
     
    +
    +
    +
    +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/template.xml b/AvocadoEdition/plugin/editor/cheditor5/template.xml new file mode 100644 index 0000000..338fd38 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/template.xml @@ -0,0 +1,368 @@ + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/cheditor5/utils/crossdomain.xml b/AvocadoEdition/plugin/editor/cheditor5/utils/crossdomain.xml new file mode 100644 index 0000000..937dc72 --- /dev/null +++ b/AvocadoEdition/plugin/editor/cheditor5/utils/crossdomain.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2Skin.html b/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2Skin.html new file mode 100644 index 0000000..ea6d9ac --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2Skin.html @@ -0,0 +1,786 @@ + + + + + + +네이버 :: Smart Editor 2 ™ + + + + + + + + + + + + + + + + + + +
    +
    글쓰기영역으로 바로가기 +
    + +
    +
      +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +
      + +
    • + +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +
      + +
    • +
      +
    • + +
    • + +
    • + +
    • + +
    • + + + +
    • + +
    • + + + +
    • + +
    • + +
    • +
      +
    • + +
    • + +
    • + +
    • + +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +

      직접 입력

      + + + + + +
      + +
      +
      +
      +
      + +
    • +
      +
    • +
      +
        +
      • +
      • +
      • +
      • +
      +
      +
    • +
      +
    • + + + +
    • +
      + + +
    • + +
      +
      +
      +
        +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      +

      + +

      +
      +
      +
      + +
    • + +
    • + + +
      +
      +
      +
      + 칸수 지정 +
      +
      +
      + + +
      +
      +
      + + +
      +
      + + + + + + + + + + + + + + + + + + + +
          
          
          
      +
      +
      + 속성직접입력 +
      +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + 표스타일 +
      +
      +
      + + + +
      +
      +
      +

      + +

      + +
      + +
      +
      +
      + + +
    • + +
    • + + +
      +
      +
      + +

      찾기/바꾸기

      +
        +
      • +
      • +
      +
      +
      +
      +
      +

      + +

      +
      + + +
      +
      +
      + + +
    • +
    +
      +
    • +
    +
    + +
    + + + + + +
    + +
    + + + + + + + + + +
    + + +
    + + +
    + + + + +
    + + +
    + + +
    +
    + + +
    + +
      +
    • +
    • +
    • +
    +
    + +
    + +
    +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2_noframe.html b/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2_noframe.html new file mode 100644 index 0000000..136575c --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/SmartEditor2_noframe.html @@ -0,0 +1,841 @@ + + + + + + +네이버 :: Smart Editor 2 ™ + + + + + + + + + + + + + + + +Version: 2.8.2.12056 + + +
    +
    글쓰기영역으로 바로가기 +
    + +
    +
      +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +
      + +
    • + +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +
      + +
    • +
      +
    • + +
    • + +
    • + +
    • + +
    • + + + +
    • + +
    • + + + +
    • + +
    • + +
    • +
      +
    • + +
    • + +
    • + +
    • + +
    • + +
    • + +
    • + +
    • + +
    • + +
      +
      +
        +
      • +
      • +
      • +
      • +
      • +
      • +
      • +
      +
      +

      직접 입력

      + + + + + +
      + +
      +
      +
      +
      + +
    • +
      +
    • + + + +
    • +
      + + +
    • + +
      +
      +
      +
        +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      • +
        +
          +
        • + + +
        +
        +
      • +
      +

      + +

      +
      +
      +
      + +
    • + +
    • + + +
      +
      +
      +
      + 칸수 지정 +
      +
      +
      + + +
      +
      +
      + + +
      +
      + + + + + + + + + + + + + + + + + + + +
          
          
          
      +
      +
      + 속성직접입력 +
      +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + + + +
      +
      +
      +
      +
      +
      + 표스타일 +
      +
      +
      + + + +
      +
      +
      +

      + +

      + +
      + +
      +
      +
      + + +
    • + +
    • + + +
      +
      +
      + +

      찾기/바꾸기

      +
        +
      • +
      • +
      +
      +
      +
      +
      +

      + +

      +
      + + +
      +
      +
      + + +
    • +
    +
      +
    • +
    +
    + +
    + + + + + +
    + +
    + + + + + + + + + +
    + + +
    + + +
    + + + + +
    + + +
    + + +
    +
    + + +
    + +
      +
    • +
    • +
    • +
    +
    + +
    + +
    +
    + + + +
    + + + + +
    + +
    +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/autosave.editor.js b/AvocadoEdition/plugin/editor/smarteditor2/autosave.editor.js new file mode 100644 index 0000000..4997876 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/autosave.editor.js @@ -0,0 +1,13 @@ +function get_editor_wr_content() +{ + return oEditors.getById['wr_content'].getIR();; +} + +function put_editor_wr_content(content) +{ + oEditors.getById["wr_content"].exec("SET_CONTENTS", [""]); + //oEditors.getById["wr_content"].exec("SET_IR", [""]); + oEditors.getById["wr_content"].exec("PASTE_HTML", [content]); + + return; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/config.js b/AvocadoEdition/plugin/editor/smarteditor2/config.js new file mode 100644 index 0000000..1082152 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/config.js @@ -0,0 +1,29 @@ +(function($){ + $(document).ready(function() { + $(".smarteditor2").each( function(index){ + var get_id = $(this).attr("id"); + + if( !get_id || $(this).prop("nodeName") != 'TEXTAREA' ) return true; + + nhn.husky.EZCreator.createInIFrame({ + oAppRef: oEditors, + elPlaceHolder: get_id, + sSkinURI: g5_editor_url+"/SmartEditor2Skin.html", + htParams : { + bUseToolbar : true, // 툴바 사용 여부 (true:사용/ false:사용하지 않음) + bUseVerticalResizer : true, // 입력창 크기 조절바 사용 여부 (true:사용/ false:사용하지 않음) + bUseModeChanger : true, // 모드 탭(Editor | HTML | TEXT) 사용 여부 (true:사용/ false:사용하지 않음) + aAdditionalFontList : [['Noto Sans KR', 'Noto Sans KR'],['Nanum Gothic', '나눔고딕'],['Nanum Myeongjo', '나눔명조'],['aphopis', 'APHOPIS']], // 추가 글꼴 목록 + fOnBeforeUnload : function(){ + //alert("완료!"); + } + }, //boolean + fOnAppLoad : function(){ + //예제 코드 + //oEditors.getById["ir1"].exec("PASTE_HTML", ["로딩이 완료된 후에 본문에 삽입되는 text입니다."]); + }, + fCreator: "createSEditor2" + }); + }); + }); +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2.css b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2.css new file mode 100644 index 0000000..020e2d1 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2.css @@ -0,0 +1,175 @@ +@charset "UTF-8"; +/* NHN Web Standardization Team (http://html.nhndesign.com/) HHJ 090226 */ +/* COMMON */ +body,#smart_editor2,#smart_editor2 p,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 ul,#smart_editor2 ol,#smart_editor2 li,#smart_editor2 dl,#smart_editor2 dt,#smart_editor2 dd,#smart_editor2 table,#smart_editor2 th,#smart_editor2 td,#smart_editor2 form,#smart_editor2 fieldset,#smart_editor2 legend,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 button,#smart_editor2 select{margin:0;padding:0} +#smart_editor2,#smart_editor2 h1,#smart_editor2 h2,#smart_editor2 h3,#smart_editor2 h4,#smart_editor2 h5,#smart_editor2 h6,#smart_editor2 input,#smart_editor2 textarea,#smart_editor2 select,#smart_editor2 table,#smart_editor2 button{font-family:'돋움',Dotum,Helvetica,sans-serif;font-size:12px;color:#666} +#smart_editor2 span,#smart_editor2 em{font-size:12px} +#smart_editor2 em,#smart_editor2 address{font-style:normal} +#smart_editor2 img,#smart_editor2 fieldset{border:0} +#smart_editor2 hr{display:none} +#smart_editor2 ol,#smart_editor2 ul{list-style:none} +#smart_editor2 button{border:0;background:none;font-size:11px;vertical-align:top;cursor:pointer} +#smart_editor2 button span,#smart_editor2 button em{visibility:hidden;overflow:hidden;position:absolute;top:0;font-size:0;line-height:0} +#smart_editor2 legend,#smart_editor2 .blind{visibility:hidden;overflow:hidden;position:absolute;width:0;height:0;font-size:0;line-height:0} +#smart_editor2 .input_ty1{height:14px;margin:0;padding:4px 2px 0 4px;border:1px solid #c7c7c7;font-size:11px;color:#666} +#smart_editor2 a:link,#smart_editor2 a:visited,#smart_editor2 a:active,#smart_editor2 a:focus{color:#666;text-decoration:none} +#smart_editor2 a:hover{color:#666;text-decoration:underline} +/* LAYOUT */ +#smart_editor2 .se2_header{margin:10px 0 29px 0} +#smart_editor2 .se2_bi{float:left;width:93px;height:20px;margin:0;padding:0;background:url("../img/ko_KR/btn_set.png?130306") -343px -358px no-repeat;font-size:0;line-height:0;text-indent:-10000px;vertical-align:middle} +#smart_editor2 .se2_allhelp{display:inline-block;width:18px;height:18px;padding:0;background:url("../img/ko_KR/btn_set.png?130306") -437px -358px no-repeat;font-size:0;line-height:0;text-indent:-10000px;vertical-align:middle} +#smart_editor2 #smart_editor2_content{border:1px solid #b5b5b5} +#smart_editor2 .se2_tool{overflow:visible;position:relative;z-index:25} +/* EDITINGAREA */ +#smart_editor2 .se2_input_area{position:relative;z-index:22;height:400px;margin:0;padding:0;*zoom:1} +#smart_editor2 .se2_input_wysiwyg,#smart_editor2 .se2_input_syntax{display:block;overflow:auto;width:100%;height:100%;margin:0;*margin:-1px 0 0 0;border:0} +/* EDITINGMODE */ +#smart_editor2 .se2_conversion_mode{position:relative;height:15px;padding-top:1px;border-top:1px solid #b5b5b5;background:url("../img/icon_set.gif") 0 -896px repeat-x} +#smart_editor2 .se2_inputarea_controller{display:block;clear:both;position:relative;width:100%;height:15px;text-align:center;cursor:n-resize} +#smart_editor2 .se2_inputarea_controller span,#smart_editor2 .controller_on span{background:url("../img/ico_extend.png") no-repeat} +#smart_editor2 .se2_inputarea_controller span{position:static;display:inline-block;visibility:visible;overflow:hidden;height:15px;padding-left:11px;background-position:0 2px;color:#888;font-size:11px;letter-spacing:-1px;line-height:16px;white-space:nowrap} +* + html #smart_editor2 .se2_inputarea_controller span{line-height:14px} +#smart_editor2 .controller_on span{background-position:0 -21px;color:#249c04} +#smart_editor2 .ly_controller{display:block;position:absolute;bottom:2px;left:50%;width:287px;margin-left:-148px;padding:8px 0 7px 9px;border:1px solid #827f7c;background:#fffdef} +#smart_editor2 .ly_controller p{color:#666;font-size:11px;letter-spacing:-1px;line-height:11px} +#smart_editor2 .ly_controller .bt_clse,#smart_editor2 .ly_controller .ic_arr{position:absolute;background:url("../img/ico_extend.png") no-repeat} +#smart_editor2 .ly_controller .bt_clse{top:5px;right:4px;width:14px;height:15px;background-position:1px -43px} +#smart_editor2 .ly_controller .ic_arr{top:25px;left:50%;width:10px;height:6px;margin-left:-5px;background-position:0 -65px} +#smart_editor2 .se2_converter{float:left;position:absolute;top:-1px;right:3px;z-index:20} +#smart_editor2 .se2_converter li{float:left} +#smart_editor2 .se2_converter .se2_to_editor{width:59px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") 0 -85px no-repeat;vertical-align:top} +#smart_editor2 .se2_converter .se2_to_html{width:59px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") -59px -70px no-repeat;vertical-align:top} +#smart_editor2 .se2_converter .se2_to_text{width:60px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") -417px -466px no-repeat;vertical-align:top} +#smart_editor2 .se2_converter .active .se2_to_editor{width:59px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") 0 -70px no-repeat;vertical-align:top} +#smart_editor2 .se2_converter .active .se2_to_html{width:59px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") -59px -85px no-repeat;vertical-align:top} +#smart_editor2 .se2_converter .active .se2_to_text{width:60px;height:15px;background:url("../img/ko_KR/btn_set.png?130306") -417px -481px no-repeat;vertical-align:top} +/* EDITINGAREA_HTMLSRC */ +#smart_editor2 .off .ico_btn,#smart_editor2 .off .se2_more,#smart_editor2 .off .se2_more2,#smart_editor2 .off .se2_font_family,#smart_editor2 .off .se2_font_size,#smart_editor2 .off .se2_bold,#smart_editor2 .off .se2_underline,#smart_editor2 .off .se2_italic,#smart_editor2 .off .se2_tdel,#smart_editor2 .off .se2_fcolor,#smart_editor2 .off .se2_fcolor_more,#smart_editor2 .off .se2_bgcolor,#smart_editor2 .off .se2_bgcolor_more,#smart_editor2 .off .se2_left,#smart_editor2 .off .se2_center,#smart_editor2 .off .se2_right,#smart_editor2 .off .se2_justify,#smart_editor2 .off .se2_ol,#smart_editor2 .off .se2_ul,#smart_editor2 .off .se2_indent,#smart_editor2 .off .se2_outdent,#smart_editor2 .off .se2_lineheight,#smart_editor2 .off .se2_del_style,#smart_editor2 .off .se2_blockquote,#smart_editor2 .off .se2_summary,#smart_editor2 .off .se2_footnote,#smart_editor2 .off .se2_url,#smart_editor2 .off .se2_emoticon,#smart_editor2 .off .se2_character,#smart_editor2 .off .se2_table,#smart_editor2 .off .se2_find,#smart_editor2 .off .se2_spelling,#smart_editor2 .off .se2_sup,#smart_editor2 .off .se2_sub,#smart_editor2 .off .se2_text_tool_more,#smart_editor2 .off .se2_new,#smart_editor2 .off .selected_color,#smart_editor2 .off .se2_lineSticker{-ms-filter:alpha(opacity=50);opacity:.5;cursor:default;filter:alpha(opacity=50)} +/* LAYER */ +#smart_editor2 .se2_text_tool .se2_layer{display:none;float:left;position:absolute;top:20px;left:0;z-index:50;margin:0;padding:0;border:1px solid #bcbbbb;background:#fafafa} +#smart_editor2 .se2_text_tool li.active{z-index:50} +#smart_editor2 .se2_text_tool .active .se2_layer{display:block} +#smart_editor2 .se2_text_tool .active li .se2_layer{display:none} +#smart_editor2 .se2_text_tool .active .active .se2_layer{display:block} +#smart_editor2 .se2_text_tool .se2_layer .se2_in_layer{float:left;margin:0;padding:0;border:1px solid #fff;background:#fafafa} +/* TEXT_TOOLBAR */ +#smart_editor2 .se2_text_tool{position:relative;clear:both;z-index:30;padding:4px 0 4px 3px;background:#f4f4f4 url("../img/bg_text_tool.gif") 0 0 repeat-x;border-bottom:1px solid #b5b5b5;*zoom:1} +#smart_editor2 .se2_text_tool:after{content:"";display:block;clear:both} +#smart_editor2 .se2_text_tool ul{float:left;display:inline;margin-right:3px;padding-left:1px;white-space:nowrap} +#smart_editor2 .se2_text_tool li{_display:inline;float:left;position:relative;z-index:30} +#smart_editor2 .se2_text_tool button,#smart_editor2 .se2_multy .se2_icon{width:21px;height:21px;background:url("../img/ko_KR/text_tool_set.png?140317") no-repeat;vertical-align:top} +#smart_editor2 .se2_text_tool .se2_font_type{position:relative} +#smart_editor2 .se2_text_tool .se2_font_type li{margin-left:3px} +#smart_editor2 .se2_text_tool .se2_font_type button{text-align:left} +#smart_editor2 .se2_text_tool .se2_font_type button.se2_font_family span,#smart_editor2 .se2_text_tool .se2_font_type button.se2_font_size span{display:inline-block;visibility:visible;position:static;width:52px;height:20px;padding:0 0 0 6px;font-size:12px;line-height:20px;*line-height:22px;color:#333;*zoom:1} +#smart_editor2 .se2_text_tool .se2_multy{position:absolute;top:0;right:0;padding-left:0;margin-right:0;white-space:nowrap;border-left:1px solid #e0dedf} +#smart_editor2 .se2_text_tool .se2_multy .se2_mn{float:left;white-space:nowrap} +#smart_editor2 .se2_text_tool .se2_multy button{background-image:none;width:47px} +#smart_editor2 .se2_text_tool .se2_multy .se2_icon{display:inline-block;visibility:visible;overflow:visible;position:static;width:16px;height:29px;margin:-1px 2px 0 -1px;background-position:0 -132px;line-height:30px;vertical-align:top} +#smart_editor2 .se2_text_tool .se2_multy button,#smart_editor2 .se2_text_tool .se2_multy button span{height:29px;line-height:29px} +#smart_editor2 .se2_text_tool .se2_map .se2_icon{background-position:-29px -132px} +#smart_editor2 .se2_text_tool button span.se2_mntxt{display:inline-block;visibility:visible;overflow:visible;_overflow-y:hidden;position:relative;*margin-right:-1px;width:auto;height:29px;font-weight:normal;font-size:11px;line-height:30px;*line-height:29px;_line-height:30px;color:#444;letter-spacing:-1px;vertical-align:top} +#smart_editor2 .se2_text_tool .se2_multy .se2_photo{margin-right:1px} +#smart_editor2 .se2_text_tool .se2_multy .hover .ico_btn{background:#e8e8e8} +#smart_editor2 .se2_text_tool .se2_multy .se2_mn.hover{background:#e0dedf} +/* TEXT_TOOLBAR : ROUNDING */ +#smart_editor2 ul li.first_child button span.tool_bg,#smart_editor2 ul li.last_child button span.tool_bg,#smart_editor2 ul li.single_child button span.tool_bg{visibility:visible;height:21px} +#smart_editor2 ul li.first_child button span.tool_bg{left:-1px;width:3px;background:url("../img/bg_button_left.gif?20121228") no-repeat} +#smart_editor2 ul li.last_child button span.tool_bg{right:0px;_right:-1px;width:2px;background:url("../img/bg_button_right.gif") no-repeat} +#smart_editor2 ul li.single_child{padding-right:1px} +#smart_editor2 ul li.single_child button span.tool_bg{left:0;background:url("../img/bg_button.gif?20121228") no-repeat;width:22px} +#smart_editor2 div.se2_text_tool ul li.hover button span.tool_bg{background-position:0 -21px} +#smart_editor2 div.se2_text_tool ul li.active button span.tool_bg,#smart_editor2 div.se2_text_tool ul li.active li.active button span.tool_bg{background-position:0 -42px} +#smart_editor2 div.se2_text_tool ul li.active li button span.tool_bg{background-position:0 0} +/* TEXT_TOOLBAR : SUB_MENU */ +#smart_editor2 .se2_sub_text_tool{display:none;position:absolute;top:20px;left:0;z-index:40;width:auto;height:29px;padding:0 4px 0 0;border:1px solid #b5b5b5;border-top:1px solid #9a9a9a;background:#f4f4f4} +#smart_editor2 .active .se2_sub_text_tool{display:block} +#smart_editor2 .se2_sub_text_tool ul{float:left;height:25px;margin:0;padding:4px 0 0 4px} +/* TEXT_TOOLBAR : SUB_MENU_SIZE */ +#smart_editor2 .se2_sub_step1{width:88px} +#smart_editor2 .se2_sub_step2{width:199px} +#smart_editor2 .se2_sub_step2_1{width:178px} +/* TEXT_TOOLBAR : BUTTON */ +#smart_editor2 .se2_text_tool .se2_font_family{width:70px;height:21px;background-position:0 -10px} +#smart_editor2 .se2_text_tool .hover .se2_font_family{background-position:0 -72px} +#smart_editor2 .se2_text_tool .active .se2_font_family{background-position:0 -103px} +#smart_editor2 .se2_text_tool .se2_font_size{width:45px;height:21px;background-position:-70px -10px} +#smart_editor2 .se2_text_tool .hover .se2_font_size{background-position:-70px -72px} +#smart_editor2 .se2_text_tool .active .se2_font_size{background-position:-70px -103px} +#smart_editor2 .se2_text_tool .se2_bold{background-position:-115px -10px} +#smart_editor2 .se2_text_tool .hover .se2_bold{background-position:-115px -72px} +#smart_editor2 .se2_text_tool .active .se2_bold{background-position:-115px -103px} +#smart_editor2 .se2_text_tool .se2_underline{background-position:-136px -10px} +#smart_editor2 .se2_text_tool .hover .se2_underline{background-position:-136px -72px} +#smart_editor2 .se2_text_tool .active .se2_underline{background-position:-136px -103px} +#smart_editor2 .se2_text_tool .se2_italic{background-position:-157px -10px} +#smart_editor2 .se2_text_tool .hover .se2_italic{background-position:-157px -72px} +#smart_editor2 .se2_text_tool .active .se2_italic{background-position:-157px -103px} +#smart_editor2 .se2_text_tool .se2_tdel{background-position:-178px -10px} +#smart_editor2 .se2_text_tool .hover .se2_tdel{background-position:-178px -72px} +#smart_editor2 .se2_text_tool .active .se2_tdel{background-position:-178px -103px} +#smart_editor2 .se2_text_tool .se2_fcolor{position:relative;background-position:-199px -10px} +#smart_editor2 .se2_text_tool .hover .se2_fcolor{background-position:-199px -72px} +#smart_editor2 .se2_text_tool .active .se2_fcolor{background-position:-199px -103px} +#smart_editor2 .se2_text_tool .se2_fcolor_more{background-position:-220px -10px;width:10px} +#smart_editor2 .se2_text_tool .hover .se2_fcolor_more{background-position:-220px -72px} +#smart_editor2 .se2_text_tool .active .se2_fcolor_more{background-position:-220px -103px} +#smart_editor2 .se2_text_tool .selected_color{position:absolute;top:14px;left:5px;width:11px;height:3px;font-size:0} +#smart_editor2 .se2_text_tool .se2_ol,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .se2_ol{background-position:-345px -10px} +#smart_editor2 .se2_text_tool .se2_ul,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .se2_ul{background-position:-366px -10px} +#smart_editor2 .se2_text_tool .hover .se2_ol,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .hover .se2_ol{background-position:-345px -72px} +#smart_editor2 .se2_text_tool .hover .se2_ul,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .hover .se2_ul{background-position:-366px -72px} +#smart_editor2 .se2_text_tool .active .se2_ol,#smart_editor2 .se2_text_tool .active .active .se2_ol{background-position:-345px -103px} +#smart_editor2 .se2_text_tool .active .se2_ul,#smart_editor2 .se2_text_tool .active .active .se2_ul{background-position:-366px -103px} +#smart_editor2 .se2_text_tool .se2_indent,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .se2_indent{background-position:-408px -10px} +#smart_editor2 .se2_text_tool .se2_outdent,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .se2_outdent{background-position:-387px -10px} +#smart_editor2 .se2_text_tool .hover .se2_indent,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .hover .se2_indent{background-position:-408px -72px} +#smart_editor2 .se2_text_tool .hover .se2_outdent,#smart_editor2 .se2_text_tool .active .se2_sub_text_tool .hover .se2_outdent{background-position:-387px -72px} +#smart_editor2 .se2_text_tool .active .se2_indent,#smart_editor2 .se2_text_tool .active .active .se2_indent{background-position:-408px -103px} +#smart_editor2 .se2_text_tool .active .se2_outdent,#smart_editor2 .se2_text_tool .active .active .se2_outdent{background-position:-387px -103px} +#smart_editor2 .se2_text_tool .se2_lineheight{background-position:-429px -10px} +#smart_editor2 .se2_text_tool .hover .se2_lineheight{background-position:-429px -72px} +#smart_editor2 .se2_text_tool .active .se2_lineheight{background-position:-429px -103px} +#smart_editor2 .se2_text_tool .se2_url{background-position:-513px -10px} +#smart_editor2 .se2_text_tool .hover .se2_url{background-position:-513px -72px} +#smart_editor2 .se2_text_tool .active .se2_url{background-position:-513px -103px} +#smart_editor2 .se2_text_tool .se2_bgcolor{position:relative;background-position:-230px -10px} +#smart_editor2 .se2_text_tool .hover .se2_bgcolor{background-position:-230px -72px} +#smart_editor2 .se2_text_tool .active .se2_bgcolor{background-position:-230px -103px} +#smart_editor2 .se2_text_tool .se2_bgcolor_more{background-position:-251px -10px;width:10px} +#smart_editor2 .se2_text_tool .hover .se2_bgcolor_more{background-position:-251px -72px} +#smart_editor2 .se2_text_tool .active .se2_bgcolor_more{background-position:-251px -103px} +#smart_editor2 .se2_text_tool .se2_left{background-position:-261px -10px} +#smart_editor2 .se2_text_tool .hover .se2_left{background-position:-261px -72px} +#smart_editor2 .se2_text_tool .active .se2_left{background-position:-261px -103px} +#smart_editor2 .se2_text_tool .se2_center{background-position:-282px -10px} +#smart_editor2 .se2_text_tool .hover .se2_center{background-position:-282px -72px} +#smart_editor2 .se2_text_tool .active .se2_center{background-position:-282px -103px} +#smart_editor2 .se2_text_tool .se2_right{background-position:-303px -10px} +#smart_editor2 .se2_text_tool .hover .se2_right{background-position:-303px -72px} +#smart_editor2 .se2_text_tool .active .se2_right{background-position:-303px -103px} +#smart_editor2 .se2_text_tool .se2_justify{background-position:-324px -10px} +#smart_editor2 .se2_text_tool .hover .se2_justify{background-position:-324px -72px} +#smart_editor2 .se2_text_tool .active .se2_justify{background-position:-324px -103px} +#smart_editor2 .se2_text_tool .se2_blockquote{background-position:-471px -10px} +#smart_editor2 .se2_text_tool .hover .se2_blockquote{background-position:-471px -72px} +#smart_editor2 .se2_text_tool .active .se2_blockquote{background-position:-471px -103px} +#smart_editor2 .se2_text_tool .se2_character{background-position:-555px -10px} +#smart_editor2 .se2_text_tool .hover .se2_character{background-position:-555px -72px} +#smart_editor2 .se2_text_tool .active .se2_character{background-position:-555px -103px} +#smart_editor2 .se2_text_tool .se2_table{background-position:-576px -10px} +#smart_editor2 .se2_text_tool .hover .se2_table{background-position:-576px -72px} +#smart_editor2 .se2_text_tool .active .se2_table{background-position:-576px -103px} +#smart_editor2 .se2_text_tool .se2_find{background-position:-597px -10px} +#smart_editor2 .se2_text_tool .hover .se2_find{background-position:-597px -72px} +#smart_editor2 .se2_text_tool .active .se2_find{background-position:-597px -103px} +#smart_editor2 .se2_text_tool .se2_sup{background-position:-660px -10px} +#smart_editor2 .se2_text_tool .hover .se2_sup{background-position:-660px -72px} +#smart_editor2 .se2_text_tool .active .se2_sup{background-position:-660px -103px} +#smart_editor2 .se2_text_tool .se2_sub{background-position:-681px -10px} +#smart_editor2 .se2_text_tool .hover .se2_sub{background-position:-681px -72px} +#smart_editor2 .se2_text_tool .active .se2_sub{background-position:-681px -103px} +#smart_editor2 .se2_text_tool .se2_text_tool_more{background-position:0 -41px;width:13px} +#smart_editor2 .se2_text_tool .se2_text_tool_more span.tool_bg{background:none} +#smart_editor2 .se2_text_tool .hover .se2_text_tool_more{background-position:-13px -41px} +#smart_editor2 .se2_text_tool .active .se2_text_tool_more{background-position:-26px -41px} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_in.css b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_in.css new file mode 100644 index 0000000..f34ddcf --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_in.css @@ -0,0 +1,37 @@ +@charset "UTF-8"; +/* Nanum Gothic */ +@import url(http://fonts.googleapis.com/earlyaccess/nanumgothic.css); +/* Noto Sans KR */ +@import url(http://fonts.googleapis.com/earlyaccess/notosanskr.css); +/* Nanum Myeongjo */ +@import url(http://fonts.googleapis.com/earlyaccess/nanummyeongjo.css); +@font-face { + font-family: 'aphopis'; + src: url('../../../../css/fonts/MetalMania-Regular.eot'); + src: url('../../../../css/fonts/MetalMania-Regular.eot#iefix') format('embedded-opentype'), + url('../../../../css/fonts/MetalMania-Regular.ttf') format('truetype'), + url('../../../../css/fonts/MetalMania-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} + +/* NHN Web Standardization Team (http://html.nhndesign.com/) HHJ 090226 */ +/* COMMON */ +body,.se2_inputarea{margin:0;padding:0;font-family:'돋움',Dotum,Helvetica,Sans-serif;font-size:12px;line-height:1.5} +/* body,.se2_inputarea,.se2_inputarea th,.se2_inputarea td{margin:0;padding:0;font-family:'돋움',Dotum,Helvetica,Sans-serif;font-size:12px;line-height:1.5;color:#666} */ +.se2_inputarea p,.se2_inputarea br{margin:0;padding:0} +.se2_inputarea{margin:15px;word-wrap:break-word;*word-wrap:normal;*word-break:break-all} +.se2_inputarea td{word-break:break-all} +.se2_inputarea_890{width:741px;margin:20px 0 10px 64px} +.se2_inputarea_698{width:548px;margin:20px 0 10px 64px} +/* TEXT_TOOLBAR : QUOTE */ +.se2_quote1{margin:0 0 30px 20px;padding:0 8px;border-left:2px solid #ccc;color:#888} +.se2_quote2{margin:0 0 30px 13px;padding:0 8px 0 16px;background:url("../img/bg_quote2.gif") 0 3px no-repeat;color:#888} +.se2_quote3{margin:0 0 30px;padding:12px 10px 11px;border:1px dashed #ccc;color:#888} +.se2_quote4{margin:0 0 30px;padding:12px 10px 11px;border:1px dashed #66b246;color:#888} +.se2_quote5{margin:0 0 30px;padding:12px 10px 11px;border:1px dashed #ccc;background:#fafafa;color:#888} +.se2_quote6{margin:0 0 30px;padding:12px 10px 11px;border:1px solid #e5e5e5;color:#888} +.se2_quote7{margin:0 0 30px;padding:12px 10px 11px;border:1px solid #66b246;color:#888} +.se2_quote8{margin:0 0 30px;padding:12px 10px 11px;border:1px solid #e5e5e5;background:#fafafa;color:#888} +.se2_quote9{margin:0 0 30px;padding:12px 10px 11px;border:2px solid #e5e5e5;color:#888} +.se2_quote10{margin:0 0 30px;padding:12px 10px 11px;border:2px solid #e5e5e5;background:#fafafa;color:#888} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_items.css b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_items.css new file mode 100644 index 0000000..844a371 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_items.css @@ -0,0 +1,462 @@ +@charset "UTF-8"; +/* NHN Web Standardization Team (http://html.nhndesign.com/) HHJ 090226 */ +/* TEXT_TOOLBAR : FONTNAME */ +#smart_editor2 .se2_tool .se2_l_font_fam{width:202px;margin:0;padding:0} +#smart_editor2 .se2_tool .se2_l_font_fam li{display:block;width:202px;height:21px;margin:0;padding:0;color:#333;cursor:pointer} +#smart_editor2 .se2_l_font_fam .hover,#smart_editor2 .se2_l_font_fam .active{background:#ebebeb} +#smart_editor2 .se2_l_font_fam button{width:200px;height:21px;margin:0;padding:2px 0 2px 0px;background:none;text-align:left} +#smart_editor2 .se2_l_font_fam button span{display:block;visibility:visible;overflow:visible;position:relative;top:auto;left:auto;width:auto;height:auto;margin:0 0 0 4px;padding:0;font-size:12px;line-height:normal;color:#333} +#smart_editor2 .se2_l_font_fam button span span{display:inline;visibility:visible;overflow:visible;width:auto;height:auto;margin:0 0 0 4px;font-family:Verdana;font-size:12px;line-height:14px;color:#888} +#smart_editor2 .se2_l_font_fam button span em{visibility:visible;overflow:auto;position:static;width:auto;height:auto;margin-right:-4px;font-size:12px;color:#888} +#smart_editor2 .se2_l_font_fam .se2_division{width:162px;height:2px !important;margin:1px 0 1px 0px;border:0;background:url("../img/bg_line1.gif") 0 0 repeat-x;font-size:0;cursor:default} +/* TEXT_TOOLBAR : FONTSIZE */ +#smart_editor2 .se2_tool .se2_l_font_size{width:302px;margin:0;padding:0} +#smart_editor2 .se2_tool .se2_l_font_size li{width:302px;margin:0;padding:0;color:#333;cursor:pointer} +#smart_editor2 .se2_l_font_size .hover,#smart_editor2 .se2_l_font_size .active{background:#ebebeb} +#smart_editor2 .se2_l_font_size button{width:300px;height:auto;margin:0;padding:2px 0 1px 0px;*padding:4px 0 1px 0px;background:none;text-align:left} +#smart_editor2 .se2_l_font_size button span{display:block;visibility:visible;overflow:visible;position:relative;top:auto;left:auto;width:auto;height:auto;margin:0 0 0 4px;padding:0;line-height:normal;color:#373737;letter-spacing:0px} +#smart_editor2 .se2_l_font_size button span span{display:inline;margin:0 0 0 5px;padding:0} +#smart_editor2 .se2_l_font_size span em{visibility:visible;overflow:auto;position:static;width:auto;height:auto;color:#888} +/* TEXT_TOOLBAR : FONTCOLOR */ +#smart_editor2 .se2_palette{float:left;position:relative;width:225px;margin:0;padding:11px 0 10px 0} +#smart_editor2 .se2_palette .se2_pick_color{_display:inline;float:left;clear:both;width:205px;margin:0 0 0 11px;padding:0} +#smart_editor2 .se2_palette .se2_pick_color li{float:left;width:12px;height:12px;margin:0;padding:0} +#smart_editor2 .se2_palette .se2_pick_color li button{width:11px;height:11px;border:0} +#smart_editor2 .se2_palette .se2_pick_color li button span{display:block;visibility:visible;overflow:visible;position:absolute;top:1px;left:1px;width:11px;height:11px} +#smart_editor2 .se2_palette .se2_pick_color li button span span{visibility:hidden;overflow:hidden;position:absolute;top:0;left:0;width:0;height:0} +#smart_editor2 .se2_palette .se2_pick_color .hover button,#smart_editor2 .se2_palette .se2_pick_color .active button{width:11px;height:11px;border:1px solid #666} +#smart_editor2 .se2_palette .se2_pick_color .hover span,#smart_editor2 .se2_palette .se2_pick_color .active span{width:7px;height:7px;border:1px solid #fff} +#smart_editor2 .se2_palette .se2_view_more{_display:inline;float:left;width:46px;height:23px;margin:1px 0 0 1px;background:url("../img/ko_KR/btn_set.png?130306") 0 -47px no-repeat} +#smart_editor2 .se2_palette .se2_view_more2{_display:inline;float:left;width:46px;height:23px;margin:1px 0 0 1px;background:url("../img/ko_KR/btn_set.png?130306") 0 -24px no-repeat} +#smart_editor2 .se2_palette h4{_display:inline;float:left;width:203px;margin:9px 0 0 11px;padding:10px 0 4px 0;background:url("../img/bg_line1.gif") repeat-x;font-weight:normal;font-size:12px;line-height:14px;color:#333;letter-spacing:-1px} +#smart_editor2 .se2_palette2{float:left;_float:none;width:214px;margin:9px 0 0 0;padding:11px 0 0 11px;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_palette2 .se2_color_set{float:left} +#smart_editor2 .se2_palette2 .se2_selected_color{_display:inline;float:left;width:83px;height:18px;margin:0;border:1px solid #c7c7c7;background:#fff} +#smart_editor2 .se2_palette2 .se2_selected_color span{_display:inline;float:left;width:79px;height:14px;margin:2px} +#smart_editor2 .se2_palette2 .input_ty1{_display:inline;float:left;width:67px;height:16px;margin:0 3px 0 3px;padding:2px 2px 0 4px;font-family:tahoma;font-size:11px} +#smart_editor2 .se2_palette2 button.se2_btn_insert{float:left;width:35px;height:21px;margin-left:2px;padding:0;background:url("../img/ko_KR/btn_set.png?130306") -80px 0 no-repeat} +#smart_editor2 .se2_gradation1{float:left;_float:none;width:201px;height:128px;margin:4px 0 0 0;border:1px solid #c7c7c7;cursor:crosshair} +#smart_editor2 .se2_gradation2{float:left;_float:none;width:201px;height:10px;margin:4px 0 1px 0;border:1px solid #c7c7c7;cursor:crosshair} +/* TEXT_TOOLBAR : BGCOLOR */ +#smart_editor2 .se2_palette_bgcolor{width:225px;margin:11px 0 0;padding:0} +#smart_editor2 .se2_palette_bgcolor .se2_background{width:205px;margin:0 11px 0 11px} +#smart_editor2 .se2_palette_bgcolor .se2_background li{width:68px;height:20px} +#smart_editor2 .se2_palette_bgcolor .se2_background button{width:67px;height:19px;border:0} +#smart_editor2 .se2_palette_bgcolor .se2_background span{left:0;display:block;visibility:visible;overflow:visible;width:65px;height:17px;padding:0} +#smart_editor2 .se2_palette_bgcolor .se2_background span span{display:block;visibility:visible;overflow:visible;width:64px;height:16px;padding:3px 0 0 3px;font-size:11px;line-height:14px;text-align:left} +#smart_editor2 .se2_palette_bgcolor .se2_background .hover span{width:65px;height:17px;border:1px solid #666} +#smart_editor2 .se2_palette_bgcolor .se2_background .hover span span{width:62px;height:14px;padding:1px 0 0 1px;border:1px solid #fff} +/* TEXT_TOOLBAR : LINEHEIGHT */ +#smart_editor2 .se2_l_line_height{width:107px;margin:0;padding:0} +#smart_editor2 .se2_l_line_height li{width:107px;margin:0;padding:0;border-top:0;border-bottom:0;color:#333;cursor:pointer} +#smart_editor2 .se2_l_line_height .hover{background:#ebebeb} +#smart_editor2 .se2_l_line_height button{width:105px;height:19px;margin:0;padding:3px 0 2px 0px;background:none;text-align:left} +#smart_editor2 .se2_l_line_height button span{visibility:visible;overflow:visible;position:relative;width:auto;height:auto;margin:0;padding:0 0 0 15px;font-size:12px;line-height:normal;color:#373737} +#smart_editor2 .se2_l_line_height li button.active span{background:url("../img/icon_set.gif") 5px -30px no-repeat} +#smart_editor2 .se2_l_line_height_user{clear:both;width:83px;margin:5px 0 0 12px;padding:10px 0 0 0;_padding:11px 0 0 0;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_l_line_height_user h3{margin:0 0 4px 0;_margin:0 0 2px -1px;padding:0;line-height:14px;color:#000;letter-spacing:-1px} +#smart_editor2 .se2_l_line_height_user .bx_input{display:block;position:relative;width:83px} +#smart_editor2 .se2_l_line_height_user .btn_up{position:absolute;top:2px;*top:3px;left:68px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -54px no-repeat} +#smart_editor2 .se2_l_line_height_user .btn_down{position:absolute;top:10px;*top:11px;left:68px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -62px no-repeat} +#smart_editor2 .se2_l_line_height_user .btn_area{margin:5px 0 10px 0} +#smart_editor2 .se2_tool .btn_area .se2_btn_apply3{width:41px;height:24px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat} +#smart_editor2 .se2_tool .btn_area .se2_btn_cancel3{width:39px;height:24px;margin-left:3px;background:url("../img/ko_KR/btn_set.png?130306") -41px 0 no-repeat} +/* TEXT_TOOLBAR : QUOTE */ +#smart_editor2 .se2_quote{width:425px;height:56px} +#smart_editor2 .se2_quote ul{_display:inline;float:left;margin:11px 0 0 9px;padding:0} +#smart_editor2 .se2_quote li{_display:inline;float:left;margin:0 0 0 2px;padding:0} +#smart_editor2 .se2_quote button{width:34px;height:34px;margin:0;padding:0;background:url("../img/ko_KR/btn_set.png?130306") no-repeat;cursor:pointer} +#smart_editor2 .se2_quote button span{left:0;display:block;visibility:visible;overflow:visible;width:32px;height:32px;margin:0;padding:0;border:1px solid #c7c7c7} +#smart_editor2 .se2_quote button span span{visibility:hidden;overflow:hidden;position:absolute;top:0;left:0;width:0;height:0;margin:0;padding:0} +#smart_editor2 .se2_quote .se2_quote1{background-position:1px -375px} +#smart_editor2 .se2_quote .se2_quote2{background-position:-32px -375px} +#smart_editor2 .se2_quote .se2_quote3{background-position:-65px -375px} +#smart_editor2 .se2_quote .se2_quote4{background-position:-98px -375px} +#smart_editor2 .se2_quote .se2_quote5{background-position:-131px -375px} +#smart_editor2 .se2_quote .se2_quote6{background-position:-164px -375px} +#smart_editor2 .se2_quote .se2_quote7{background-position:-197px -375px} +#smart_editor2 .se2_quote .se2_quote8{background-position:-230px -375px} +#smart_editor2 .se2_quote .se2_quote9{background-position:-263px -375px} +#smart_editor2 .se2_quote .se2_quote10{background-position:-296px -375px} +#smart_editor2 .se2_quote .hover button span,#smart_editor2 .se2_quote .active button span{width:30px;height:30px;margin:0;padding:0;border:2px solid #44b525} +#smart_editor2 .se2_quote .hover button span span,#smart_editor2 .se2_quote .active button span span{visibility:hidden;overflow:hidden;position:absolute;top:0;left:0;width:0;height:0;margin:0;padding:0} +#smart_editor2 .se2_quote .se2_cancel2{float:left;width:40px;height:35px;margin:11px 0 0 5px;background:url("../img/ko_KR/btn_set.png?130306") -46px -24px no-repeat} +#smart_editor2 .se2_quote .se2_cancel2 span{visibility:hidden;overflow:hidden;position:absolute;top:0;left:0;width:0;height:0;margin:0;padding:0} +/* TEXT_TOOLBAR : HYPERLINK */ +#smart_editor2 .se2_url2{width:281px;padding:11px 11px 6px 11px;color:#666} +#smart_editor2 .se2_url2 .input_ty1{display:block;width:185px;height:16px;margin:0 5px 5px 0;*margin:-1px 5px 5px 0;padding:5px 2px 0 4px} +#smart_editor2 .se2_url2 .se2_url_new{width:15px;height:15px;margin:-1px 3px 1px -1px;*margin:-2px 3px 2px -1px;vertical-align:middle} +#smart_editor2 .se2_url2 label{font-size:11px;line-height:14px;vertical-align:middle} +#smart_editor2 .se2_url2 .se2_apply{position:absolute;top:13px;right:51px;width:41px;height:24px;margin:-1px 3px 1px 0;background:url("../img/ko_KR/btn_set.png?130306") no-repeat} +#smart_editor2 .se2_url2 .se2_cancel{position:absolute;top:13px;right:9px;width:39px;height:24px;margin:-1px 3px 1px 0;background:url("../img/ko_KR/btn_set.png?130306") -41px 0 no-repeat} +/* TEXT_TOOLBAR : SCHARACTER */ +#smart_editor2 .se2_bx_character{width:469px;height:272px;margin:0;padding:0;background:url("../img/ko_KR/bx_set_110302.gif") 9px -1230px no-repeat} +#smart_editor2 .se2_bx_character .se2_char_tab{_display:inline;float:left;position:relative;width:443px;margin:11px 10px 200px 11px;padding:0 0 0 1px} +#smart_editor2 .se2_bx_character .se2_char_tab li{position:static;margin:0 0 0 -1px;padding:0} +#smart_editor2 .se2_bx_character .se2_char1{width:76px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") 0 -204px no-repeat} +#smart_editor2 .se2_bx_character .se2_char2{width:86px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -75px -204px no-repeat} +#smart_editor2 .se2_bx_character .se2_char3{width:68px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -160px -204px no-repeat} +#smart_editor2 .se2_bx_character .se2_char4{width:55px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -227px -204px no-repeat} +#smart_editor2 .se2_bx_character .se2_char5{width:97px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -281px -204px no-repeat} +#smart_editor2 .se2_bx_character .se2_char6{width:66px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -377px -204px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char1{width:76px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") 0 -230px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char2{width:86px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -75px -230px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char3{width:68px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -160px -230px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char4{width:55px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -227px -230px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char5{width:97px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -281px -230px no-repeat} +#smart_editor2 .se2_bx_character .active .se2_char6{width:66px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -377px -230px no-repeat} +#smart_editor2 .se2_bx_character .se2_s_character{display:none;position:absolute;top:26px;left:0;width:448px;height:194px;margin:0;padding:0} +#smart_editor2 .se2_bx_character .active .se2_s_character{display:block} +#smart_editor2 .se2_bx_character .se2_s_character ul{float:left;width:422px;height:172px;margin:0;padding:9px 0 0 11px} +#smart_editor2 .se2_bx_character .se2_s_character li{_display:inline;float:left;position:relative;width:20px;height:18px;margin:0 0 1px 1px;background:#fff} +#smart_editor2 .se2_bx_character .se2_s_character button{width:20px;height:18px;margin:0;padding:2px;background:none} +#smart_editor2 .se2_bx_character .se2_s_character .hover,#smart_editor2 .se2_bx_character .se2_s_character .active{background:url("../img/ko_KR/btn_set.png?130306") -446px -274px no-repeat} +#smart_editor2 .se2_bx_character .se2_s_character button span{left:0;display:block;visibility:visible;overflow:visible;width:14px;height:16px;margin:3px 0 0 3px;border:0;background:none;font-size:12px;line-height:normal} +#smart_editor2 .se2_apply_character{clear:both;position:relative;padding:0 0 0 11px} +#smart_editor2 .se2_apply_character label{margin:0 3px 0 0;font-size:12px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_apply_character .input_ty1{width:283px;height:17px;margin:-1px 5px 1px 0;padding:4px 0 0 5px;font-size:12px;color:#666;letter-spacing:0;vertical-align:middle} +#smart_editor2 .se2_apply_character .se2_confirm{width:41px;height:24px;margin-right:3px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat;vertical-align:middle} +#smart_editor2 .se2_apply_character .se2_cancel{width:39px;height:24px;background:url("../img/ko_KR/btn_set.png?130306") -41px 0 no-repeat;vertical-align:middle} +/* TEXT_TOOLBAR : TABLECREATOR */ +#smart_editor2 .se2_table_set{position:relative;width:166px;margin:3px 11px 0 11px;padding:8px 0 0 0} +#smart_editor2 .se2_table_set .se2_cell_num{float:left;width:73px} +#smart_editor2 .se2_table_set .se2_cell_num dt{float:left;clear:both;width:17px;height:23px;margin:0;padding:0} +#smart_editor2 .se2_table_set .se2_cell_num dt label{display:block;margin:5px 0 0 0;font-size:11px;color:#666} +#smart_editor2 .se2_table_set .se2_cell_num dd{float:left;position:relative;width:54px;height:23px;margin:0;padding:0} +#smart_editor2 .se2_table_set .se2_cell_num .input_ty2{display:block;width:32px;height:16px;*margin:-1px 0 0 0;padding:2px 19px 0 0px;border:1px solid #c7c7c7;font-family:tahoma,verdana,times New Roman;font-size:11px;color:#666;text-align:right;*direction:rtl} +#smart_editor2 .se2_table_set .se2_cell_num .input_ty2::-ms-clear{display:none} +#smart_editor2 .se2_table_set .se2_pre_table{float:right;width:91px;height:43px;background:#c7c7c7;border-spacing:1px} +#smart_editor2 .se2_table_set .se2_pre_table tr{background:#fff} +#smart_editor2 .se2_table_set .se2_pre_table td{font-size:0;line-height:0} +#smart_editor2 .se2_table_set .se2_add{position:absolute;top:2px;right:3px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -54px no-repeat} +#smart_editor2 .se2_table_set .se2_del{position:absolute;top:10px;right:3px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -62px no-repeat} +/* TEXT_TOOLBAR : TABLEEDITOR */ +#smart_editor2 .se2_table_set .se2_t_proper1{float:left;width:166px;margin:7px 0 0 0;padding:10px 0 5px;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_table_set .se2_t_proper1 dt{width:166px;margin:0 0 6px 0} +#smart_editor2 .se2_table_set .se2_t_proper1 dd{width:166px} +#smart_editor2 .se2_table_set .se2_t_proper1 dt input{width:15px;height:15px;margin:-1px 3px 1px 0;_margin:-2px 3px 2px 0;vertical-align:middle} +#smart_editor2 .se2_table_set .se2_t_proper1 dt label{font-weight:bold;font-size:11px;color:#666;letter-spacing:-1px;vertical-align:middle} +#smart_editor2 .se2_table_set .se2_t_proper1_1{float:left;position:relative;z-index:59;width:166px;margin:1px 0 0 0} +#smart_editor2 .se2_table_set .se2_t_proper1_2{z-index:54;margin:0} +#smart_editor2 .se2_table_set .se2_t_proper1_3{z-index:53;margin:0} +#smart_editor2 .se2_table_set .se2_t_proper1_4{z-index:52;margin:0} +#smart_editor2 .se2_table_set .se2_t_proper1_1 dt{_display:inline;float:left;clear:both;width:66px;height:22px;margin:1px 0 0 18px} +#smart_editor2 .se2_table_set .se2_t_proper1_1 dt label{display:block;margin:4px 0 0 0;font-weight:normal;font-size:11px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_table_set .se2_t_proper1_1 dd{float:left;position:relative;width:82px;height:23px} +#smart_editor2 .se2_table_set .se2_t_proper1_1 .input_ty1{width:72px;height:16px;*margin:-1px 0 0 0;padding:2px 2px 0 6px;font-family:tahoma,verdana,times New Roman;font-size:11px;color:#666} +#smart_editor2 .se2_table_set .se2_t_proper1_1 .input_ty3{float:left;width:49px;height:16px;margin:0 3px 0 0;padding:2px 4px 0 4px;border:1px solid #c7c7c7;font-family:tahoma,verdana,times New Roman;font-size:11px;color:#666} +#smart_editor2 .se2_table_set .se2_t_proper1_1 .se2_add{top:2px;right:2px} +#smart_editor2 .se2_table_set .se2_t_proper1_1 .se2_del{top:10px;right:2px} +#smart_editor2 .se2_table_set .se2_t_proper1_1 .se2_color_set .input_ty1{_display:inline;float:left;width:67px;height:16px;margin:0 3px 0 3px;padding:2px 2px 0 4px;font-family:tahoma,verdana,times New Roman;font-size:11px} +#smart_editor2 .se2_select_ty1{position:relative;width:80px;height:18px;border:1px solid #c7c7c7;background:#fff;font-size:11px;line-height:14px;text-align:left} +#smart_editor2 .se2_select_ty1 span{float:left;width:54px;height:18px;margin:0 0 0 5px;font-size:11px;line-height:14px;color:#666} +#smart_editor2 .se2_select_ty1 .se2_b_style0{position:relative;top:3px;left:-3px;white-space:nowrap} +#smart_editor2 .se2_select_ty1 .se2_b_style1{height:15px;margin:3px 0 0 4px;font-size:11px;line-height:14px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_select_ty1 .se2_b_style2{background:url("../img/bg_set.gif") 0 -50px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_b_style3{background:url("../img/bg_set.gif") 0 -68px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_b_style4{background:url("../img/bg_set.gif") 0 -85px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_b_style5{background:url("../img/bg_set.gif") 0 -103px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_b_style6{background:url("../img/bg_set.gif") 0 -121px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_b_style7{background:url("../img/bg_set.gif") 0 -139px repeat-x} +#smart_editor2 .se2_select_ty1 .se2_view_more{position:absolute;top:1px;right:1px;width:13px;height:16px;background:url("../img/ko_KR/btn_set.png?130306") -112px -54px no-repeat} +#smart_editor2 .se2_select_ty1 .se2_view_more2{position:absolute;top:1px;right:1px;width:13px;height:16px;background:url("../img/ko_KR/btn_set.png?130306") -99px -54px no-repeat} +/* TEXT_TOOLBAR : TABLEEDITOR > BORDER */ +#smart_editor2 .se2_table_set .se2_b_t_b1{border-top:1px solid #b1b1b1} +#smart_editor2 .se2_layer_b_style{position:absolute;top:20px;right:0px;width:80px;padding-bottom:1px;border:1px solid #c7c7c7;border-top:1px solid #a8a8a8;background:#fff} +#smart_editor2 .se2_layer_b_style ul{width:80px;margin:0;padding:1px 0 0 0} +#smart_editor2 .se2_layer_b_style li{width:80px;height:18px;margin:0;padding:0} +#smart_editor2 .se2_layer_b_style .hover,#smart_editor2 .se2_layer_b_style .active{background:#ebebeb} +#smart_editor2 .se2_layer_b_style button{width:80px;height:18px;background:none} +#smart_editor2 .se2_layer_b_style button span{left:0;display:block;visibility:visible;overflow:visible;width:71px;height:18px;margin:0 0 0 5px;font-size:11px;line-height:15px;text-align:left} +#smart_editor2 .se2_layer_b_style button span span{visibility:hidden;overflow:hidden;position:absolute;top:0;left:0;width:0;height:0} +#smart_editor2 .se2_layer_b_style .se2_b_style1 span{margin:3px 0 0 4px;font-size:11px;line-height:14px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_layer_b_style .se2_b_style2 span{background:url("../img/bg_set.gif") 0 -50px repeat-x} +#smart_editor2 .se2_layer_b_style .se2_b_style3 span{background:url("../img/bg_set.gif") 0 -68px repeat-x} +#smart_editor2 .se2_layer_b_style .se2_b_style4 span{background:url("../img/bg_set.gif") 0 -86px repeat-x} +#smart_editor2 .se2_layer_b_style .se2_b_style5 span{background:url("../img/bg_set.gif") 0 -103px repeat-x} +#smart_editor2 .se2_layer_b_style .se2_b_style6 span{background:url("../img/bg_set.gif") 0 -121px repeat-x} +#smart_editor2 .se2_layer_b_style .se2_b_style7 span{background:url("../img/bg_set.gif") 0 -139px repeat-x} +/* TEXT_TOOLBAR : TABLEEDITOR > COLOR */ +#smart_editor2 .se2_pre_color{float:left;width:18px;height:18px;border:1px solid #c7c7c7} +#smart_editor2 .se2_pre_color button{float:left;width:14px;height:14px;margin:2px 0 0 2px;padding:0} +#smart_editor2 .se2_pre_color button span{overflow:hidden;position:absolute;top:-10000px;left:-10000px;z-index:-100;width:0;height:0} +/* TEXT_TOOLBAR : TABLEEDITOR > DIMMED */ +#smart_editor2 .se2_table_set .se2_t_dim1{clear:both;position:absolute;top:71px;left:16px;z-index:60;width:157px;height:118px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_table_set .se2_t_dim2{position:absolute;top:116px;left:16px;z-index:55;width:157px;height:45px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_table_set .se2_t_dim3{clear:both;position:absolute;top:192px;left:16px;z-index:51;width:157px;height:39px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +/* TEXT_TOOLBAR : TABLEEDITOR > STYLE PREVIEW */ +#smart_editor2 .se2_table_set .se2_t_proper2{float:left;position:relative;z-index:50;width:166px;margin:2px 0 0 0} +#smart_editor2 .se2_table_set .se2_t_proper2 dt{float:left;width:84px;height:33px;margin:4px 0 0 0} +#smart_editor2 .se2_table_set .se2_t_proper2 dt input{width:15px;height:15px;margin:-1px 3px 1px 0;_margin:-2px 3px 2px 0;vertical-align:middle} +#smart_editor2 .se2_table_set .se2_t_proper2 dt label{font-weight:bold;font-size:11px;color:#666;letter-spacing:-1px;vertical-align:middle} +#smart_editor2 .se2_table_set .se2_t_proper2 dd{float:left;width:66px;height:33px} +#smart_editor2 .se2_select_ty2{position:relative;width:65px;height:31px;border:1px solid #c7c7c7;background:#fff;font-size:11px;line-height:14px;text-align:left} +#smart_editor2 .se2_select_ty2 span{float:left;width:45px;height:25px;margin:3px 0 0 3px;background:url("../img/ko_KR/btn_set.png?130306") repeat-x} +#smart_editor2 .se2_select_ty2 .se2_t_style1{background-position:0 -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style2{background-position:-46px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style3{background-position:-92px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style4{background-position:-138px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style5{background-position:-184px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style6{background-position:-230px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style7{background-position:-276px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style8{background-position:-322px -410px} +#smart_editor2 .se2_select_ty2 .se2_t_style9{background-position:0 -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style10{background-position:-46px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style11{background-position:-92px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style12{background-position:-138px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style13{background-position:-184px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style14{background-position:-230px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style15{background-position:-276px -436px} +#smart_editor2 .se2_select_ty2 .se2_t_style16{background-position:-322px -436px} +#smart_editor2 .se2_select_ty2 .se2_view_more{position:absolute;top:1px;right:1px;_right:0px;width:13px !important;height:29px !important;background:url("../img/ko_KR/btn_set.png?130306") -353px -48px no-repeat !important} +#smart_editor2 .se2_select_ty2 .se2_view_more2{position:absolute;top:1px;right:1px;_right:0px;width:13px !important;height:29px !important;background:url("../img/ko_KR/btn_set.png?130306") -340px -48px no-repeat !important} +#smart_editor2 .se2_select_ty2 .se2_view_more span{display:none} +/* TEXT_TOOLBAR : TABLEEDITOR > STYLE */ +#smart_editor2 .se2_layer_t_style{position:absolute;top:33px;right:15px;width:208px;border:1px solid #c7c7c7;border-top:1px solid #a8a8a8;background:#fff} +#smart_editor2 .se2_layer_t_style ul{width:204px;height:126px;margin:1px 2px;padding:1px 0 0 0;background:#fff} +#smart_editor2 .se2_layer_t_style li{_display:inline;float:left;width:45px;height:25px;margin:1px;padding:1px;border:1px solid #fff} +#smart_editor2 .se2_layer_t_style .hover,#smart_editor2 .se2_layer_t_style .active{border:1px solid #666;background:#fff} +#smart_editor2 .se2_layer_t_style button{width:45px;height:25px;background:url("../img/ko_KR/btn_set.png?130306") repeat-x !important} +#smart_editor2 .se2_layer_t_style .se2_t_style1{background-position:0 -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style2{background-position:-46px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style3{background-position:-92px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style4{background-position:-138px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style5{background-position:-184px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style6{background-position:-230px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style7{background-position:-276px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style8{background-position:-322px -410px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style9{background-position:0 -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style10{background-position:-46px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style11{background-position:-92px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style12{background-position:-138px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style13{background-position:-184px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style14{background-position:-230px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style15{background-position:-276px -436px !important} +#smart_editor2 .se2_layer_t_style .se2_t_style16{background-position:-322px -436px !important} +#smart_editor2 .se2_table_set .se2_btn_area{float:left;width:166px;margin:6px 0 0 0;padding:12px 0 8px 0;background:url("../img/bg_line1.gif") repeat-x;text-align:center} +#smart_editor2 .se2_table_set button.se2_apply{width:41px;height:24px;margin-right:3px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat} +#smart_editor2 .se2_table_set button.se2_cancel{width:39px;height:24px;background:url("../img/ko_KR/btn_set.png?130306") -41px 0 no-repeat} +#smart_editor2 .se2_table_set .se2_rd{width:14px;height:14px;vertical-align:middle} +#smart_editor2 .se2_table_set .se2_celltit{font-size:11px;font-size:11px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_table_set dt label.se2_celltit{display:inline} +/* TEXT_TOOLBAR : FINDREPLACE */ +#smart_editor2 .se2_bx_find_revise{position:relative;width:255px;margin:0;padding:0} +#smart_editor2 .se2_bx_find_revise .se2_close{position:absolute;top:5px;right:8px;width:20px;height:20px;background:url("../img/ko_KR/btn_set.png?130306") -151px -1px no-repeat} +#smart_editor2 .se2_bx_find_revise h3{margin:0;padding:10px 0 13px 10px;background:url("../img/bg_find_h3.gif") 0 -1px repeat-x;font-size:12px;line-height:14px;letter-spacing:-1px} +#smart_editor2 .se2_bx_find_revise ul{position:relative;margin:8px 0 0 0;padding:0 0 0 12px} +#smart_editor2 .se2_bx_find_revise ul li{_display:inline;float:left;position:static;margin:0 0 0 -1px;padding:0} +#smart_editor2 .se2_bx_find_revise .se2_tabfind{width:117px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") 0 -100px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_tabrevise{width:117px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -116px -100px no-repeat} +#smart_editor2 .se2_bx_find_revise .active .se2_tabfind{width:117px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") 0 -126px no-repeat} +#smart_editor2 .se2_bx_find_revise .active .se2_tabrevise{width:117px;height:26px;background:url("../img/ko_KR/btn_set.png?130306") -116px -126px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_in_bx_find dl{_display:inline;float:left;width:223px;margin:0 0 0 9px;padding:7px 0 13px 14px;background:url("../img/ko_KR/bx_set_110302.gif") -289px -1518px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_in_bx_revise dl{_display:inline;float:left;width:223px;margin:0 0 0 9px;padding:7px 0 13px 14px;background:url("../img/ko_KR/bx_set_110302.gif") -289px -1619px no-repeat} +#smart_editor2 .se2_bx_find_revise dt{_display:inline;float:left;clear:both;width:47px;margin:1px 0 2px 0} +#smart_editor2 .se2_bx_find_revise dd{float:left;margin:0 0 2px 0} +#smart_editor2 .se2_bx_find_revise label{float:left;padding:5px 0 0 0;font-size:11px;color:#666;letter-spacing:-2px} +#smart_editor2 .se2_bx_find_revise input{float:left;width:155px;height:12px;margin:1px 0 0 0;padding:3px 2px 3px 4px;font-size:12px;color:#666} +#smart_editor2 .se2_bx_find_revise .se2_find_btns{float:left;clear:both;width:255px;padding:8px 0 10px 0;text-align:center} +#smart_editor2 .se2_bx_find_revise .se2_find_next{width:65px;height:24px;margin:0 3px 0 0;background:url("../img/ko_KR/btn_set.png?130306") -180px -48px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_find_next2{width:61px;height:24px;margin:0 3px 0 0;background:url("../img/ko_KR/btn_set.png?130306") -180px -24px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_revise1{width:54px;height:24px;margin:0 3px 0 0;background:url("../img/ko_KR/btn_set.png?130306") -245px -48px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_revise2{width:70px;height:24px;margin:0 3px 0 0;background:url("../img/ko_KR/btn_set.png?130306") -245px -24px no-repeat} +#smart_editor2 .se2_bx_find_revise .se2_cancel{width:39px;height:24px;background:url("../img/ko_KR/btn_set.png?130306") -41px 0 no-repeat} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE */ +#smart_editor2 .se2_qmax{position:absolute;width:18px;height:18px;background:url("../img/ko_KR/btn_set.png?130306") -339px -169px no-repeat} +#smart_editor2 .se2_qeditor{position:absolute;top:0;left:0;width:183px;margin:0;padding:0;border:1px solid #c7c7c7;border-right:1px solid #ababab;border-bottom:1px solid #ababab;background:#fafafa} +#smart_editor2 .se2_qeditor label,#smart_editor2 .se2_qeditor span,#smart_editor2 .se2_qeditor dt{font-size:11px;color:#666;letter-spacing:-1px} +#smart_editor2 .se2_qbar{position:relative;width:183px;height:11px;background:url("../img/ko_KR/bx_set_110302.gif") 0 -731px no-repeat} +#smart_editor2 .se2_qbar .se2_qmini{position:absolute;top:-1px;right:0;*right:-1px;_right:-3px;width:18px;height:14px;background:url("../img/ko_KR/btn_set.png?130306") -315px -170px no-repeat} +#smart_editor2 .se2_qbar .se2_qmini button{width:20px;height:14px;margin-top:-1px} +#smart_editor2 .se2_qeditor .se2_qbody0{float:left;border:1px solid #fefefe} +#smart_editor2 .se2_qeditor .se2_qbody{position:relative;z-index:90;width:174px;padding:4px 0 0 7px} +#smart_editor2 .se2_qeditor .se2_qe1{overflow:hidden;width:174px} +#smart_editor2 .se2_qeditor .se2_qe1 dt{float:left;width:22px;height:18px;padding:4px 0 0 0} +#smart_editor2 .se2_qeditor .se2_qe1 dd{float:left;width:65px;height:22px} +#smart_editor2 .se2_qeditor .se2_addrow{width:28px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -49px} +#smart_editor2 .se2_qeditor .se2_addcol{width:29px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -49px} +#smart_editor2 .se2_qeditor .se2_seprow{width:28px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -68px} +#smart_editor2 .se2_qeditor .se2_sepcol{width:29px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -68px} +#smart_editor2 .se2_qeditor .se2_delrow{width:28px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -106px} +#smart_editor2 .se2_qeditor .se2_delcol{width:29px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -106px} +#smart_editor2 .se2_qeditor .se2_merrow{width:57px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -125px} +#smart_editor2 .se2_qeditor .se2_mercol{width:57px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -125px} +#smart_editor2 .se2_qeditor .se2_seprow_off{width:28px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -87px} +#smart_editor2 .se2_qeditor .se2_sepcol_off{width:29px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -87px} +#smart_editor2 .se2_qeditor .se2_merrow_off{width:57px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -385px -144px} +#smart_editor2 .se2_qeditor .se2_mercol_off{width:57px;height:19px;background:url("../img/ko_KR/btn_set.png?130306") no-repeat -413px -144px} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > CELL_BACKGROUND */ +#smart_editor2 .se2_qeditor .se2_qe2{_display:inline;float:left;position:relative;z-index:100;width:165px;margin:2px 0 0 1px;padding:7px 0 0 0;background:url("../img/bg_line1.gif") repeat-x;zoom:1} +#smart_editor2 .se2_qeditor .se2_qe2_1 dt{float:left;width:62px;padding:3px 0 0 0} +#smart_editor2 .se2_qeditor .se2_qe2_1 dt input{width:15px;height:15px;margin:-1px 1px 1px -1px;vertical-align:middle} +#smart_editor2 .se2_qeditor .se2_qe2_1 dd{float:left;position:relative;zoom:1} +#smart_editor2 .se2_qeditor .se2_qe2_3{padding:7px 0 6px 0} +/* My글양식 없을때 */ +#smart_editor2 .se2_qeditor .se2_qe2_2{position:relative;_position:absolute} +#smart_editor2 .se2_qeditor .se2_qe2_2 dt{float:left;width:50px;padding:3px 0 0 13px} +#smart_editor2 .se2_qeditor .se2_qe2_2 dt input{width:15px;height:15px;margin:-1px 2px 1px -1px;vertical-align:middle} +#smart_editor2 .se2_qeditor .se2_qe2_2 dd{float:left} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > STYLE */ +#smart_editor2 .se2_table_set .se2_qbody .se2_t_proper2{float:left;*float:none;position:static;width:166px;margin:5px 0 0 1px} +#smart_editor2 .se2_qeditor .se2_qe3 dt{float:left;width:62px;padding:0} +#smart_editor2 .se2_qeditor .se2_qe3 dt label{font-weight:normal} +#smart_editor2 .se2_qeditor .se2_qe3 dt input{width:15px;height:15px;margin:-1px 1px 1px -1px;vertical-align:middle} +#smart_editor2 .se2_qeditor .se2_qe3 dd .se2_qe3_table{position:relative} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > CELL_BACKGROUND PREWVIEW */ +#smart_editor2 .se2_qeditor .se2_pre_color{float:left;width:18px;height:18px;border:1px solid #c7c7c7} +#smart_editor2 .se2_qeditor .se2_pre_color button{float:left;width:14px;height:14px;margin:2px 0 0 2px;padding:0} +#smart_editor2 .se2_qeditor .se2_pre_color button span{overflow:hidden;position:absolute;top:-10000px;left:-10000px;z-index:-100;width:0;height:0} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > CELL_BACKGROUND LAYER */ +#smart_editor2 .se2_qeditor .se2_layer{float:left;clear:both;position:absolute;top:20px;left:0;margin:0;padding:0;border:1px solid #c7c7c7;border-top:1px solid #9a9a9a;background:#fafafa} +#smart_editor2 .se2_qeditor .se2_layer .se2_in_layer{float:left;margin:0;padding:0;border:1px solid #fff;background:#fafafa} +#smart_editor2 .se2_qeditor .se2_layer button{vertical-align:top} +#smart_editor2 .se2_qeditor .se2_layer .se2_pick_color li{position:relative} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > CELL_BACKGROUND IMAGE */ +#smart_editor2 .se2_qeditor .se2_pre_bgimg{float:left;width:14px;height:14px;padding:2px;border:1px solid #c7c7c7} +#smart_editor2 .se2_qeditor .se2_qe2_2 button{width:16px;height:16px;background:url("../img/ko_KR/btn_set.png?130306") 0 -261px no-repeat} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > CELL_BACKGROUND IMAGE LAYER */ +#smart_editor2 .se2_cellimg_set{_display:inline;float:left;width:136px;margin:4px 3px 0 4px;padding-bottom:4px} +#smart_editor2 .se2_cellimg_set li{_display:inline;float:left;width:16px;height:16px;margin:0 1px 1px 0} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg0{background-position:-255px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg1{background-position:0 -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg2{background-position:-17px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg3{background-position:-34px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg4{background-position:-51px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg5{background-position:-68px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg6{background-position:-85px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg7{background-position:-102px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg8{background-position:-119px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg9{background-position:-136px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg10{background-position:-153px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg11{background-position:-170px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg12{background-position:-187px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg13{background-position:-204px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg14{background-position:-221px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg15{background-position:-238px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg16{background-position:-255px -261px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg17{background-position:0 -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg18{background-position:-17px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg19{background-position:-34px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg20{background-position:-51px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg21{background-position:-68px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg22{background-position:-85px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg23{background-position:-102px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg24{background-position:-119px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg25{background-position:-136px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg26{background-position:-153px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg27{background-position:-170px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg28{background-position:-187px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg29{background-position:-204px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg30{background-position:-221px -278px} +#smart_editor2 .se2_qeditor .se2_qe2_2 .se2_cellimg31{background-position:-238px -278px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg button{width:14px;height:14px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg1{background-position:-1px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg2{background-position:-18px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg3{background-position:-35px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg4{background-position:-52px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg5{background-position:-69px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg6{background-position:-86px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg7{background-position:-103px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg8{background-position:-120px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg9{background-position:-137px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg10{background-position:-154px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg11{background-position:-171px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg12{background-position:-188px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg13{background-position:-205px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg14{background-position:-222px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg15{background-position:-239px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg16{background-position:-256px -262px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg17{background-position:-1px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg18{background-position:-18px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg19{background-position:-35px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg20{background-position:-52px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg21{background-position:-69px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg22{background-position:-86px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg23{background-position:-103px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg24{background-position:-120px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg25{background-position:-137px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg26{background-position:-154px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg27{background-position:-171px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg28{background-position:-188px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg29{background-position:-205px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg30{background-position:-222px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg31{background-position:-239px -279px} +#smart_editor2 .se2_qeditor .se2_pre_bgimg .se2_cellimg32{background-position:-256px -279px} +/* TEXT_TOOLBAR : QUICKEDITOR_TABLE > MY REVIEW */ +#smart_editor2 .se2_btn_area{_display:inline;float:left;clear:both;width:166px;margin:5px 0 0 1px;padding:7px 0 6px 0;background:url("../img/bg_line1.gif") repeat-x;text-align:center} +#smart_editor2 .se2_btn_area .se2_btn_save{width:97px;height:21px;background:url("../img/ko_KR/btn_set.png?130306") -369px -163px no-repeat} +/* TEXT_TOOLBAR : QUICKEDITOR_IMAGE */ +#smart_editor2 .se2_qe10{width:166px;margin:0;*margin:-2px 0 0 0} +#smart_editor2 .se2_qe10 label{margin:0 1px 0 0;vertical-align:middle} +#smart_editor2 .se2_qe10 .se2_sheight{margin-left:4px} +#smart_editor2 .se2_qe10 .input_ty1{width:30px;height:13px;margin:0 0 1px 1px;padding:3px 4px 0 1px;font-size:11px;letter-spacing:0;text-align:right;vertical-align:middle} +#smart_editor2 .se2_qe10 .se2_sreset{width:41px;height:19px;margin-left:3px;background:url("../img/ko_KR/btn_set.png?130306") -401px -184px no-repeat;vertical-align:middle} +#smart_editor2 .se2_qe10_1{margin-top:4px;padding:10px 0 3px;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_qe10_1 input{width:15px;height:15px;margin:-1px 3px 1px -1px;vertical-align:middle} +#smart_editor2 .se2_qe11{float:left;width:166px;margin:4px 0 0 0;padding:7px 0 2px 0;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_qe11_1{float:left;width:99px} +#smart_editor2 .se2_qe11_1 dt{float:left;width:56px;height:15px;padding:5px 0 0 0} +#smart_editor2 .se2_qe11_1 dd{float:left;position:relative;width:38px;height:20px} +#smart_editor2 .se2_qe11_1 .input_ty1{display:block;width:29px;height:15px;margin:0;*margin:-1px 0 1px 0;padding:3px 1px 0 5px;font-size:11px;letter-spacing:0;text-align:left} +#smart_editor2 .se2_qe11_1 .se2_add{position:absolute;top:2px;right:3px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -54px no-repeat} +#smart_editor2 .se2_qe11_1 .se2_del{position:absolute;top:10px;right:3px;width:13px;height:8px;background:url("../img/ko_KR/btn_set.png?130306") -86px -62px no-repeat} +#smart_editor2 .se2_qe11_2{float:left;width:67px} +#smart_editor2 .se2_qe11_2 dt{float:left;width:47px;margin:5px 0 0 0} +#smart_editor2 .se2_qe11_2 dd{float:left;position:relative;width:20px} +#smart_editor2 .se2_qe12{float:left;width:166px;margin:3px 0 0 0;padding:7px 0 0 0;background:url("../img/bg_line1.gif") repeat-x} +#smart_editor2 .se2_qe12 dt{float:left;margin:5px 4px 0 0} +#smart_editor2 .se2_qe12 dd{float:left;padding:0 0 6px 0} +#smart_editor2 .se2_qe12 .se2_align0{float:left;width:19px;height:21px;background:url("../img/ko_KR/btn_set.png?130306") -276px -121px no-repeat} +#smart_editor2 .se2_qe12 .se2_align1{float:left;width:19px;height:21px;background:url("../img/ko_KR/btn_set.png?130306") -295px -121px no-repeat} +#smart_editor2 .se2_qe12 .se2_align2{float:left;width:20px;height:21px;background:url("../img/ko_KR/btn_set.png?130306") -314px -121px no-repeat} +#smart_editor2 .se2_qe13{position:relative;z-index:10;zoom:1} +#smart_editor2 .se2_qe13 dt{float:left;width:62px;padding:3px 0 0} +#smart_editor2 .se2_qe13 dt input{width:15px;height:15px;margin:-1px 1px 1px -1px;vertical-align:middle;zoom:1} +#smart_editor2 .se2_qe13 dt .se2_qdim2{width:32px} +#smart_editor2 .se2_qe13 dd .se2_select_ty1{width:38px} +#smart_editor2 .se2_qe13 dd .se2_select_ty1 span{width:15px} +#smart_editor2 .se2_qe13 dd .input_ty1{width:20px} +#smart_editor2 .se2_qe13 dd .se2_palette2 .input_ty1{width:67px} +#smart_editor2 .se2_qe13 .se2_add{*top:3px} +#smart_editor2 .se2_qe13 .se2_del{*top:11px} +#smart_editor2 .se2_qe13 .se2_layer_b_style{right:-2px;_right:0} +#smart_editor2 .se2_qe13 .se2_layer_b_style li span{width:auto;margin:0 4px 0 5px;padding-top:2px} +#smart_editor2 .se2_qe13 dd{_display:inline;float:left;position:relative;width:29px;margin-right:5px;_margin-right:3px;zoom:1} +#smart_editor2 .se2_qe13 dd .se2_palette h4{margin-top:9px;font-family:dotum;font-size:12px} +#smart_editor2 .se2_qe13 dd.dd_type{width:38px} +#smart_editor2 .se2_qe13 dd.dd_type2{width:37px;margin-right:3px} +#smart_editor2 .se2_qe13 dd.dd_type2 .input_ty1{width:29px} +#smart_editor2 .se2_qe13 dd.dd_type2 button{right:2px;_right:1px} +#smart_editor2 .se2_qe13 dd.dd_type3{width:20px;margin:0} +#smart_editor2 .se2_qe13_v1{_display:inline;float:left;margin:2px 0 1px} +#smart_editor2 .se2_qe13_v1 dt{padding:4px 0 0 1px} +#smart_editor2 .se2_qe13_v2{_display:inline;float:left;position:relative;z-index:100;width:165px;margin:4px 0 0 1px;zoom:1} +#smart_editor2 .se2_qe13_v2 dd{width:18px;margin:0} +#smart_editor2 .se2_qeditor .se2_qdim1{clear:both;position:absolute;top:25px;left:115px;width:60px;height:23px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim2{clear:both;position:absolute;top:55px;left:24px;z-index:110;width:70px;height:22px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim3{clear:both;position:absolute;top:55px;left:118px;z-index:110;width:56px;height:22px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim4{clear:both;position:absolute;top:81px;left:23px;z-index:35;width:116px;height:35px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim5{clear:both;position:absolute;top:31px;left:106px;width:68px;height:26px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim6c{clear:both;position:absolute;top:25px;left:28px;width:29px;height:23px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim6r{clear:both;position:absolute;top:25px;left:57px;width:29px;height:23px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_highedit{float:right;width:56px;height:21px;margin:-27px 8px 0 0;background:url("../img/ko_KR/btn_set.png?130306") -329px -142px no-repeat} +#smart_editor2 .se2_qeditor .se2_qdim7{clear:both;position:absolute;top:55px;left:24px;z-index:110;width:150px;height:48px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim8{clear:both;position:absolute;top:105px;left:24px;z-index:110;width:150px;height:37px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim9{clear:both;position:absolute;top:55px;left:111px;z-index:110;width:65px;height:24px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim10{clear:both;position:absolute;top:55px;left:100px;z-index:110;width:77px;height:24px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +#smart_editor2 .se2_qeditor .se2_qdim11{clear:both;position:absolute;top:55px;left:65px;z-index:110;width:115px;height:24px;background:#fafafa;opacity:0.5;filter:alpha(opacity=50)} +/* HELP : ACCESSIBILITY */ +#smart_editor2 .se2_accessibility{z-index:90} +#smart_editor2 .se2_accessibility .se2_in_layer{width:568px;padding:0 10px;background:#fafafa;border:1px solid #bcbbbb} +#smart_editor2 .se2_accessibility h3{margin:0 -10px;padding:6px 0 12px 0;background:url("../img/bg_find_h3.gif") repeat-x;font-size:12px;line-height:14px;letter-spacing:-1px} +#smart_editor2 .se2_accessibility h3 strong{display:inline-block;padding:4px 0 3px 11px;color:#333;letter-spacing:0} +#smart_editor2 .se2_accessibility .se2_close{position:absolute;top:10px;right:12px;width:13px;height:12px;background:url("../img/ko_KR/btn_set.png?130306") -155px -5px no-repeat} +#smart_editor2 .se2_accessibility .box_help{padding:0 2px;margin-top:8px;background:url("../img/bg_help.gif") 0 100% no-repeat} +#smart_editor2 .se2_accessibility .box_help div{overflow:hidden;padding:20px 21px 24px;border-top:1px solid #d0d0d0;color:#333} +#smart_editor2 .se2_accessibility .box_help strong{display:block;margin-bottom:2px} +#smart_editor2 .se2_accessibility .box_help p{margin-bottom:28px;line-height:1.5} +#smart_editor2 .se2_accessibility .box_help ul{width:150%;margin-top:10px} +#smart_editor2 .se2_accessibility .box_help li{position:relative;float:left;width:252px;padding:5px 0 5px 9px;margin-right:40px;background:url("../img/ko_KR/btn_set.png?130306") -475px -51px no-repeat;border-right:1px solid #f0f0f0;*zoom:1;line-height:1} +#smart_editor2 .se2_accessibility .box_help li span{position:absolute;top:4px;left:138px;line-height:1.2} +#smart_editor2 .se2_accessibility .se2_btns{padding:9px 0 10px;text-align:center} +#smart_editor2 .se2_accessibility .se2_btns .se2_close2{width:39px;height:24px;background:url("../img/ko_KR/btn_set.png?130306") -235px -120px no-repeat} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_out.css b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_out.css new file mode 100644 index 0000000..2719f13 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/css/smart_editor2_out.css @@ -0,0 +1,12 @@ +@charset "UTF-8"; +/* NHN Web Standardization Team (http://html.nhndesign.com/) HHJ 090226 */ +/* COMMON */ +.se2_outputarea,.se2_outputarea th,.se2_outputarea td{margin:0;padding:0;color:#666;font-size:12px;font-family:'돋움',Dotum,'굴림',Gulim,Helvetica,Sans-serif;line-height:1.5} +.se2_outputarea p{margin:0;padding:0} +.se2_outputarea a:hover{text-decoration:underline} +.se2_outputarea a:link{color:#0000ff} +.se2_outputarea ul{margin:0 0 0 40px;padding:0} +.se2_outputarea ul li{margin:0;list-style-type:disc;padding:0} +.se2_outputarea ul ul li{list-style-type:circle} +.se2_outputarea ul ul ul li{list-style-type:square} +.se2_outputarea img,.se2_outputarea fieldset{border:0} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/editor.lib.php b/AvocadoEdition/plugin/editor/smarteditor2/editor.lib.php new file mode 100644 index 0000000..b163cdb --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/editor.lib.php @@ -0,0 +1,166 @@ +') ) { //textarea로 작성되고, html 내용이 없다면 + $content = nl2br($content); + } + } + + $editor_url = G5_EDITOR_URL.'/'.$config['cf_editor']; + + $html = ""; + $html .= "웹에디터 시작"; + if ($is_dhtml_editor) + $html .= ''; + + if ($is_dhtml_editor && $js) { + $html .= "\n".''; + $html .= "\n".''; + $html .= "\n".''; + $html .= "\n"; + $js = false; + } + + $smarteditor_class = $is_dhtml_editor ? "smarteditor2" : ""; + $html .= "\n"; + $html .= "\n웹 에디터 끝"; + return $html; +} + + +// textarea 로 값을 넘긴다. javascript 반드시 필요 +function get_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "var {$id}_editor_data = oEditors.getById['{$id}'].getIR();\noEditors.getById['{$id}'].exec('UPDATE_CONTENTS_FIELD', []);\nif(jQuery.inArray(document.getElementById('{$id}').value.toLowerCase().replace(/^\s*|\s*$/g, ''), [' ','

     

    ','


    ','

    ','

    ','
    ','']) != -1){document.getElementById('{$id}').value='';}\n"; + } else { + return "var {$id}_editor = document.getElementById('{$id}');\n"; + } +} + + +// textarea 의 값이 비어 있는지 검사 +function chk_editor_js($id, $is_dhtml_editor=true) +{ + if ($is_dhtml_editor) { + return "if (!{$id}_editor_data || jQuery.inArray({$id}_editor_data.toLowerCase(), [' ','

     

    ','


    ','

    ','
    ']) != -1) { alert(\"내용을 입력해 주십시오.\"); oEditors.getById['{$id}'].exec('FOCUS'); return false; }\n"; + } else { + return "if (!{$id}_editor.value) { alert(\"내용을 입력해 주십시오.\"); {$id}_editor.focus(); return false; }\n"; + } +} + +/* +https://github.com/timostamm/NonceUtil-PHP +*/ + +if (!defined('FT_NONCE_UNIQUE_KEY')) + define( 'FT_NONCE_UNIQUE_KEY' , sha1($_SERVER['SERVER_SOFTWARE'].G5_MYSQL_USER.session_id().G5_TABLE_PREFIX) ); + +if (!defined('FT_NONCE_SESSION_KEY')) + define( 'FT_NONCE_SESSION_KEY' , substr(md5(FT_NONCE_UNIQUE_KEY), 5) ); + +if (!defined('FT_NONCE_DURATION')) + define( 'FT_NONCE_DURATION' , 60 * 60 ); // 300 makes link or form good for 5 minutes from time of generation, 300은 5분간 유효, 60 * 60 은 1시간 + +if (!defined('FT_NONCE_KEY')) + define( 'FT_NONCE_KEY' , '_nonce' ); + +// This method creates a key / value pair for a url string +if(!function_exists('ft_nonce_create_query_string')){ + function ft_nonce_create_query_string( $action = '' , $user = '' ){ + return FT_NONCE_KEY."=".ft_nonce_create( $action , $user ); + } +} + +if(!function_exists('ft_get_secret_key')){ + function ft_get_secret_key($secret){ + return md5(FT_NONCE_UNIQUE_KEY.$secret); + } +} + +// This method creates an nonce. It should be called by one of the previous two functions. +if(!function_exists('ft_nonce_create')){ + function ft_nonce_create( $action = '',$user='', $timeoutSeconds=FT_NONCE_DURATION ){ + + $secret = ft_get_secret_key($action.$user); + + set_session('token_'.FT_NONCE_SESSION_KEY, $secret); + + $salt = ft_nonce_generate_hash(); + $time = time(); + $maxTime = $time + $timeoutSeconds; + $nonce = $salt . "|" . $maxTime . "|" . sha1( $salt . $secret . $maxTime ); + return $nonce; + + } +} + +// This method validates an nonce +if(!function_exists('ft_nonce_is_valid')){ + function ft_nonce_is_valid( $nonce, $action = '', $user='' ){ + + $secret = ft_get_secret_key($action.$user); + + $token = get_session('token_'.FT_NONCE_SESSION_KEY); + + if ($secret != $token){ + return false; + } + + if (is_string($nonce) == false) { + return false; + } + $a = explode('|', $nonce); + if (count($a) != 3) { + return false; + } + $salt = $a[0]; + $maxTime = intval($a[1]); + $hash = $a[2]; + $back = sha1( $salt . $secret . $maxTime ); + if ($back != $hash) { + return false; + } + if (time() > $maxTime) { + return false; + } + return true; + } +} + +// This method generates the nonce timestamp +if(!function_exists('ft_nonce_generate_hash')){ + function ft_nonce_generate_hash(){ + $length = 10; + $chars='1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'; + $ll = strlen($chars)-1; + $o = ''; + while (strlen($o) < $length) { + $o .= $chars[ rand(0, $ll) ]; + } + return $o; + } +} +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_b1.png b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_b1.png new file mode 100644 index 0000000000000000000000000000000000000000..8bd0c06fb96d0d38ad4fe581fd31cf2bf5a4a10e GIT binary patch literal 115 zcmeAS@N?(olHy`uVBq!ia0vp^Od!m`1|*BN@u~nR$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1GqMj~}Ar-fhQW6ppSd-Y)*fbb83>X+{7&y~5tm^|RVDNPH Kb6Mw<&;$Uf9~={^RHgL z(%jsM`0>-tn>YXd{deci?ccwDA3uKl=g*%%zW;dgF72=ScTQnL2LpOH^US~0i)UHjxoMcx%+mz&Al)UtA2O(=9ex?vckf$A|kTP%(ASk zvP?{}yu7juyy8N9l8jOUQu0#LGV(G4i1@!Yv{mn~cN`Sa(k zTen`ldgcHB|FdV$W&i`l|J)J20SYdOC5b@V#=fE;F*!T6L?J0PJu}Z%>HY5gN(z}N zwo2iqz6QPp&Z!xh9#uuD!Bu`C$yM3OmMKd1b_zBXRu#Dgxv3?I3Kh9IdBs*0wn~X9 z`AMl(KsHENUr7P1q$Jx`$q^)>0J76LzbI9~RL?*+*}%+D!OTR@(8R#f#8OAW$iUD* z-_S_kz+BhRz{=Fz%D_+o3Y37h6{VzE1-ZCE?E>;_l`=|73as??%gf94%8m8%i_-NC zEiEne4UF`SjC6r2bc-wVN)jt{^NN*WCb*;)Cl_TFlw{`TDS%8&Ov*1Uu~h=P6yk;4 z0=Thx#d=`x=q2ap>Q^Kd=o{)8fV>1#=KlDb#X~hD#E>34K5C;EJ)Q4N-fSW zElN%WDpv+sRbb^@l$uzQUlfv`p92fUfQaY~=8hI_rcS1YhOUN=hOWjImga7T#?B^g#+I%y zy)OC5rManjB{01y2)&j#^@5T@ZUN9{m(-%nveXo}qWoM1u$Qeeal6F~r+HAlDY)HY zj#IBb&@uX;h((HMm=G}afSB-P3*^8Perg^twHE=CHRJz(fB*dc_4CK~Z(qNB{`B#~ z`*&~Oyngla#q(!RpFDo_@WK6ickkT3b@RscYgeyazI5@z`EzH_oIZ8(#PMTCj~qU9 z@WB3kd-v?#wR6YzZCkf&-n4PU`gLp9tX{Qp#qwoKmn>eiaKZd}bLY&SHFL)FX;Y_6 zo-}bne_wA;cUNaeds}Nub5mnOeO+x$bya0Wd0A;maZzDGeqL@)c2;IadRl5qa#CVK zd|YfybW~(Scvxsia8O`?zn`yFMfd zYiVkztEs9eD=8|-%gM?}OG!$Ii;0Q|3keGF^YQXy^Buv$KFh+tYi^To<#Z(c2Pco^c5kPtcjebxE@vR>|&Dogle9hP5AOwem=Rcg9f VvgXEWv(tC0Hgld~5n^Jn1^{#J-!cFI literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_find_h3.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_find_h3.gif new file mode 100644 index 0000000000000000000000000000000000000000..06627d98250b56f75525c97adf0a19ab0c791bd7 GIT binary patch literal 159 zcmZ?wbhEHbWMoigIKsg2@9)1aUq1i({rl(7pMU@U{rc_emoHzwfB*jL=dVA%e?NWt z^y`^)%+7*gzTJ=CK+HG;8KjfKG)044@r AQUCw| literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_help.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_help.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2aae94ba5ab45792b1c9245acf7310ad7e6bb82 GIT binary patch literal 2360 zcmV-83CH$FNk%w1VK@Tx0mJ|R^z-x3(9p!h#QXdE`T6LyWj9Q49%6> z@A$la&qvXheSw05goTDUe}{^TjE#aZj3rP1s(hGorOSdXU&{0sbEeIDHE-%Mli|jYuRM-SIg8@TnD1TA z%vsUo&Y&%B4o#ZR=hCQcoKDR;+vwJ?*{qID+t2ITxWUZMO?x+Q*uHZ!;-z@$5 zV(;Vks(-)M{{C47V1QB$NT5>&9;j6Rf(jbNV1q(E2%%3BPN-9b7TSbihB9r)p-Ucq zs8Wa`nnYrWBAtk$M=GwUQHw63bX$zh!ARpoHr~k6j5-RJV~+{_2qa8A4vCwPMgoLn zk~9^`BydhXIb4)d8b@W7$z6#hb6RfsT$f%-2WFVnjY%eUW}dlSnreE-W}D%?2`71S z&Us#)cB+SGp6%_)CwzYXIbWcH+DB-i`5lTVe~K>pU!#r+2x+7RPD&|)mR`DGrkXm) zX{Ql>3Mz%7j(TCKrfP_4svRN`fncoObwmWOE*5K_w8DBTuC?we>i`ibpsTNI9if1* zwi0`mvB)ah=dr^&I~KFiO8XW6vj`+>Eq@3co9(vqb*sR);MylHx#i|}uD0n;6~Maf zs_QMg@gmsm1L)R!)w>ViORv61@#`^>B%(BN7CqVMcBPPH=12WSbVFC@{JhRRt1;De< zKvOt$&P88%^v_9mBy`V6H*NCLQfo+c)gAKeK-5^TB(wutGu<_g34qP@*d~@8HrigR zeKy-9mA$~*a66sA0&|O9H$p<=P50g?-JLh!DGL5K;bi-*H{$>Fy}$vBGrms%2jC64 z$k2SCtz=&!Fsx$Lgj9%SsZ>+aC) z1?28KL6jE|Jnh4aQ~dGC^L>Ev!Z%OT^UO;>(DKn+pAYuPYwr#9*?T`a_}z<-6#3>) zj(+;vug^YC?!O-o_wvJUyb<+}F2Vif=Z_2t1uy{q{PzwL7(jsiBj7L$2!H`9P#q)y zKm!x_Kwm^~f)#|I1SIId3@UGf81x`eK-fVMcH@F2G~qTPSb!9&@EQO_;0wWFKpD=E zC=xJ02yf^O5>k+dT=5|gd&t2b4p9{-G~yA#BE%(1BZ*FY;s#r+g)hAy-sRB~uT zEh>Y7S@hyBpeV-waWt`v#ULXZw^+nArtyq!93vd#NR=suk&d&#VioZyi5lLKkFWsa z9s&7@ITA9DhCE~})Tl^Awy}{|NhBoOA<0P=#*TxuBtQ1oMNP88kD2r&UUIlYQ6jOD zrX&k0Qz?&CveGfGeB~t=Da$LyvX+!!;U95X2|e<16rlX2Ep@m{Vcz4G#)Jzplj)gd zGSd*Wd}c14Da}njvYNfbBsMMK%WY2cfW`FYCW#qJafTt9=4|FQ)2YmLvQwRLebE?f-fKkZ3MfezFd^gO635~@&xFtni&c_>81aLXp0S_3mB4J6`e9mAvOQZ(Py4UiG?_z3+AJTH!li`J$D+_qA_X z@w;FBij}|r_3u{!JYWHDmB0r!Fjf(~U7q&1{F}z_7CzZn= z_OMYwJYo?GmBc4D@lR2_VioU{#V>X-PGLM_8P}A?H@2}%alB(4zm&&6_AyI=JY*rK zl*mUmvPqG=WF?Q3$xn9jN1;4rDRY#{SGICSvAkt1Ta?RR_VPr*JZ3RNl+0%~b3@U* zW;H96&2M(|LE$`SIS-W1cee9C@w{g}^OMhi_A@>KJ!nDKlhB7Yv^){LXhpx1(T{eu zG&>& z*0;7bGjY9ZT_=;*zxK5;fjw+t3zOK#Huf)(y=)Q+;MvfQwzQ{B?P^>5+Styvwztjg zZhQON;10LA$4%~XoBQ18PPe+(&F*%)8`>mf?GGeK?|R$&-uTY9zW2@Ve*63101vpp e2Tt&U8~or1Pq@Mt&hUmi{NWIfxWx4x0suSVU$e&m literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_icon_tool.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_icon_tool.gif new file mode 100644 index 0000000000000000000000000000000000000000..ef680ebee2ebd98b06850b1af3e7b4d5414487b8 GIT binary patch literal 103 zcmZ?wbhEHbWMoia*vtR||NsC0`SaKBKYxDy`t|+CkKccO{rK_y`}c3ZfB*jV>(|ep zKYu{@-@XA=D*j|)WMJTD&;jWLnZdv!V$hSg%usWsuS>j7gvgnT3Vg3D1R1OWw2C*G literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_line1.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_line1.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c506a4a18bc89e5d528a378821b1f32ee0a3ef1 GIT binary patch literal 43 scmZ?wbhEHbWMp7sXkcJ?`t<4l|Nj+#vM_*v4u}BBFfcK>a4}c|01d|pvH$=8 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_quote2.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_quote2.gif new file mode 100644 index 0000000000000000000000000000000000000000..eb8cd04a7e838830dcace5d90b03bd7d31dd473c GIT binary patch literal 56 zcmZ?wbhEHb!F7Ld^{b=IEYp=7? JRxmJF0|1fQ5BUH9 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_set.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_set.gif new file mode 100644 index 0000000000000000000000000000000000000000..14d09739d40c56324004c0d8d409d26a0bed8e0b GIT binary patch literal 941 zcmc&y{ZCV87`=1l_R`8I;p;+6L4|UuEOSG#ieos`sc2lnLR`OqZE3p5fXsckA4pJC zC=5mGvKcdnaZ8A7leM=WfV4QWF(~aVA)&Z>@B6;@7A+%wL^2uK58dUj*!k&sPEO7_ z$@9E*=zwll;|JK+*n{KP=owuLEzJc>cUK~_MqP$ms^t4)7 z?+**4D+!K8_H>`cembLTs|Y~4Ly_S!Z}E?u@? zxh&uL>K3U4m&&iHGcqLdT)bA2er=OX@}{IZSN#?3a$i!Zs9jQNS^7IK=nB|X?RvRm0Ylq+Ki+d%=Wdw-?w_Kb)`T$qZH?z=cJ$QBUu?j08~EE_l&g<;htNb<`d0Id z_ZMNZZ%fVfBg2lxz&B+lxS3(+L#DsFM}2gJUYZ-I9W)0=T+5N6_XF3Dj=CR3y(gEs z;OOW4)^X1U|K>g3dGwntf9HjywT~BrS1T^Q)Hd?z(!yZbYH)0H^$DEl$v@`1v$hhS zt5=77WB;x`6$0NK^H;Y0{m;rWVElgZQ*f%^^gPoFPZJu#)GRBH!;a@E6grzxXGP~o z%Rr+=@majF^G+MZcj4y`@-}M3gSt!IalU8U@6^pNO6ILXukMW3aA8lSPPkZwm&E$^ ZWqnv^eqD35UuHX8z7(@7o@EhO#eYNFuiO9t literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_text_tool.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_text_tool.gif new file mode 100644 index 0000000000000000000000000000000000000000..60d61def8e0070f2846866c806e634de9d5d1bfd GIT binary patch literal 1123 zcmZ?wbhEHbWMq(KSj52als47YguJQ{>uF6ifOi{A8 zQ?RM9s>m(KO)W`OsL0L9E4HezRZ2|BPfE1{vO&W7N(x{lCE2!0jvxsIke$x?MX3s= zdIq}524;o|W+r-uCI*%!mO2VX28IUuhDQ1Z=DLOkR;K1w28Ieypait7C?(A*$i)q6 z7m#PGlu=SrV5P5LUS6(OZmgGIl&)`RX=$l%V5DzkqzhD`TU?n}l31aeSF8*(!6mgg zxhS)sBr`ux0c2ugQhsTPtrF0s5HI8wz>Uo-)&qM-FF8L~zap_f-%!s0KQ78XXd5kmluQ8`}$gW<`tJD<|U_ky4WfKP0-8COtCUEFfy`qbv1Ic zuy8XpbTxExa<;T|baON^b2KzGF?WXPb;(aI%}vcKf$2>_=rzWv7nBro3xGDeq!wkC zrKY$Q<>xAZy=;|<+bsq-&4cPq!R;19oO<Vgs zyL#pFrHdENpF4Zz^r@34jvqUEVojbN~+qz}*ri~lcuUorj^{SOC zmM>enWbvYf3+B(8J7@N+nKPzOn>uCkq=^&y`+9r2yE;4C+ge+in;IMH>uPJNt12tX z%Sua%iwXi?qaq{1!$L!Xg8~Em{d|4Ay*xeK-CSLq zog5wP?QCtVtt>6f%}h;V~xOjJZzNKk;E wkC%s=i<5($jg^I&iIIUp@h1zojL-p*pmKzPna6@v=AFthqi)gg7c30c0RDfFr~m)} literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/bg_tool2.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/bg_tool2.gif new file mode 100644 index 0000000000000000000000000000000000000000..f96aafb5bbac1a85b473181582fac41010cfab92 GIT binary patch literal 104 zcmZ?wbhEHb=s>#-~6pTP;w)q8_poZbCD;f82R=Ddtm>(rk}>HI!dlFMJQ?)LU~{|_t>aL|zw HX0QeT_nI%< literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_698.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_698.gif new file mode 100644 index 0000000000000000000000000000000000000000..96350892c5785f00554f768d4e4a628b0983d88f GIT binary patch literal 139 zcmV;60CfLHNk%w1VK@Q^0Du7i%*@RH|NkNR1OWg50RSuj0000u0tf&A0%D9GfXnR< zqnxzbi?iOm`wxcVNR}q4OzFwC?hD8AOxN~ZuaS=T{tpZahs0uz!ZRwD%%<}RjW&`F ts`QG@YPVdimGSM0$K-YSA=zdoK06Q_GLn;6O literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_890.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/editor_guideline_890.gif new file mode 100644 index 0000000000000000000000000000000000000000..5a241e1e4a2c712529b68e98e5aac867147eda79 GIT binary patch literal 155 zcmV;M0A&A1Nk%w1Vfg|G0Du7i%*@RH|NkNR1OWg50RSuj0002_0tf&A0&JmtxX9S( JVQ5$Y06W*+P%{7k literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/ico_extend.png b/AvocadoEdition/plugin/editor/smarteditor2/img/ico_extend.png new file mode 100644 index 0000000000000000000000000000000000000000..1aa88ff68f25ca28ba99905d1e4d439f7c564d10 GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^AhrhwGm!jIGvx)4k}PqJC<)F_D=AMbN@Z|N$xljE z@XSq2PYp^FE7t_m-N=ns~Z~||NniTmX`Ma|Nk&; z#xkHX&XOR%U?3L^7=ryPgn)u2o-U3d6}Qgx2XZwyaJaaan}7eO?iZY<{mNXZ<@g5~ zfyvDAs;@3M$tp{RPhVj;b(eRd&5n9Efr|kh*CyRRClI`Hx5%yk_S=*`o806(STwQo zR{VZCf3A#&|BI%XcU12rEPw1%6=2qJ=TsRZ8^gt;qC%q6uLc0^XYh3O Kb6Mw<&;$VU3T+Mm literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/icon_set.gif b/AvocadoEdition/plugin/editor/smarteditor2/img/icon_set.gif new file mode 100644 index 0000000000000000000000000000000000000000..842d3944b3a8193357c84e5994343a46d09ee17f GIT binary patch literal 4611 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
    5KBLruV-QJQMb^J4 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

    MWvXlQ~*6bA`$_0%9LB3fq^{0OFl!d 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

    1R(@7~ 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

    (ySrQ4+v^(}t7~h^D=TmB{}-~SXQzAn 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 Za-1U_>uAS2;xUhU+#?_RD8qmN06T$RcvAoX literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/ko_KR/text_tool_set.png b/AvocadoEdition/plugin/editor/smarteditor2/img/ko_KR/text_tool_set.png new file mode 100644 index 0000000000000000000000000000000000000000..c1e5be374ae008c217d47a2b7f3485af8166b4a3 GIT binary patch literal 11403 zcmdtIg;!fa_cj`&#ibM}1&V8tB85_1i&H2?iaQi2P#l80v=k_A#jQYb4=%-}Xn+)V zhXe>A-|74Q?!Di-Ykl_*xU*Jr_E~3U_RQYTnLN)-qTgz~A;N!(4+4RRl$GSQK_E;B zU}xZB0pH%pHVxo{=b~ib1_BX0{`bKEWn?`8f$%l$<>cPJwR3iNcC&MKVNjNnV{rNG zY-8_e4YXUzerK!mZjVv|v3e=18Wr?i)mfVYmqA-LHi$fdjf)YFR3(ZrZ;?W)`;meI zHqFqFD6FqvgW@Q(xCvwM7jQNi^S_1`M8ymv*Zc|`=Gqb4WA_d7k~=>yvg;;rx^M|o zlmxY21`(FYK6~^xbg*w=ZIf3z7@x%jM2cHy#ps4&#sFOhh>JgG>cWA5FuZ37a6w(_ znO!evBhe)Lvgt+`L17qO?g_6{af8S~(!O71i$T(g7(v--Z0|rnut8=cmKGbJw>%&- z_Q35KP*C=Dx*rC}@H-;~#*YLL!(;0xd61nL=;wrPi~>mi1&G{6wNDhZzyo@rtY@PH z`qc#L8Yd;F1>q8cUT8&ybAqt_KxRYC%-*1|bP&1Xxt{ph^D5FEE+A6rwc;%-q6)!= zxIC^ndV0LiIL4K!o|6lkW1443^Y-|pQwszOk^H?F1%ZAfPyn;NKzWZ7SB;Mge{Cc- z<=O9ih-R{|*tp-CsBn=6f!5purtZ1<>YfIPJq&WX&u2Zxwlg94;em*?sU?wa0R7lo z(z|f^7aN7VZ!L?9Tbr8;Dt)qs=EHja_qIKzU3w_Tn*i}U#MNKOI!myCaqt`L>%Tpt zmuf|{6Nz|X7R%f5Z|<51(06n*Onu50E&5#K8(L(pU*$96E(D60qGb~~`&p;aR_ics zB$g!XCFs{jNesUPo>F5=EVwE=slI#HIsybbZ*%Vc!-0zxWEZ+N;e|etLcRIH3JS7O zPILuXC@pb%hJ~)ODc-K!X}GlVfYP?UAz1dCO#k%w&B#NL29gMQ&pw4`P z^Td|g>q&K*S~2xZEcKwy3laW|?7LTLgP@wWXox+F~Wj%ko6!1XTp}>a;Ju z+eqPTq`6*axohC zN&<%{a*?=#?gL$bTm5J9*SfD)Gsd%yrTqIZQ}+05^(ROt76dmMACGYM*=N7YoOxqQ zW!vHwdJz>Htr{}In<~khNi(oA)Um1Je&uSs<~x0romrRJb5shgJ{CTVAzB}I^%{K5hDGeA>LGuXCahndfkFF~(z{#R3xS2@D`gh~=F`8jt( zazk8XRbbV?bX26PX{c#Lv)4JtG#n-u$c(l^`=X~nB|)qhwph`@GQozJ$ZKCPW9L_? z*HCMC?c$M4+>aI+3Yqwj%8;$@N=Cb(!*7+0h@G_YgmHV~@V5cGbCWpc+vc&o0fg+~ zk>Pp~QeR!7^q)@gr@r)>T9$Kz$=}MS$ggJF@@tA#^QgS!k}T)_D83}pD%2`9z-wbL zI;)?puk5HwE6U4NCH%<|0=ql9h+NNJC)n_#O5+iek-DOV|F9P9aGFV?U4K0S0jwoH6e!c$QTazoS0hqe$$Xtdnc>OcBp~s+gFiGe;hU>$Iiq?~qwT)!wvFe=PwVj7`~FX{O?=Oi zaeh10ef#;qfCs-(ws=?P1IIiUPOYuAo=xXi^ss13Mb7iFqtUuy=r@t9lU(!>Sr6G- zVq;N+svZxW{&vUDkD|5Wu0Bxw4T=ZPBXl4B6mO1c2APqI3ReBzZLF(usnZctf|ju0BbP6jmV~vq==5GB8O6?QUoq=EPHR!L^=<5rZ0c5 zFRSQlv6`@%w%OZW<;gK5PAN~_P9^?Cw767H1kW zCBMhV#H4fzbuM*ob%c+nR~pRcuRl#4)A+T+g$`$-hV2NHK=(io}QfU?(W{)+?=1C!{Latv-4}jHBc@tFK=&e5!Z;Am>3-$ zo%?(A%*@Qq&F$6I)h%!V3^@E2iIkI*yGNlqJ0aQG*{7#xKvO9xsXHVRb&r~#o4>le zLf+l&?Cd}wkUQkv`Ptbm(DD{}4fsGHu5WJcQTK2-JUTkMsi_HhhrGPH>g(%^h=@Sm zBF`@_Q7BYTPtO(nYJY$4?hf#Fcd&o3x4U<7eoFIfLa$;v^*KA^fzVE$TU_CuOU0YkfN8g_m6kNjL3Eob{#l@}W=D-|!--W()Ft{d^l&Nld^H-l+v-)m zpT#`yBHZ5IMlQWV!@=nL`;Co_v$>(Ix$4m>+rh!X_V)JG)zvFFVsFUg{PYNUdy8Iu z*O!EQb8~%sd~$bCFh4)v)6;!^d2x5qeSLj%*vpB&N5iiXBe~4y6H0gc-&Pl<@6qVF zxq0+9=FO}I0*<)4yj)ydJO?syegOn%zCm+-Ztm(|u;6zn6aoQ1K0dy?LmeF*U0z;f zWo3nihGu4FE-ym`1qIRnDS*?3g$1CKrKKe(6uP{;yt1+aj1vZf{r&qF2-^DkIxrC+ zK3iK`!0Z610BGFX+uPsYKR7rzJUj$C2fP3|1@Z_a`WzU|1%OQeDF6WfWevb8fL;Kr z0GI)61DFBO4mfwL7taIUn|XI_jd%YY%>UoML4AtUvmg-Npt8J-j`z}Gwoe?*VD?Eg zu9dXNL$f3X-yYIlwn58hWQ-qqWu9^hp4tt}4JqDXzX?gUHPFT$d9GT^3ax!$*qBQM z(*v`}kg+Jz(ujH{h1V@wos2Q9ZgfOO8jA#;TGYgX6yr)^m^s`n; za>TYmy*^jrLyVnQ6$NdQcQxM0vh*&lSCz7NN201|3mp?evKxeyS!=a`tz4qw?o*P&cLTmb!ZxDfI2je&ytAiQ4u!HWqnl8^t zG;_pndQ(*$V)!Hs4~R^G^>bXU{HHR*^{bS)%S`oaGTDd9s^IRK&uV0}d$$2#XanAn z`uc$_#aXuB)t>V*dJ_fnzHMlUSRC2{C*)f8%kz@shlj7$@%@}RgvM1%EIpigV+~cx zrT*ssn}M3PeM1$M>u-Klcd}do1K<5d(s!bN4|d*sh~ATUb2i2keIgr7x_%BV_VSfo z=G3Lx7N0z12K#@izD^W_fJdmHRxm|faN}@XN8KTmuIx*6WAg8>brRpZ#GO4NPevxh zFDK_o#NGcM1fEX{^3`?hEI-FFm6bfXvpnT_F@NM+5{1bqOk5tw#W-XHyY^K5Xm(`= zKDj>UF}+>)1@Aqi%f#Mw_X4rXIr{|#2}$;52cC7^w2|DM1=m&6d7rgApME+v_5mxa zYU|O$68;s9GwTr4bro(|Wo`9JMJOLNt^1x6mq}%Vb7U+Iu0}m+R-%}Z_^(Ue=;{%Y zquub%=AB@w6Q931dh~$B-oEN4db0i(>7)5P*I$powAO8Be7vrjN{zdxy~^HKmkpyZ zMC2e_-ZvI!sp4YV$>r2D)x@;M+8`xa#URDnfU-uLGq$v^R%y6ayN@X)xmH_uIGRNx z%i4ftD~%IcZ0(szsV_XkIjDxwT%24RrLrn+MTZFr>a1O@=RWx65e5I0Stb`rY%rH6 z60O30P|bZnHOI$&-Jc0`K9^bf>(??)Ow+kNHFcVQe8AD_$tv>hVgiO-@$2;bDFNwT zY$|D}MofCxEa1P8Glv)A#E|m!1;!p0B9vd1CVyv-eOSVsSgVwV3m?Vo&`$}K9Z<-4JT#v$X9$3q+(XY?wNi~Lz5Zrl(v5%#x_l5u5~NmYJ2 zy}@T?Yu!v+jnYqwNKF$~HDPZw_+VsY6sFKL+fSzTdwt!)-qrOHWfOFpNh|u7KA8#? zWw^o<6LLx_D%IG^U!+-98Y#ZgNxjx4bsrHi=DI^s6mB;o>8s@`6-Ws^J zD}KIW(8N7k9Pu*xDgI+~pPmqg1rOy{YAQ~ls*W$ZSzoV&Fo4V=2plzm5i*$NlZlZM zU_N~KJdXtz(~LbaL!T66hgbQGoptHCR&>wRYXO*QFC$&kOR+avKKqo5hmSl-EgAMMm(>Xw**d3n0&V!j@w0KIb6FCC z+_r862AYj{^`cZx!PI&#EpgAiAwWk)j9hsuUCXos&Dy|YHm+`KBi;!aYvR-qT+7!i zaj{P}1k5oh_KN4~ zi;mR(%=*jnxci*vS=Rnn{BX=KjtR&;!S6{4cA1z1PeT2|`3JbVf8qr_2rkWg!8uXT z2(TtuxBeC;SzP|6?d>UWjrLFSGjhC0JYJ2(jHdVQLL%Xlv^}Nz+*BpoN@-TH{XW=1 z+p!8Dp?Fd@t}^o2cNeAFiWl!F(t0i~qDl+(<-H+sq#1HA!Y9dj$&wkuieo^fA=|Mp zM5Mw=wSMcgXs7q!=9Qh3>%^3bzgaKT&yv09=gd#EaIFg2o@{a3Dc+vac|=hH?q95_ z;ZB+yR7)zg8WmC>5E@j=ClfpnQBNvmarpWr{Y$aE&0uYDI^77<3@we|7`GPQaE6`Z zs8F5345e1I&w5{4I-MB5u=;_mCTVgSyV{IAdoBAwsSlH?PND?Au(0R4JS9jYF8fsi z9gRb{f^HWkCFsQf=m|kHD`b((bNbN$CgltNEL>;QRCnl`6A1FS0Egrm>e+yhf*JSb zi}9@&#p>AIG>w0g?Y5ml5#gw!s+&$s2`SeiLn-u=-RaSg>7cpRt{wMMj*I7x&m%ct0v# z7?Eyc^Jg?JgAMO-uh5wPn+U~tT7HZOMZs;!{6zolM;A&1LeqQ91qIX>QTC+Cg^2WG z(fWzy)L{Q~=7RJ%WgP)uD|aEm4B;&a%|HkWOxcRA4YlrPe?wV0$x^BmlYSEOq^t0474p#Pyp= zP%MH}wuM&KAna{QDfSmedI;{LWCknWo9b^0i;g2W@kzq9i;ltsi;gL!R_;TOUWw>f zT&q115R@khkCx0qs5;MiUsRrj9VED zFAFW(ROw8u-Sg5iJ0X>xzB1nF?E;JMrF{emhlV-INQwfjgqJI9+54mR(TW8u8i!iK zRIy+BYq=E*YPm-~>wHz*Dpk{AdZQr9HS#B=AfJOQIjZ(a@|K-W;e&jRnK{6S8}@Y9 zVdIJ(*3wFm@l;FyDwl#Gol*d_jmf8F<+=$rLI-nHr{s!)4w;YTe3fyVXGe|0eAUo@th0w-z|6JJ&j)xv zG(WGcprA}x+WTOo`*n1D_nxGV{tiQ$GNM-~CYB-<^eFQtGX=HIHDnQZIu znMXi%Li@;_M}Q_;-b$2dVou|YReGs>)!3ZI{HB3VBU^5cgoKzOGgo@$tj5Incur3C zm!SrwN?}8XS-(m+jE3Ahg{ixQmz<5?NilOuNIkaS0m+8m9y>fGV&IxeROYcywfkLI%o?q7_zS3EpOK>W(X&ubuuMy^Y>{F`Ha~ImVAOx? z>z@F)ufUD3wkn&c=10Nb^Y%dHvG$z1#fijf_9SKB?T{KJ#l+uM(~w3S7}NB-FkKf- z+!^Vxm+8XFmOnauMLPUu8*Iv07XS7MUpkX3&W{!+Jx z_`3z4J{TlCYcYCYF=e^A^tI0I%=D?-8U3)E>;F)7fT{oQR2^XI|DozHAZsPG;lKhl z{;fc49_7j*5$*Pi@l@i@aQ*JbMN{O7c*F0hvOojGwQyi=@1?kPw8eOLM3+}sbLZ)# zqHJdQSIGhwaLX%zt5;QooK%ZEgWMBoi$Z9qVVbv(Oku=fW7oIBN?X^Ttib3WrghFV zV1Jsz&tMT;h?wW(2o8N5X}u+mte7W*&(4r(&|-dQSqU`mwf}NKPpl zQ^U*wdh&I(~ z2oJ&kRP1gJSs~KSj1k45u{?6H_Bu?yOC}Hsatk5sP&YQ!@rp7Iww}#P>bFJL93i~BOH`AH=r?Jk+ ze^cl}%wPF-1QeN6&j&(nuLqj?oBAzkyd9y9`r^;x2b=7(Bp`CyXezIxzGPAdRroK$G;>DJJ)8zmwPluRq(XpB33UbgZe0 z2sYSGJCor`er07w**u0o{sHFyB|3ZHbs5*=9k-Vv$ARbf&f=&gqh80&&yb;s8Ve>W z{O}&xlSQgId$`lUe3L?9ul#Er^XkRuY!d z>*mF{)I%7i+e(#J4A8yn z>FfM=%JB`|?q@~NnA_x!_aydoGM(U)Qt+Uc%Et?g07d@Y+bdW5VeZR#d?|Y z#>@rOg7K}0k`ou4o(4KG%b)lApLRPSeM!P!{2;OmbC7VLr}pP}1@0d^oYoCruw$k1 zLEHq|aPWt@8!D2lPGlE7{VU{BFx73MhpvxFN+HJuYqgP}QCxphTJB zKzT3-v4R)~NgQIB2uTP+-jYR_dp~LPa%`Q=6jqw`H1w>_$mjmVm)!m@pATe6(>#jj zHFt_hX${CC!q?1$>BK-nnV8?POSaa`)wL)iBdNms$*$FcGh%yRh_^Qz>l?LC;uFY_ zV&`G^xF~~Uo={@vsk7j+lKx-`0`(q~cbrlo#81~HNR}`5u>dPf%vqLKkLlI+uD0{xl;gz<=y-F`phC5fVM5{{g!lgV(xy%F5v-m z>hgddwbTLYK-}!)b|Tsk0Y_<;7Fi?jU3ep1d3O|VYpbbR-j36AKnP3E|6k)zC zlP>DPTql0EVN)0KlC|&$_ebqUtv|x*Yy;G}$D9veKCga7QwTZ7zjc-4pJ9=`A2)`IF#TC*iN;j4 zn(mb;bv+y__W$c?`sa>c;?U+Xqx5dF{pH49jjldJSS>Cn$i!N!O-ULz>$zV{?QS&k z{w{sz7}<-=LDqG4oTORibIWo>z9mjKDI_sv`<(ZdgPR=Rrfs!k>N3qVBfnih0w_dq zYhR#z(0UtsgFpTKn?>P_Vu8RHfe3*J^Cxe1VR`lDg)?&0p-%?BnHRoP;1^KzBPxnc z(13PFxb{84JZ%)3CGQ_1ESdrBG4?*e7hv2FB*FqGjL{T+YztRolM_g<--a?I6Azj$ zgB?wz{#6?0p1?*1y)GlB%X~!FxtuB#ez68~plESuBgqa`ztek>aMCvu8;Z|$Id14?pFr}u4922}--J3d;2q?*@re z*g%(H3tBTK;CCg9l5L>qtWW;grOjjaT)e;Wj;jnWAv6boENPXGy|@A2FSoeefF*N> zG+89gV;@I{^|82D=Z=rb|FEb3_RK|EruZF9u-bc@JqHg|-}=lsSV14)Ud| z9HreKSlRe=?#5_&Eq7xa7b4?%4`VGd$;a->G0zzl;uQN86=+y*dFzeH3p_VZC=|#u z4b7L__9x9si1@iMe#T;{}kKI5SMnsjIG-4W~`9~XuZ6`Vrh$b|z9WOd?*IT%@M!Lv*aO2EG$mVa<0DDh}Ja5hd8#jK0a3X(;8 zDUV9cCi%wYNzB+Eg7ZFwWdG9s+U;`D88z0FBLPRz``ElKJh6;TN$BnfY-O$Oucjfl zR;}BuX~PWSNuc@uE&r;DhN5WD?B!5}Mk45Yt zjq;OO_{Wo@l{UQ@`0;Fg$I>dut-83ei)lCNb$sD=yovAO;bL8U$5ny#vo;vvvH!_x z$Ji`Fc%CGu;2T-|prz{bXYu`(HO(jy8`J)cGjDFn&O(ke{q`>luT#mxKm0_BDV!bm z9X|3edR}KA`ltF(W3bFmS!*3CXW7UNP!0)y9VQG(Y+_d}zifgPfOZ*w90x2r-^mWMdZ}vp`ArRcQS3Mmrrdhp|EY*^ zA#fg|Lt*`+tO!awV*P-y{auIrUk}4J4mpzNpmyC4jz7bCp(%`Ix=?^*=DzO z+l$eby!!KJh|fMkBQ@r{I@17kwLO;U->+vczmk?I;=I~^L%(OXx9hC?-2rpdj5}oM zP+Xv^9ik`Lj2KgI74;T_cDY7Kf;Uk)S3{A;_2)y8CvE_1s@eVTCjB+vmzHait^bcL z{(scVcc5t>1xp{9%bw-^&{Frb_4d{o1K)}C!Gwczf`i!jr%ADfGTZFe%L>m+h$AtL ztSLtMj1H9WjG^3(*IZxh-UA~Oeo5ynlA!0BB{SP3tcvIK@m!dbaU1=`v{ACaeM-gb zv^>qUd6U8vDo)zyJ@b^fPOt6(rNlqlCTEywTcPmgKSu;j^rs%eN*x*3vO#ztRPadw zAF3B1YZIN9yBX`M6LY@3R3Ok{&C9g+xQ>+nJt9~FI8s;Yjlt&U(T^^L2goz0dA53y z3P-7m=o8bNCJ`kGwB3K0ni5R&W%^LKY~HU)KX|xDhJWT+!yBmC|HahiR~Z`6|6ywW zm+fsb`!{dWSKY{A%Zb;#@^cfBX3EXDc(`(N7J`|4)>y&+*$W*?)POHNxkViQxT7tMLiBR;ey0u?f5g;Ayi* z{#&Ojg3TpvV5|_s4Jc1p@NB2c@8j9X6FO7KmMSkq< zfNgW2nXr)Se&+xY;F66X{F*ut@JG(#B zusy>8ModLQnq|lMiq)&x+ichPsc9sA8#C--naN2@mY3_PHR6@w*s8-_%BIyN zP6$T#-}N2K)~C{3&2_6$O{n>qq8Mwef`d!|32 z6B`FbULoQ2@T+I77}vgkey*uDNrU|-Jb&V;cB)UlmH1l(J%YLIIbDtS##H%NIAr>F z`xJ7sBLT%}Jieay(fM2Jve&a8PrvyaxT&9c(0`W1E+4xNL392h+P&YGxt6>;J<_|d zjQwQNTG_MI^bVXoYFlEq^ax0#<&kOY1HNaa_}^iT9bywzT{fnr5C0Mz=DRw<5S6;2 zlq52XA|RObBx)8*(nHMa*l0v^Mc48O%7c228V{9HaK9PHs*~AQJ%YV*NbolZNFA6@ z7v1?%2ShjyZ}#f6%VB-6}uI)|BgAz z8rIeCfClfZtqqRnNFWz_9gx|P(%|{t$bkySs!->w2auDt9=bEg&I1aNz>)|KSW!Y`(>ZmF&|8ssUPC7Vhs5miwsczDJKaY}w}Nb|?CB zodj@z3O_-fgjKir@EcvH-a?(7JCgrX&Fer6UGtI<`2Q60tmg`OL%p^y2G*p&f6)A1 z?2dOZwE}j!a&xj)0>URid&F#v%*Mw?sxmk6g4?g?zVhkiuC)a^TxWRoq7n0GY7=j- z=RlLrQ~&)9L_I=C-S4CWQI7`40IncCh&rT%M30om#y%ggP~PgIok66Ii$`yN$c6!@ P)*xjC4f!frvylGexPS=smTJxA7N<{qsN#sT_NePmARt-D4wu|k? zG+dj_6syHQ9*)jKNk~s{sY!<=Zd@?YsAy5C{I?~M<>g-V#a`_9;`jT0@4m0T_xTCP zq)2DSV~zj-I1{7r6aaV)vg?XBQT83_`1`l^^L7D&UXZ|J7Zj)Fv4GHYUK$HS%t^h( zqOelaujDFOf%cGz90L-XnwqRut87??Ac(M5Xf<2cbZZu?1u-JRdSRR#1u2}$7HG_F zzaS|P-Va1|qoSwKIhw$b7St6bDMAWZ%vRcz=f=)za66FLj$K?>Oq{{;r$~GSU7$!^ zSzaxa;)fTSuWM-a@-m7NT|Pr1O?k3r{7fd(tmap)lu)5exveNi%*e)$Ze(USLhLlF znJ(6lKJ7kDRXE4U(Uo!ZL>tz6VvgQNKA+;1Rj9J&Cz6nD^!Vv#fQOoLfzdeEbIV*@jl|_Ds1R0BS*sv zeO%xm=o*mZXIx9Ok3^&9HP*y+e zy7kqQ)FE7*?C$pNska z@nyz6l^^&C3t7;W$~*$ab8+8ok#~jt!CAeGk4usyg)UxT*^~00aM`_#QPnuKNnPwQ z<;k=s`sP03GQ-rLasAC!{U2IO3;NmFxoJHc{33V92K>8~!3?htR3j%Yd0^6pv6-W| z@}uYWrF;|dQa=_D!bj6vTUX+VGc`}2i^3cC&hPn>YUt3{H&&2Zl1`Vd`AdAw-}l~m zcH+Q?Qpqu9pCMyhk_NHTxG+}s^msI*L*({|6Lcz$09k%X;lW;O{GQ3n^_Xe zO4eOQM^$M_GL*!lPqq#l)^FtuZm-`j3xWkxbxlHo@?5^B-4>#jt zU3(vUY!LLhM|wPgXQ`Ni)rGKm{=}7)oJLoz@B@AT>WXI7)4i?^7 z0=4g)Eaa?jR6dCLGXDjA`_wXTt$vsZ6?y*+*PMjjvYJc!L^^V!X7oZMYJ1)BzvK5R eLeV}WZ@2?VNSGGRJb1?bb^wt;!gq$HRQ>}@`iW`) literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_cancel.png b/AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_cancel.png new file mode 100644 index 0000000000000000000000000000000000000000..a39adf821dd58a526ba1c728d7f427953537a8e5 GIT binary patch literal 718 zcmeAS@N?(olHy`uVBq!ia0vp^20$#s!3-n?Hl6taq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6|D&H331KH$oTQ&$4?OY`TzgFe<1Y#=g(h%{{or+fBpXb z_s?IT+@HUHfByRU>(_4}0aEer-@m_q|NQ>*`}Z%P)}KHHASOuu&)+}4e*FZ={QmP7 zsOrz3Cr_RL>0dv8{stQN2PgTDNr=_L+|NsA^Oi~F01LGb~7srr_TX&}1ELv(H$jpkMsYP$D(|T#=MV30O?3wgV~U7kn<*0Hy+TTaiMb&Xx~yvX5u=fXWJCnQG1H?jrKS*{sZ!grtd@IJAm z;Oi!hrNs_140GP8YoGt!>alIU-=3FQCPz3`*M8Ubx|g+UKf^EQdH7uBh)SD r+e#Ck&+7NT+^yetzx-7{12aSRp+{GnA6TydracBvS3j3^P6|6H_V+Po~-c6-^HC332`T>*ufEzkmGr@$<)zzkmP!|M&0Luirm^{QUj< z4^Zsy-+%x9{{8d!FHrjD&mVvO{`vFgH&E!`|Nl>(JOK)UKCw`Sa(gQ>TD( z_Z9C=Vqjp@@pN$vskn7#%I&fy0|8gX=C&1_O;PV}RZo7^^Y8!lsVp9g^`;#?o_CGM zxWLTD(ZsSeS!nLLyB2?y7i*l0&y6`6KJ}ut_;G`)+!kza%8tIeEP0$;V0PHIgq1tZ zE(EL3&N7|#{GMT3!pV041W8jM0GGd)Bo+88sJ&c9yL?A^6`0_ z91jIoCyt|*nvAEmy_~}AsiYtzlVVwTF7XwQ=F}8Erh^hUI8Qknooh{!5t*Ezevm=# k*SX#Qh4=6Nq|6H_V+Po~-c6-^HC332`T>*ufEzkmGr@$<)zzkmP!|M&0Luirm^{QUj< z4^Zsy-+%x9{{8d!FHrjD&mVvO{`vFgH&E!`|Nl>(JOK)UFMb|fBrmm>J(7! z4&R(v3=E7qo-U3d6}Rq8xn0&|AmFOl+_r+VDeC>L>dCKq{{6o`mBnMR-n65~^RDq2 z7ns>Nnpl=53(Y-u*W$18VvTe0xiLq>r(U!cKW=c9+k)*)+0j>*C699p%ntjOuyUu_ zg<$pBS*Ej|-!p8h+$4KVfv@<;ovLp!*Afy=Pt0NOG@kTa=i`l>X*W-;N;KK@)FW;4 zOye(;`5ba)ZQB-KB3XTTrtvYWzrE%?+I*R_l$MFgzh8e#vfWyN?R4+M`-Q@LO&+CI z81^L}xlw-pkaYHC^S=zqJc|nV9HL8 kI=B13@c!MOln*czE;wg6Va8S_V6-xLy85}Sb4q9e0KGst2><{9 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_del.png b/AvocadoEdition/plugin/editor/smarteditor2/img/photoQuickPopup/btn_del.png new file mode 100644 index 0000000000000000000000000000000000000000..9bbf5957e42acad8653dccc3c6927cbd3a054dec GIT binary patch literal 157 zcmeAS@N?(olHy`uVBq!ia0vp^d>}RlGmu=zwB8p;NtU=qlmzFem6RtIr7}3CX0{{R3S@g5*0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyjZjQfMf>~v!^6YJ$H&IT#>&dd$jHdV z#KghJIG&d$!bxVYir;mOI#rlzLa+S+9>hyuA4M`1$$y_V)IUj*jN$=JE0I^78Wf`uhC*{P*|w z_4W1r{r&Uv^Yrxe{{H>|003B;N3s9_0Ru@yK~#9!tdD7Tf-n$8N2$A3yYEFTkVNSF z|39y0Wm5QLxQEGvH_7Ed^6MvseL>HM-xSI>TF4{=%|=Ig+Yx0a{P2B;%@T%cphy1>l>&SrK?Vx10 z{u`#%(E-@SG+#P|o3jRgshCq%<^zCL?*F12 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/img/text_tool_set2.png b/AvocadoEdition/plugin/editor/smarteditor2/img/text_tool_set2.png new file mode 100644 index 0000000000000000000000000000000000000000..889a3334f9338350a33c0121978f83b833f55a06 GIT binary patch literal 7271 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"); + }catch(e){ + elIFrame = document.createElement("IFRAME"); + elIFrame.setAttribute("frameborder", "0"); + elIFrame.setAttribute("scrolling", "no"); + } + + elIFrame.style.width = "1px"; + elIFrame.style.height = "1px"; + elPlaceHolder.parentNode.insertBefore(elIFrame, elPlaceHolder.nextSibling); + + attachEvent(elIFrame, "load", function(){ + fCreator = elIFrame.contentWindow[fCreator] || elIFrame.contentWindow.createSEditor2; + +// top.document.title = ((new Date())-window.STime); +// window.STime = new Date(); + + try{ + + nEditorWidth = elIFrame.contentWindow.document.body.scrollWidth || "500px"; + nEditorHeight = elIFrame.contentWindow.document.body.scrollHeight + 12; + elIFrame.style.width = "100%"; + elIFrame.style.height = nEditorHeight+ "px"; + elIFrame.contentWindow.document.body.style.margin = "0"; + }catch(e){ + nhn.husky.EZCreator.hideBlocker(true); + elIFrame.style.border = "5px solid red"; + elIFrame.style.width = "500px"; + elIFrame.style.height = "500px"; + alert("Failed to access "+sSkinURI); + return; + } + + var oApp = fCreator(elPlaceHolder, htParams); // oEditor + + + oApp.elPlaceHolder = elPlaceHolder; + + oAppRef[oAppRef.length] = oApp; + if(!oAppRef.getById) oAppRef.getById = {}; + + if(elPlaceHolder.id) oAppRef.getById[elPlaceHolder.id] = oApp; + + oApp.run({fnOnAppReady:fOnAppLoad}); + +// top.document.title += ", "+((new Date())-window.STime); + nhn.husky.EZCreator.hideBlocker(); + }); +// window.STime = new Date(); + elIFrame.src = sSkinURI; + this.elIFrame = elIFrame; + }; + + this.showBlocker = function(){ + if(this.nBlockerCount<1){ + var elBlocker = document.createElement("DIV"); + elBlocker.style.position = "absolute"; + elBlocker.style.top = 0; + elBlocker.style.left = 0; + elBlocker.style.backgroundColor = "#FFFFFF"; + elBlocker.style.width = "100%"; + + document.body.appendChild(elBlocker); + + nhn.husky.EZCreator.elBlocker = elBlocker; + } + + nhn.husky.EZCreator.elBlocker.style.height = Math.max(document.body.scrollHeight, document.body.clientHeight)+"px"; + + this.nBlockerCount++; + }; + + this.hideBlocker = function(bForce){ + if(!bForce){ + if(--this.nBlockerCount > 0) return; + } + + this.nBlockerCount = 0; + + if(nhn.husky.EZCreator.elBlocker) nhn.husky.EZCreator.elBlocker.style.display = "none"; + } +})(); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_General.js b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_General.js new file mode 100644 index 0000000..ea8b29a --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_General.js @@ -0,0 +1,52 @@ +/* + * Smart Editor 2 Configuration : This setting must be changed by service + */ +window.nhn = window.nhn || {}; +nhn.husky = nhn.husky || {}; +nhn.husky.SE2M_Configuration = nhn.husky.SE2M_Configuration || {}; + +nhn.husky.SE2M_Configuration.Quote = { + sImageBaseURL : 'http://static.se2.naver.com/static/img' +}; + +nhn.husky.SE2M_Configuration.CustomObject = { + sVersion : 1, + sClassName : '__se_object', + sValueName : 'jsonvalue', + sTagIdPrefix : 'se_object_', + sTailComment : '', + sBlankTemplateURL : nhn.husky.SE2M_Configuration.LinkageDomain.sCommonStatic + '/static/db_attach/iframe_template_for_se1_obj.html', + sAttributeOfEmpty : 's_isempty="true"', + sAttributeOfOldDB : 's_olddb="true"', + sBlock : '

    ', + sBlockTemplate : '', + sHighlight : '
    ', + sHighlightTemplate : '', + sHtmlTemplateStartTag : '', + sHtmlTemplateEndTag : '', + sHtmlFilterTag : '{=sType}_{=sSubType}_{=nSeq}', + sTplHtmlFilterTag : '', + sImgComServerPath : nhn.husky.SE2M_Configuration.LinkageDomain.sCommonStatic + '/static/img/reviewitem', + nMaxWidth : 548 +}; + +nhn.husky.SE2M_Configuration.SE2M_ReEditAction = { + bUsed : true, + nSecDisplayDulationReEditMsg : 3, + aReEditGuideMsg : [ + '이미지 파일은 1회 클릭 시 크기 조절, 더블클릭 시 재편집이 가능합니다.', + '첨부한 파일을 더블클릭 시 재편집이 가능합니다.', + '첨부한 글양식 테이블을 드래그시 테이블 재편집이 가능합니다.', + '첨부한 표를 드래그 시 표 재편집이 가능합니다.' + ] +}; + +nhn.husky.SE2M_Configuration.SE2M_ColorPalette = { + bUseRecentColor : false +}; + +nhn.husky.SE2M_Configuration.QuickEditor = { + common : { + bUseConfig : false + } +}; \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_Service.js b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_Service.js new file mode 100644 index 0000000..c42a43b --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2B_Configuration_Service.js @@ -0,0 +1,71 @@ +/* + * Smart Editor 2 Configuration : This setting must be changed by service + */ +window.nhn = window.nhn || {}; +nhn.husky = nhn.husky || {}; +nhn.husky.SE2M_Configuration = nhn.husky.SE2M_Configuration || {}; + +/** + * 스마트에디터2에서 접근하는 JS, IMG 디렉토리 + */ +nhn.husky.SE2M_Configuration.Editor = { + sJsBaseURL : './js_src', + sImageBaseURL : './img/' +}; + +/** + * JS LazyLoad를 위한 경로 + */ +nhn.husky.SE2M_Configuration.LazyLoad = { + sJsBaseURI : "js_lazyload" +}; + +/** + * CSS LazyLoad를 위한 경로 + */ +nhn.husky.SE2M_Configuration.SE2B_CSSLoader = { + sCSSBaseURI : "css" +}; + +/** + * 편집영역 설정 + */ +nhn.husky.SE2M_Configuration.SE_EditingAreaManager = { + sCSSBaseURI : "css", + sBlankPageURL : "smart_editor2_inputarea.html", + sBlankPageURL_EmulateIE7 : "smart_editor2_inputarea_ie8.html", + aAddtionalEmulateIE7 : [] // IE8 default 사용, IE9 ~ 선택적 사용 +}; + +/** + * 스마트에디터2에서 사용하는 도메인 정보 + * http://wiki.nhncorp.com/pages/viewpage.action?pageId=74253685 + */ +nhn.husky.SE2M_Configuration.LinkageDomain = { + sCommonAPI : 'http://api.se2.naver.com', + sCommonStatic : 'http://static.se2.naver.com', + sCommonImage : 'http://images.se2.naver.com' +}; + + +/** + * [웹접근성] + * 단축키 ALT+, ALT+. 을 이용하여 스마트에디터 영역의 이전/이후 요소로 이동할 수 있다. + * sBeforeElementId : 스마트에디터 영역 이전 요소의 id + * sNextElementId : 스마트에디터 영역 이후 요소의 id + * + * 스마트에디터 영역 이외의 제목 영역 (예:스마트에디터가 적용된 블로그 쓰기 페이지에서의 제목 영역) 에 해당하는 엘리먼트에서 Tab키를 누르면 에디팅 영역으로 포커스를 이동시킬 수 있다. + * sTitleElementId : 제목에 해당하는 input 요소의 id. + */ +nhn.husky.SE2M_Configuration.SE2M_Accessibility = { + sBeforeElementId : '', + sNextElementId : '', + sTitleElementId : '' +}; + +/** + * 링크 기능 옵션 + */ +nhn.husky.SE2M_Configuration.SE2M_Hyperlink = { + bAutolink : true // 자동링크기능 사용여부(기본값:true) +}; \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/js/SE2BasicCreator.js b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2BasicCreator.js new file mode 100644 index 0000000..235f95c --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2BasicCreator.js @@ -0,0 +1,95 @@ +function createSEditor2(elIRField, htParams, elSeAppContainer){ + if(!window.$Jindo){ + parent.document.body.innerHTML="진도 프레임웍이 필요합니다.
    \n
    http://dev.naver.com/projects/jindo/download에서 Jindo 1.5.3 버전의 jindo.min.js를 다운로드 받아 /js 폴더에 복사 해 주세요.\n(아직 Jindo 2 는 지원하지 않습니다.)"; + return; + } + + var elAppContainer = (elSeAppContainer || jindo.$("smart_editor2")); + var elEditingArea = jindo.$$.getSingle("DIV.husky_seditor_editing_area_container", elAppContainer); + var oWYSIWYGIFrame = jindo.$$.getSingle("IFRAME.se2_input_wysiwyg", elEditingArea); + var oIRTextarea = elIRField?elIRField:jindo.$$.getSingle("TEXTAREA.blind", elEditingArea); + var oHTMLSrc = jindo.$$.getSingle("TEXTAREA.se2_input_htmlsrc", elEditingArea); + var oTextArea = jindo.$$.getSingle("TEXTAREA.se2_input_text", elEditingArea); + + if(!htParams){ + htParams = {}; + htParams.fOnBeforeUnload = null; + } + htParams.elAppContainer = elAppContainer; // 에디터 UI 최상위 element 셋팅 + htParams.oNavigator = jindo.$Agent().navigator(); // navigator 객체 셋팅 + + var oEditor = new nhn.husky.HuskyCore(htParams); + oEditor.registerPlugin(new nhn.husky.CorePlugin(htParams?htParams.fOnAppLoad:null)); + oEditor.registerPlugin(new nhn.husky.StringConverterManager()); + + var htDimension = { + nMinHeight:205, + nMinWidth:parseInt(elIRField.style.minWidth, 10)||570, + nHeight:elIRField.style.height||elIRField.offsetHeight, + nWidth:elIRField.style.width||elIRField.offsetWidth + }; + + var htConversionMode = { + bUseVerticalResizer : htParams.bUseVerticalResizer, + bUseModeChanger : htParams.bUseModeChanger + }; + + var aAdditionalFontList = htParams.aAdditionalFontList; + + oEditor.registerPlugin(new nhn.husky.SE_EditingAreaManager("WYSIWYG", oIRTextarea, htDimension, htParams.fOnBeforeUnload, elAppContainer)); + oEditor.registerPlugin(new nhn.husky.SE_EditingArea_WYSIWYG(oWYSIWYGIFrame)); // Tab Editor 모드 + oEditor.registerPlugin(new nhn.husky.SE_EditingArea_HTMLSrc(oHTMLSrc)); // Tab HTML 모드 + oEditor.registerPlugin(new nhn.husky.SE_EditingArea_TEXT(oTextArea)); // Tab Text 모드 + oEditor.registerPlugin(new nhn.husky.SE2M_EditingModeChanger(elAppContainer, htConversionMode)); // 모드간 변경(Editor, HTML, Text) + oEditor.registerPlugin(new nhn.husky.SE_PasteHandler()); // WYSIWYG Paste Handler + + oEditor.registerPlugin(new nhn.husky.HuskyRangeManager(oWYSIWYGIFrame)); + oEditor.registerPlugin(new nhn.husky.Utils()); + oEditor.registerPlugin(new nhn.husky.SE2M_UtilPlugin()); + oEditor.registerPlugin(new nhn.husky.SE_WYSIWYGStyler()); + oEditor.registerPlugin(new nhn.husky.SE2M_Toolbar(elAppContainer)); + + oEditor.registerPlugin(new nhn.husky.Hotkey()); // 단축키 + oEditor.registerPlugin(new nhn.husky.SE_EditingAreaVerticalResizer(elAppContainer, htConversionMode)); // 편집영역 리사이즈 + oEditor.registerPlugin(new nhn.husky.DialogLayerManager()); + oEditor.registerPlugin(new nhn.husky.ActiveLayerManager()); + oEditor.registerPlugin(new nhn.husky.SE_WYSIWYGStyleGetter()); // 커서 위치 스타일 정보 가져오기 + + oEditor.registerPlugin(new nhn.husky.SE_WYSIWYGEnterKey("P")); // 엔터 시 처리, 현재는 P로 처리 + + oEditor.registerPlugin(new nhn.husky.SE2M_ColorPalette(elAppContainer)); // 색상 팔레트 + oEditor.registerPlugin(new nhn.husky.SE2M_FontColor(elAppContainer)); // 글자색 + oEditor.registerPlugin(new nhn.husky.SE2M_BGColor(elAppContainer)); // 글자배경색 + oEditor.registerPlugin(new nhn.husky.SE2M_FontNameWithLayerUI(elAppContainer, aAdditionalFontList)); // 글꼴종류 + oEditor.registerPlugin(new nhn.husky.SE2M_FontSizeWithLayerUI(elAppContainer)); // 글꼴크기 + + oEditor.registerPlugin(new nhn.husky.SE2M_LineStyler()); + oEditor.registerPlugin(new nhn.husky.SE2M_ExecCommand(oWYSIWYGIFrame)); + oEditor.registerPlugin(new nhn.husky.SE2M_LineHeightWithLayerUI(elAppContainer)); // 줄간격 + + oEditor.registerPlugin(new nhn.husky.SE2M_Quote(elAppContainer)); // 인용구 + oEditor.registerPlugin(new nhn.husky.SE2M_Hyperlink(elAppContainer)); // 링크 + oEditor.registerPlugin(new nhn.husky.SE2M_SCharacter(elAppContainer)); // 특수문자 + oEditor.registerPlugin(new nhn.husky.SE2M_FindReplacePlugin(elAppContainer)); // 찾기/바꾸기 + oEditor.registerPlugin(new nhn.husky.SE2M_TableCreator(elAppContainer)); // 테이블 생성 + oEditor.registerPlugin(new nhn.husky.SE2M_TableEditor(elAppContainer)); // 테이블 편집 + oEditor.registerPlugin(new nhn.husky.SE2M_TableBlockStyler(elAppContainer)); // 테이블 스타일 + if(nhn.husky.SE2M_AttachQuickPhoto){ + oEditor.registerPlugin(new nhn.husky.SE2M_AttachQuickPhoto(elAppContainer)); // 사진 + } + + oEditor.registerPlugin(new nhn.husky.MessageManager(oMessageMap)); + oEditor.registerPlugin(new nhn.husky.SE2M_QuickEditor_Common(elAppContainer)); // 퀵에디터 공통(표, 이미지) + + oEditor.registerPlugin(new nhn.husky.SE2B_CSSLoader()); // CSS lazy load + if(window.frameElement){ + oEditor.registerPlugin(new nhn.husky.SE_OuterIFrameControl(elAppContainer, 100)); + } + + oEditor.registerPlugin(new nhn.husky.SE_ToolbarToggler(elAppContainer, htParams.bUseToolbar)); + oEditor.registerPlugin(new nhn.husky.SE2M_Accessibility(elAppContainer)); // 에디터내의 웹접근성 관련 기능모음 플러그인 + + oEditor.registerPlugin(new nhn.husky.SE2B_Customize_ToolBar(elAppContainer)); // 2.3 버젼에 있는 툴바 이용 + + return oEditor; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/js/SE2M_Configuration.js b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2M_Configuration.js new file mode 100644 index 0000000..8c84f21 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/js/SE2M_Configuration.js @@ -0,0 +1,149 @@ +/* + * Smart Editor 2 Configuration : This setting must be changed by service + */ +window.nhn = window.nhn || {}; +nhn.husky = nhn.husky || {}; +nhn.husky.SE2M_Configuration = nhn.husky.SE2M_Configuration || {}; + +/** + * CSS LazyLoad를 위한 경로 + */ +nhn.husky.SE2M_Configuration.SE2B_CSSLoader = { + sCSSBaseURI : "css" +}; + +/** + * 편집영역 설정 + */ +nhn.husky.SE2M_Configuration.SE_EditingAreaManager = { + sCSSBaseURI : "css", // smart_editor2_inputarea.html 파일의 상대경로 + sBlankPageURL : "smart_editor2_inputarea.html", + sBlankPageURL_EmulateIE7 : "smart_editor2_inputarea_ie8.html", + aAddtionalEmulateIE7 : [] // IE8 default 사용, IE9 ~ 선택적 사용 +}; + +/** + * [웹접근성] + * 단축키 ALT+, ALT+. 을 이용하여 스마트에디터 영역의 이전/이후 요소로 이동할 수 있다. + * sBeforeElementId : 스마트에디터 영역 이전 요소의 id + * sNextElementId : 스마트에디터 영역 이후 요소의 id + * + * 스마트에디터 영역 이외의 제목 영역 (예:스마트에디터가 적용된 블로그 쓰기 페이지에서의 제목 영역) 에 해당하는 엘리먼트에서 Tab키를 누르면 에디팅 영역으로 포커스를 이동시킬 수 있다. + * sTitleElementId : 제목에 해당하는 input 요소의 id. + */ +nhn.husky.SE2M_Configuration.SE2M_Accessibility = { + ed_nonce : (typeof parent.ed_nonce !='undefined') ? parent.ed_nonce : '', + sBeforeElementId : '', + sNextElementId : '', + sTitleElementId : '' +}; + +/** + * 링크 기능 옵션 + */ +nhn.husky.SE2M_Configuration.SE2M_Hyperlink = { + bAutolink : true // 자동링크기능 사용여부(기본값:true) +}; + +nhn.husky.SE2M_Configuration.Quote = { + sImageBaseURL : 'http://static.se2.naver.com/static/img' +}; +nhn.husky.SE2M_Configuration.SE2M_ColorPalette = { + bAddRecentColorFromDefault : false +}; + +nhn.husky.SE2B_Customize_ToolBar = jindo.$Class(/** @lends nhn.husky.SE2B_Customize_ToolBar */{ + name : "SE2B_Customize_ToolBar", + /** + * @constructs + * @param {Object} oAppContainer 에디터를 구성하는 컨테이너 + */ + $init : function(oAppContainer) { + this._assignHTMLElements(oAppContainer); + }, + $BEFORE_MSG_APP_READY : function(){ + this._addEventMoreButton(); + }, + + /** + * @private + * @description DOM엘리먼트를 수집하는 메소드 + * @param {Object} oAppContainer 툴바 포함 에디터를 감싸고 있는 div 엘리먼트 + */ + _assignHTMLElements : function(oAppContainer) { + this.oAppContainer = oAppContainer; + this.elTextToolBarArea = jindo.$$.getSingle("div.se2_tool"); + this.elTextMoreButton = jindo.$$.getSingle("button.se2_text_tool_more", this.elTextToolBarArea); + this.elTextMoreButtonParent = this.elTextMoreButton.parentNode; + this.welTextMoreButtonParent = jindo.$Element(this.elTextMoreButtonParent); + this.elMoreLayer = jindo.$$.getSingle("div.se2_sub_text_tool"); + }, + + _addEventMoreButton : function (){ + this.oApp.registerBrowserEvent(this.elTextMoreButton, "click", "EVENT_CLICK_EXPAND_VIEW"); + this.oApp.registerBrowserEvent(this.elMoreLayer, "click", "EVENT_CLICK_EXPAND_VIEW"); + }, + + $ON_EVENT_CLICK_EXPAND_VIEW : function(weEvent){ + this.oApp.exec("TOGGLE_EXPAND_VIEW", [this.elTextMoreButton]); + weEvent.stop(); + }, + + $ON_TOGGLE_EXPAND_VIEW : function(){ + if(!this.welTextMoreButtonParent.hasClass("active")){ + this.oApp.exec("SHOW_EXPAND_VIEW"); + } else { + this.oApp.exec("HIDE_EXPAND_VIEW"); + } + }, + + $ON_CHANGE_EDITING_MODE : function(sMode){ + if(sMode != "WYSIWYG"){ + this.elTextMoreButton.disabled =true; + this.welTextMoreButtonParent.removeClass("active"); + this.oApp.exec("HIDE_EXPAND_VIEW"); + }else{ + this.elTextMoreButton.disabled =false; + } + }, + + $AFTER_SHOW_ACTIVE_LAYER : function(){ + this.oApp.exec("HIDE_EXPAND_VIEW"); + }, + + $AFTER_SHOW_DIALOG_LAYER : function(){ + this.oApp.exec("HIDE_EXPAND_VIEW"); + }, + + $ON_SHOW_EXPAND_VIEW : function(){ + this.welTextMoreButtonParent.addClass("active"); + this.elMoreLayer.style.display = "block"; + }, + + $ON_HIDE_EXPAND_VIEW : function(){ + this.welTextMoreButtonParent.removeClass("active"); + this.elMoreLayer.style.display = "none"; + }, + + /** + * CHANGE_EDITING_MODE모드 이후에 호출되어야 함. + * WYSIWYG 모드가 활성화되기 전에 호출이 되면 APPLY_FONTCOLOR에서 에러 발생. + */ + $ON_RESET_TOOLBAR : function(){ + if(this.oApp.getEditingMode() !== "WYSIWYG"){ + return; + } + //스펠체크 닫기 + this.oApp.exec("END_SPELLCHECK"); + //열린 팝업을 닫기 위해서 + this.oApp.exec("DISABLE_ALL_UI"); + this.oApp.exec("ENABLE_ALL_UI"); + //글자색과 글자 배경색을 제외한 세팅 + this.oApp.exec("RESET_STYLE_STATUS"); + this.oApp.exec("CHECK_STYLE_CHANGE"); + //최근 사용한 글자색 셋팅. + this.oApp.exec("APPLY_FONTCOLOR", ["#000000"]); + //더보기 영역 닫기. + this.oApp.exec("HIDE_EXPAND_VIEW"); + } +}); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/js/jindo.min.js b/AvocadoEdition/plugin/editor/smarteditor2/js/jindo.min.js new file mode 100644 index 0000000..538b503 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/js/jindo.min.js @@ -0,0 +1 @@ +if(typeof window!="undefined"&&typeof window.nhn=="undefined"){window.nhn={};}if(typeof window!="undefined"){if(typeof window.jindo=="undefined"){window.jindo={};}}else{if(!jindo){jindo={};}}jindo.$Jindo=function(){var cl=arguments.callee;var cc=cl._cached;if(cc){return cc;}if(!(this instanceof cl)){return new cl();}if(!cc){cl._cached=this;}this.version="1.5.2";};jindo.$=function(sID){var ret=[],arg=arguments,nArgLeng=arg.length,lastArgument=arg[nArgLeng-1],doc=document,el=null;var reg=/^<([a-z]+|h[1-5])>$/i;var reg2=/^<([a-z]+|h[1-5])(\s+[^>]+)?>/i;if(nArgLeng>1&&typeof lastArgument!="string"&&lastArgument.body){arg=Array.prototype.slice.apply(arg,[0,nArgLeng-1]);doc=lastArgument;}for(var i=0;i-1){if(reg.test(el)){el=doc.createElement(RegExp.$1);}else{if(reg2.test(el)){var p={thead:"table",tbody:"table",tr:"tbody",td:"tr",dt:"dl",dd:"dl",li:"ul",legend:"fieldset",option:"select"};var tag=RegExp.$1.toLowerCase();var ele=jindo._createEle(p[tag],el,doc);for(var i=0,leng=ele.length;i1?ret:(ret[0]||null);};jindo._createEle=function(sParentTag,sHTML,oDoc,bWantParent){var sId="R"+new Date().getTime()+parseInt(Math.random()*100000,10);var oDummy=oDoc.createElement("div");switch(sParentTag){case"select":case"table":case"dl":case"ul":case"fieldset":oDummy.innerHTML="<"+sParentTag+' class="'+sId+'">'+sHTML+"";break;case"thead":case"tbody":case"col":oDummy.innerHTML="<"+sParentTag+' class="'+sId+'">'+sHTML+"
    ";break;case"tr":oDummy.innerHTML=''+sHTML+"
    ";break;default:oDummy.innerHTML='
    '+sHTML+"
    ";break;}var oFound;for(oFound=oDummy.firstChild;oFound;oFound=oFound.firstChild){if(oFound.className==sId){break;}}return bWantParent?oFound:oFound.childNodes;};jindo.$Class=function(oDef){function typeClass(){var t=this;var a=[];var superFunc=function(m,superClass,func){if(m!="constructor"&&func.toString().indexOf("$super")>-1){var funcArg=func.toString().replace(/function\s*\(([^\)]*)[\w\W]*/g,"$1").split(",");var funcStr=func.toString().replace(/function[^{]*{/,"").replace(/(\w|\.?)(this\.\$super|this)/g,function(m,m2,m3){if(!m2){return m3+".$super";}return m;});funcStr=funcStr.substr(0,funcStr.length-1);func=superClass[m]=eval("false||function("+funcArg.join(",")+"){"+funcStr+"}");}return function(){var f=this.$this[m];var t=this.$this;var r=(t[m]=func).apply(t,arguments);t[m]=f;return r;};};while(typeof t._$superClass!="undefined"){t.$super=new Object;t.$super.$this=this;for(var x in t._$superClass.prototype){if(t._$superClass.prototype.hasOwnProperty(x)){if(typeof this[x]=="undefined"&&x!="$init"){this[x]=t._$superClass.prototype[x];}if(x!="constructor"&&x!="_$superClass"&&typeof t._$superClass.prototype[x]=="function"){t.$super[x]=superFunc(x,t._$superClass,t._$superClass.prototype[x]);}else{t.$super[x]=t._$superClass.prototype[x];}}}if(typeof t.$super.$init=="function"){a[a.length]=t;}t=t.$super;}for(var i=a.length-1;i>-1;i--){a[i].$super.$init.apply(a[i].$super,arguments);}if(typeof this.$init=="function"){this.$init.apply(this,arguments);}}if(typeof oDef.$static!="undefined"){var i=0,x;for(x in oDef){if(oDef.hasOwnProperty(x)){x=="$static"||i++;}}for(x in oDef.$static){if(oDef.$static.hasOwnProperty(x)){typeClass[x]=oDef.$static[x];}}if(!i){return oDef.$static;}delete oDef.$static;}typeClass.prototype=oDef;typeClass.prototype.constructor=typeClass;typeClass.extend=jindo.$Class.extend;return typeClass;};jindo.$Class.extend=function(superClass){if(typeof superClass=="undefined"||superClass===null||!superClass.extend){throw new Error("extend시 슈퍼 클래스는 Class여야 합니다.");}this.prototype._$superClass=superClass;for(var x in superClass){if(superClass.hasOwnProperty(x)){if(x=="prototype"){continue;}this[x]=superClass[x];}}return this;};jindo.$$=jindo.cssquery=(function(){var sVersion="3.0";var debugOption={repeat:1};var UID=1;var cost=0;var validUID={};var bSupportByClassName=document.getElementsByClassName?true:false;var safeHTML=false;var getUID4HTML=function(oEl){var nUID=safeHTML?(oEl._cssquery_UID&&oEl._cssquery_UID[0]):oEl._cssquery_UID;if(nUID&&validUID[nUID]==oEl){return nUID;}nUID=UID++;oEl._cssquery_UID=safeHTML?[nUID]:nUID;validUID[nUID]=oEl;return nUID;};var getUID4XML=function(oEl){var oAttr=oEl.getAttribute("_cssquery_UID");var nUID=safeHTML?(oAttr&&oAttr[0]):oAttr;if(!nUID){nUID=UID++;oEl.setAttribute("_cssquery_UID",safeHTML?[nUID]:nUID);}return nUID;};var getUID=getUID4HTML;var uniqid=function(sPrefix){return(sPrefix||"")+new Date().getTime()+parseInt(Math.random()*100000000,10);};function getElementsByClass(searchClass,node,tag){var classElements=new Array();if(node==null){node=document;}if(tag==null){tag="*";}var els=node.getElementsByTagName(tag);var elsLen=els.length;var pattern=new RegExp("(^|\\s)"+searchClass+"(\\s|$)");for(i=0,j=0;i -1)';case"^=":return"("+sVar+" && "+sVar+".indexOf("+sVal+") == 0)";case"$=":return"("+sVar+" && "+sVar+".substr("+sVar+".length - "+oExpr.val.length+") == "+sVal+")";case"*=":return"("+sVar+" && "+sVar+".indexOf("+sVal+") > -1)";case"!=":return"("+sVar+" != "+sVal+")";case"=":return"("+sVar+" == "+sVal+")";}return"("+sVar+")";};var getNodeIndex=function(oEl){var nUID=getUID(oEl);var nIndex=oNodeIndexes[nUID]||0;if(nIndex==0){for(var oSib=(oEl.parentNode||oEl._IE5_parentNode).firstChild;oSib;oSib=oSib.nextSibling){if(oSib.nodeType!=1){continue;}nIndex++;setNodeIndex(oSib,nIndex);}nIndex=oNodeIndexes[nUID];}return nIndex;};var oNodeIndexes={};var setNodeIndex=function(oEl,nIndex){var nUID=getUID(oEl);oNodeIndexes[nUID]=nIndex;};var unsetNodeIndexes=function(){setTimeout(function(){oNodeIndexes={};},0);};var oPseudoes_dontShrink={contains:function(oEl,sOption){return(oEl.innerText||oEl.textContent||"").indexOf(sOption)>-1;},"last-child":function(oEl,sOption){for(oEl=oEl.nextSibling;oEl;oEl=oEl.nextSibling){if(oEl.nodeType==1){return false;}}return true;},"first-child":function(oEl,sOption){for(oEl=oEl.previousSibling;oEl;oEl=oEl.previousSibling){if(oEl.nodeType==1){return false;}}return true;},"only-child":function(oEl,sOption){var nChild=0;for(var oChild=(oEl.parentNode||oEl._IE5_parentNode).firstChild;oChild;oChild=oChild.nextSibling){if(oChild.nodeType==1){nChild++;}if(nChild>1){return false;}}return nChild?true:false;},empty:function(oEl,_){return oEl.firstChild?false:true;},"nth-child":function(oEl,nMul,nAdd){var nIndex=getNodeIndex(oEl);return nIndex%nMul==nAdd;},"nth-last-child":function(oEl,nMul,nAdd){var oLast=(oEl.parentNode||oEl._IE5_parentNode).lastChild;for(;oLast;oLast=oLast.previousSibling){if(oLast.nodeType==1){break;}}var nTotal=getNodeIndex(oLast);var nIndex=getNodeIndex(oEl);var nLastIndex=nTotal-nIndex+1;return nLastIndex%nMul==nAdd;},checked:function(oEl){return !!oEl.checked;},selected:function(oEl){return !!oEl.selected;},enabled:function(oEl){return !oEl.disabled;},disabled:function(oEl){return !!oEl.disabled;}};var getExpression=function(sBody){var oRet={defines:"",returns:"true"};var sBody=restoreKeys(sBody,true);var aExprs=[];var aDefineCode=[],aReturnCode=[];var sId,sTagName;var sBody=sBody.replace(/:([\w-]+)(\(([^)]*)\))?/g,function(_1,sType,_2,sOption){switch(sType){case"not":var oInner=getExpression(sOption);var sFuncDefines=oInner.defines;var sFuncReturns=oInner.returnsID+oInner.returnsTAG+oInner.returns;aReturnCode.push("!(function() { "+sFuncDefines+" return "+sFuncReturns+" })()");break;case"nth-child":case"nth-last-child":sOption=restoreString(sOption);if(sOption=="even"){sOption="2n";}else{if(sOption=="odd"){sOption="2n+1";}}var nMul,nAdd;var matchstr=sOption.match(/([0-9]*)n([+-][0-9]+)*/);if(matchstr){nMul=matchstr[1]||1;nAdd=matchstr[2]||0;}else{nMul=Infinity;nAdd=parseInt(sOption,10);}aReturnCode.push("oPseudoes_dontShrink["+wrapQuot(sType)+"](oEl, "+nMul+", "+nAdd+")");break;case"first-of-type":case"last-of-type":sType=(sType=="first-of-type"?"nth-of-type":"nth-last-of-type");sOption=1;case"nth-of-type":case"nth-last-of-type":sOption=restoreString(sOption);if(sOption=="even"){sOption="2n";}else{if(sOption=="odd"){sOption="2n+1";}}var nMul,nAdd;if(/([0-9]*)n([+-][0-9]+)*/.test(sOption)){nMul=parseInt(RegExp.$1,10)||1;nAdd=parseInt(RegExp.$2,20)||0;}else{nMul=Infinity;nAdd=parseInt(sOption,10);}oRet.nth=[nMul,nAdd,sType];break;default:sOption=sOption?restoreString(sOption):"";aReturnCode.push("oPseudoes_dontShrink["+wrapQuot(sType)+"](oEl, "+wrapQuot(sOption)+")");break;}return"";});var sBody=sBody.replace(/\[(@?[\w-]+)(([!^~$*]?=)([^\]]*))?\]/g,function(_1,sKey,_2,sOp,sVal){sKey=restoreString(sKey);sVal=restoreString(sVal);if(sKey=="checked"||sKey=="disabled"||sKey=="enabled"||sKey=="readonly"||sKey=="selected"){if(!sVal){sOp="=";sVal="true";}}aExprs.push({key:sKey,op:sOp,val:sVal});return"";});var sClassName=null;var sBody=sBody.replace(/\.([\w-]+)/g,function(_,sClass){aExprs.push({key:"class",op:"~=",val:sClass});if(!sClassName){sClassName=sClass;}return"";});var sBody=sBody.replace(/#([\w-]+)/g,function(_,sIdValue){if(bXMLDocument){aExprs.push({key:"id",op:"=",val:sIdValue});}else{sId=sIdValue;}return"";});sTagName=sBody=="*"?"":sBody;var oVars={};for(var i=0,oExpr;oExpr=aExprs[i];i++){var sKey=oExpr.key;if(!oVars[sKey]){aDefineCode.push(getDefineCode(sKey));}aReturnCode.unshift(getReturnCode(oExpr));oVars[sKey]=true;}if(aDefineCode.length){oRet.defines="var "+aDefineCode.join(",")+";";}if(aReturnCode.length){oRet.returns=aReturnCode.join("&&");}oRet.quotID=sId?wrapQuot(sId):"";oRet.quotTAG=sTagName?wrapQuot(bXMLDocument?sTagName:sTagName.toUpperCase()):"";if(bSupportByClassName){oRet.quotCLASS=sClassName?wrapQuot(sClassName):"";}oRet.returnsID=sId?"oEl.id == "+oRet.quotID+" && ":"";oRet.returnsTAG=sTagName&&sTagName!="*"?"oEl.tagName == "+oRet.quotTAG+" && ":"";return oRet;};var splitToParts=function(sQuery){var aParts=[];var sRel=" ";var sBody=sQuery.replace(/(.*?)\s*(!?[+>~ ]|!)\s*/g,function(_,sBody,sRelative){if(sBody){aParts.push({rel:sRel,body:sBody});}sRel=sRelative.replace(/\s+$/g,"")||" ";return"";});if(sBody){aParts.push({rel:sRel,body:sBody});}return aParts;};var isNth_dontShrink=function(oEl,sTagName,nMul,nAdd,sDirection){var nIndex=0;for(var oSib=oEl;oSib;oSib=oSib[sDirection]){if(oSib.nodeType==1&&(!sTagName||sTagName==oSib.tagName)){nIndex++;}}return nIndex%nMul==nAdd;};var compileParts=function(aParts){var aPartExprs=[];for(var i=0,oPart;oPart=aParts[i];i++){aPartExprs.push(getExpression(oPart.body));}var sFunc="";var sPushCode="aRet.push(oEl); if (oOptions.single) { bStop = true; }";for(var i=aParts.length-1,oPart;oPart=aParts[i];i--){var oExpr=aPartExprs[i];var sPush=(debugOption.callback?"cost++;":"")+oExpr.defines;var sReturn="if (bStop) {"+(i==0?"return aRet;":"return;")+"}";if(oExpr.returns=="true"){sPush+=(sFunc?sFunc+"(oEl);":sPushCode)+sReturn;}else{sPush+="if ("+oExpr.returns+") {"+(sFunc?sFunc+"(oEl);":sPushCode)+sReturn+"}";}var sCheckTag="oEl.nodeType != 1";if(oExpr.quotTAG){sCheckTag="oEl.tagName != "+oExpr.quotTAG;}var sTmpFunc="(function(oBase"+(i==0?", oOptions) { var bStop = false; var aRet = [];":") {");if(oExpr.nth){sPush="if (isNth_dontShrink(oEl, "+(oExpr.quotTAG?oExpr.quotTAG:"false")+","+oExpr.nth[0]+","+oExpr.nth[1]+',"'+(oExpr.nth[2]=="nth-of-type"?"previousSibling":"nextSibling")+'")) {'+sPush+"}";}switch(oPart.rel){case" ":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oCandi = oEl;for (; oCandi; oCandi = (oCandi.parentNode || oCandi._IE5_parentNode)) {if (oCandi == oBase) break;}if (!oCandi || "+sCheckTag+") return aRet;"+sPush;}else{sTmpFunc+="var aCandi = getChilds_dontShrink(oBase, "+(oExpr.quotTAG||'"*"')+", "+(oExpr.quotCLASS||"null")+");for (var i = 0, oEl; oEl = aCandi[i]; i++) {"+(oExpr.quotCLASS?"if ("+sCheckTag+") continue;":"")+sPush+"}";}break;case">":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");if ((oEl.parentNode || oEl._IE5_parentNode) != oBase || "+sCheckTag+") return aRet;"+sPush;}else{sTmpFunc+="for (var oEl = oBase.firstChild; oEl; oEl = oEl.nextSibling) {if ("+sCheckTag+") { continue; }"+sPush+"}";}break;case"+":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oPrev;for (oPrev = oEl.previousSibling; oPrev; oPrev = oPrev.previousSibling) { if (oPrev.nodeType == 1) break; }if (!oPrev || oPrev != oBase || "+sCheckTag+") return aRet;"+sPush;}else{sTmpFunc+="for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) { if (oEl.nodeType == 1) break; }if (!oEl || "+sCheckTag+") { return aRet; }"+sPush;}break;case"~":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oCandi = oEl;for (; oCandi; oCandi = oCandi.previousSibling) { if (oCandi == oBase) break; }if (!oCandi || "+sCheckTag+") return aRet;"+sPush;}else{sTmpFunc+="for (var oEl = oBase.nextSibling; oEl; oEl = oEl.nextSibling) {if ("+sCheckTag+") { continue; }if (!markElement_dontShrink(oEl, "+i+")) { break; }"+sPush+"}";}break;case"!":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");for (; oBase; oBase = (oBase.parentNode || oBase._IE5_parentNode)) { if (oBase == oEl) break; }if (!oBase || "+sCheckTag+") return aRet;"+sPush;}else{sTmpFunc+="for (var oEl = (oBase.parentNode || oBase._IE5_parentNode); oEl; oEl = (oEl.parentNode || oEl._IE5_parentNode)) {if ("+sCheckTag+") { continue; }"+sPush+"}";}break;case"!>":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oRel = (oBase.parentNode || oBase._IE5_parentNode);if (!oRel || oEl != oRel || ("+sCheckTag+")) return aRet;"+sPush;}else{sTmpFunc+="var oEl = (oBase.parentNode || oBase._IE5_parentNode);if (!oEl || "+sCheckTag+") { return aRet; }"+sPush;}break;case"!+":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oRel;for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { if (oRel.nodeType == 1) break; }if (!oRel || oEl != oRel || ("+sCheckTag+")) return aRet;"+sPush;}else{sTmpFunc+="for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) { if (oEl.nodeType == 1) break; }if (!oEl || "+sCheckTag+") { return aRet; }"+sPush;}break;case"!~":if(oExpr.quotID){sTmpFunc+="var oEl = oDocument_dontShrink.getElementById("+oExpr.quotID+");var oRel;for (oRel = oBase.previousSibling; oRel; oRel = oRel.previousSibling) { if (oRel.nodeType != 1) { continue; }if (oRel == oEl) { break; }}if (!oRel || ("+sCheckTag+")) return aRet;"+sPush;}else{sTmpFunc+="for (oEl = oBase.previousSibling; oEl; oEl = oEl.previousSibling) {if ("+sCheckTag+") { continue; }if (!markElement_dontShrink(oEl, "+i+")) { break; }"+sPush+"}";}break;}sTmpFunc+=(i==0?"return aRet;":"")+"})";sFunc=sTmpFunc;}eval("var fpCompiled = "+sFunc+";");return fpCompiled;};var parseQuery=function(sQuery){var sCacheKey=sQuery;var fpSelf=arguments.callee;var fpFunction=fpSelf._cache[sCacheKey];if(!fpFunction){sQuery=backupKeys(sQuery);var aParts=splitToParts(sQuery);fpFunction=fpSelf._cache[sCacheKey]=compileParts(aParts);fpFunction.depth=aParts.length;}return fpFunction;};parseQuery._cache={};var parseTestQuery=function(sQuery){var fpSelf=arguments.callee;var aSplitQuery=backupKeys(sQuery).split(/\s*,\s*/);var aResult=[];var nLen=aSplitQuery.length;var aFunc=[];for(var i=0;i"+sTag+":nth-of-type("+sTh+")";});return old_cssquery(sXPath,oParent);};cssquery.debug=function(fpCallback,nRepeat){debugOption.callback=fpCallback;debugOption.repeat=nRepeat||1;};cssquery.safeHTML=function(bFlag){var bIE=/MSIE/.test(window.navigator.userAgent);if(arguments.length>0){safeHTML=bFlag&&bIE;}return safeHTML||!bIE;};cssquery.version=sVersion;cssquery.release=function(){if(/MSIE/.test(window.navigator.userAgent)){delete validUID;validUID={};if(bUseResultCache){cssquery.clearCache();}}};cssquery._getCacheInfo=function(){return{uidCache:validUID,eleCache:oResultCache};};cssquery._resetUID=function(){UID=0;};cssquery.extreme=function(bExtreme){if(arguments.length==0){bExtreme=true;}bExtremeMode=bExtreme;};return cssquery;})();jindo.$Agent=function(){var cl=arguments.callee;var cc=cl._cached;if(cc){return cc;}if(!(this instanceof cl)){return new cl;}if(!cc){cl._cached=this;}this._navigator=navigator;this._dm=document.documentMode;};jindo.$Agent.prototype.navigator=function(){var info={},ver=-1,nativeVersion=-1,u=this._navigator.userAgent,v=this._navigator.vendor||"",dm=this._dm;function f(s,h){return((h||"").indexOf(s)>-1);}info.getName=function(){var name="";for(x in info){if(typeof info[x]=="boolean"&&info[x]&&info.hasOwnProperty(x)){name=x;}}return name;};info.webkit=f("WebKit",u);info.opera=(window.opera!==undefined)||f("Opera",u);info.ie=!info.opera&&(f("MSIE",u)||f("Trident",u));info.chrome=info.webkit&&f("Chrome",u);info.safari=info.webkit&&!info.chrome&&f("Apple",v);info.firefox=f("Firefox",u);info.mozilla=f("Gecko",u)&&!info.safari&&!info.chrome&&!info.firefox&&!info.ie;info.camino=f("Camino",v);info.netscape=f("Netscape",u);info.omniweb=f("OmniWeb",u);info.icab=f("iCab",v);info.konqueror=f("KDE",v);info.mobile=(f("Mobile",u)||f("Android",u)||f("Nokia",u)||f("webOS",u)||f("Opera Mini",u)||f("BlackBerry",u)||(f("Windows",u)&&f("PPC",u))||f("Smartphone",u)||f("IEMobile",u))&&!f("iPad",u);info.msafari=(!f("IEMobile",u)&&f("Mobile",u))||(f("iPad",u)&&f("Safari",u));info.mopera=f("Opera Mini",u);info.mie=f("PPC",u)||f("Smartphone",u)||f("IEMobile",u);try{if(info.ie){if(dm>0){ver=dm;if(u.match(/(?:Trident)\/([0-9.]+)/)){var nTridentNum=parseFloat(RegExp.$1,10);if(nTridentNum>3){nativeVersion=nTridentNum+4;}}else{nativeVersion=ver;}}else{nativeVersion=ver=u.match(/(?:MSIE) ([0-9.]+)/)[1];}}else{if(info.safari||info.msafari){ver=parseFloat(u.match(/Safari\/([0-9.]+)/)[1]);if(ver==100){ver=1.1;}else{if(u.match(/Version\/([0-9.]+)/)){ver=RegExp.$1;}else{ver=[1,1.2,-1,1.3,2,3][Math.floor(ver/100)];}}}else{if(info.mopera){ver=u.match(/(?:Opera\sMini)\/([0-9.]+)/)[1];}else{if(info.firefox||info.opera||info.omniweb){ver=u.match(/(?:Firefox|Opera|OmniWeb)\/([0-9.]+)/)[1];}else{if(info.mozilla){ver=u.match(/rv:([0-9.]+)/)[1];}else{if(info.icab){ver=u.match(/iCab[ \/]([0-9.]+)/)[1];}else{if(info.chrome){ver=u.match(/Chrome[ \/]([0-9.]+)/)[1];}}}}}}}info.version=parseFloat(ver);info.nativeVersion=parseFloat(nativeVersion);if(isNaN(info.version)){info.version=-1;}}catch(e){info.version=-1;}this.navigator=function(){return info;};return info;};jindo.$Agent.prototype.os=function(){var info=new Object;var u=this._navigator.userAgent;var p=this._navigator.platform;var f=function(s,h){return(h.indexOf(s)>-1);};info.getName=function(){var name="";for(x in info){if(typeof info[x]=="boolean"&&info[x]&&info.hasOwnProperty(x)){name=x;}}return name;};info.win=f("Win",p);info.mac=f("Mac",p);info.linux=f("Linux",p);info.win2000=info.win&&(f("NT 5.0",u)||f("2000",u));info.winxp=info.win&&f("NT 5.1",u);info.xpsp2=info.winxp&&f("SV1",u);info.vista=info.win&&f("NT 6.0",u);info.win7=info.win&&f("NT 6.1",u);info.ipad=f("iPad",u);info.iphone=f("iPhone",u)&&!info.ipad;info.android=f("Android",u);info.nokia=f("Nokia",u);info.webos=f("webOS",u);info.blackberry=f("BlackBerry",u);info.mwin=f("PPC",u)||f("Smartphone",u)||f("IEMobile",u);this.os=function(){return info;};return info;};jindo.$Agent.prototype.flash=function(){var info=new Object;var p=this._navigator.plugins;var m=this._navigator.mimeTypes;var f=null;info.installed=false;info.version=-1;if(typeof p!="undefined"&&p.length){f=p["Shockwave Flash"];if(f){info.installed=true;if(f.description){info.version=parseFloat(f.description.match(/[0-9.]+/)[0]);}}if(p["Shockwave Flash 2.0"]){info.installed=true;info.version=2;}}else{if(typeof m!="undefined"&&m.length){f=m["application/x-shockwave-flash"];info.installed=(f&&f.enabledPlugin);}else{for(var i=10;i>1;i--){try{f=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+i);info.installed=true;info.version=i;break;}catch(e){}}}}this.flash=function(){return info;};this.info=this.flash;return info;};jindo.$Agent.prototype.silverlight=function(){var info=new Object;var p=this._navigator.plugins;var s=null;info.installed=false;info.version=-1;if(typeof p!="undefined"&&p.length){s=p["Silverlight Plug-In"];if(s){info.installed=true;info.version=parseInt(s.description.split(".")[0],10);if(s.description=="1.0.30226.2"){info.version=2;}}}else{try{s=new ActiveXObject("AgControl.AgControl");info.installed=true;if(s.isVersionSupported("3.0")){info.version=3;}else{if(s.isVersionSupported("2.0")){info.version=2;}else{if(s.isVersionSupported("1.0")){info.version=1;}}}}catch(e){}}this.silverlight=function(){return info;};return info;};jindo.$A=function(array){var cl=arguments.callee;if(typeof array=="undefined"||array==null){array=[];}if(array instanceof cl){return array;}if(!(this instanceof cl)){return new cl(array);}this._array=[];if(array.constructor!=String){this._array=[];for(var i=0;i-1);};jindo.$A.prototype.indexOf=function(oValue){if(typeof this._array.indexOf!="undefined"){jindo.$A.prototype.indexOf=function(oValue){return this._array.indexOf(oValue);};}else{jindo.$A.prototype.indexOf=function(oValue){for(var i=0;iMath.random()?1:-1;});return this;};jindo.$A.prototype.reverse=function(){this._array.reverse();return this;};jindo.$A.prototype.empty=function(){return this.length(0);};jindo.$A.Break=function(){if(!(this instanceof arguments.callee)){throw new arguments.callee;}};jindo.$A.Continue=function(){if(!(this instanceof arguments.callee)){throw new arguments.callee;}};jindo.$A.prototype.map=function(fCallback,oThis){if(typeof this._array.map=="function"){jindo.$A.prototype.map=function(fCallback,oThis){var arr=this._array;var errBreak=this.constructor.Break;var errContinue=this.constructor.Continue;function f(v,i,a){try{return fCallback.call(oThis,v,i,a);}catch(e){if(e instanceof errContinue){return v;}else{throw e;}}}try{this._array=this._array.map(f);}catch(e){if(!(e instanceof errBreak)){throw e;}}return this;};}else{jindo.$A.prototype.map=function(fCallback,oThis){var arr=this._array;var returnArr=[];var errBreak=this.constructor.Break;var errContinue=this.constructor.Continue;function f(v,i,a){try{return fCallback.call(oThis,v,i,a);}catch(e){if(e instanceof errContinue){return v;}else{throw e;}}}for(var i=0;i=b.length){b[j]=a[i];}}this._array=b;return this;};jindo.$Ajax=function(url,option){var cl=arguments.callee;if(!(this instanceof cl)){return new cl(url,option);}function _getXHR(){if(window.XMLHttpRequest){return new XMLHttpRequest();}else{if(ActiveXObject){try{return new ActiveXObject("MSXML2.XMLHTTP");}catch(e){return new ActiveXObject("Microsoft.XMLHTTP");}return null;}}}var loc=location.toString();var domain="";try{domain=loc.match(/^https?:\/\/([a-z0-9_\-\.]+)/i)[1];}catch(e){}this._status=0;this._url=url;this._options=new Object;this._headers=new Object;this._options={type:"xhr",method:"post",proxy:"",timeout:0,onload:function(req){},onerror:null,ontimeout:function(req){},jsonp_charset:"utf-8",callbackid:"",callbackname:"",sendheader:true,async:true,decode:true,postBody:false};this.option(option);if(jindo.$Ajax.CONFIG){this.option(jindo.$Ajax.CONFIG);}var _opt=this._options;_opt.type=_opt.type.toLowerCase();_opt.method=_opt.method.toLowerCase();if(typeof window.__jindo2_callback=="undefined"){window.__jindo2_callback=new Array();}switch(_opt.type){case"put":case"delete":case"get":case"post":_opt.method=_opt.type;_opt.type="xhr";case"xhr":this._request=_getXHR();break;case"flash":if(!jindo.$Ajax.SWFRequest){throw Error("Require jindo.$Ajax.SWFRequest");}this._request=new jindo.$Ajax.SWFRequest(jindo.$Fn(this.option,this).bind());break;case"jsonp":if(!jindo.$Ajax.JSONPRequest){throw Error("Require jindo.$Ajax.JSONPRequest");}_opt.method="get";this._request=new jindo.$Ajax.JSONPRequest(jindo.$Fn(this.option,this).bind());break;case"iframe":if(!jindo.$Ajax.FrameRequest){throw Error("Require jindo.$Ajax.FrameRequest");}this._request=new jindo.$Ajax.FrameRequest(jindo.$Fn(this.option,this).bind());break;}};jindo.$Ajax.prototype._onload=(function(isIE){if(isIE){return function(){var bSuccess=this._request.readyState==4&&this._request.status==200;var oResult;if(this._request.readyState==4){try{if(this._request.status!=200&&typeof this._options.onerror=="function"){if(!this._request.status==0){this._options.onerror(jindo.$Ajax.Response(this._request));}}else{if(!this._is_abort){oResult=this._options.onload(jindo.$Ajax.Response(this._request));}}}finally{if(typeof this._oncompleted=="function"){this._oncompleted(bSuccess,oResult);}if(this._options.type=="xhr"){this.abort();try{delete this._request.onload;}catch(e){this._request.onload=undefined;}}delete this._request.onreadystatechange;}}};}else{return function(){var bSuccess=this._request.readyState==4&&this._request.status==200;var oResult;if(this._request.readyState==4){try{if(this._request.status!=200&&typeof this._options.onerror=="function"){this._options.onerror(jindo.$Ajax.Response(this._request));}else{oResult=this._options.onload(jindo.$Ajax.Response(this._request));}}finally{this._status--;if(typeof this._oncompleted=="function"){this._oncompleted(bSuccess,oResult);}}}};}})(/MSIE/.test(window.navigator.userAgent));jindo.$Ajax.prototype.request=function(oData){this._status++;var t=this;var req=this._request;var opt=this._options;var data,v,a=[],data="";var _timer=null;var url=this._url;this._is_abort=false;if(opt.postBody&&opt.type.toUpperCase()=="XHR"&&opt.method.toUpperCase()!="GET"){if(typeof oData=="string"){data=oData;}else{data=jindo.$Json(oData).toString();}}else{if(typeof oData=="undefined"||!oData){data=null;}else{for(var k in oData){if(oData.hasOwnProperty(k)){v=oData[k];if(typeof v=="function"){v=v();}if(v instanceof Array||v instanceof jindo.$A){jindo.$A(v).forEach(function(value,index,array){a[a.length]=k+"="+encodeURIComponent(value);});}else{a[a.length]=k+"="+encodeURIComponent(v);}}}data=a.join("&");}}if(data&&opt.type.toUpperCase()=="XHR"&&opt.method.toUpperCase()=="GET"){if(url.indexOf("?")==-1){url+="?";}else{url+="&";}url+=data;data=null;}req.open(opt.method.toUpperCase(),url,opt.async);if(opt.type.toUpperCase()=="XHR"&&opt.method.toUpperCase()=="GET"&&/MSIE/.test(window.navigator.userAgent)){req.setRequestHeader("If-Modified-Since","Thu, 1 Jan 1970 00:00:00 GMT");}if(opt.sendheader){if(!this._headers["Content-Type"]){req.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");}req.setRequestHeader("charset","utf-8");for(var x in this._headers){if(this._headers.hasOwnProperty(x)){if(typeof this._headers[x]=="function"){continue;}req.setRequestHeader(x,String(this._headers[x]));}}}var navi=navigator.userAgent;if(req.addEventListener&&!(navi.indexOf("Opera")>-1)&&!(navi.indexOf("MSIE")>-1)){if(this._loadFunc){req.removeEventListener("load",this._loadFunc,false);}this._loadFunc=function(rq){clearTimeout(_timer);_timer=undefined;t._onload(rq);};req.addEventListener("load",this._loadFunc,false);}else{if(typeof req.onload!="undefined"){req.onload=function(rq){if(req.readyState==4&&!t._is_abort){clearTimeout(_timer);_timer=undefined;t._onload(rq);}};}else{if(window.navigator.userAgent.match(/(?:MSIE) ([0-9.]+)/)[1]==6&&opt.async){var onreadystatechange=function(rq){if(req.readyState==4&&!t._is_abort){if(_timer){clearTimeout(_timer);_timer=undefined;}t._onload(rq);clearInterval(t._interval);t._interval=undefined;}};this._interval=setInterval(onreadystatechange,300);}else{req.onreadystatechange=function(rq){if(req.readyState==4){clearTimeout(_timer);_timer=undefined;t._onload(rq);}};}}}if(opt.timeout>0){if(this._timer){clearTimeout(this._timer);}_timer=setTimeout(function(){t._is_abort=true;if(t._interval){clearInterval(t._interval);t._interval=undefined;}try{req.abort();}catch(e){}opt.ontimeout(req);if(typeof t._oncompleted=="function"){t._oncompleted(false);}},opt.timeout*1000);this._timer=_timer;}this._test_url=url;req.send(data);return this;};jindo.$Ajax.prototype.isIdle=function(){return this._status==0;};jindo.$Ajax.prototype.abort=function(){try{if(this._interval){clearInterval(this._interval);}if(this._timer){clearTimeout(this._timer);}this._interval=undefined;this._timer=undefined;this._is_abort=true;this._request.abort();}finally{this._status--;}return this;};jindo.$Ajax.prototype.option=function(name,value){if(typeof name=="undefined"){return"";}if(typeof name=="string"){if(typeof value=="undefined"){return this._options[name];}this._options[name]=value;return this;}try{for(var x in name){if(name.hasOwnProperty(x)){this._options[x]=name[x];}}}catch(e){}return this;};jindo.$Ajax.prototype.header=function(name,value){if(typeof name=="undefined"){return"";}if(typeof name=="string"){if(typeof value=="undefined"){return this._headers[name];}this._headers[name]=value;return this;}try{for(var x in name){if(name.hasOwnProperty(x)){this._headers[x]=name[x];}}}catch(e){}return this;};jindo.$Ajax.Response=function(req){if(this===jindo.$Ajax){return new jindo.$Ajax.Response(req);}this._response=req;};jindo.$Ajax.Response.prototype.xml=function(){return this._response.responseXML;};jindo.$Ajax.Response.prototype.text=function(){return this._response.responseText;};jindo.$Ajax.Response.prototype.status=function(){return this._response.status;};jindo.$Ajax.Response.prototype.readyState=function(){return this._response.readyState;};jindo.$Ajax.Response.prototype.json=function(){if(this._response.responseJSON){return this._response.responseJSON;}else{if(this._response.responseText){try{return eval("("+this._response.responseText+")");}catch(e){return{};}}}return{};};jindo.$Ajax.Response.prototype.header=function(name){if(typeof name=="string"){return this._response.getResponseHeader(name);}return this._response.getAllResponseHeaders();};jindo.$Ajax.RequestBase=jindo.$Class({_respHeaderString:"",callbackid:"",callbackname:"",responseXML:null,responseJSON:null,responseText:"",status:404,readyState:0,$init:function(fpOption){},onload:function(){},abort:function(){},open:function(){},send:function(){},setRequestHeader:function(sName,sValue){this._headers[sName]=sValue;},getResponseHeader:function(sName){return this._respHeaders[sName]||"";},getAllResponseHeaders:function(){return this._respHeaderString;},_getCallbackInfo:function(){var id="";if(this.option("callbackid")!=""){var idx=0;do{id="_"+this.option("callbackid")+"_"+idx;idx++;}while(window.__jindo2_callback[id]);}else{do{id="_"+Math.floor(Math.random()*10000);}while(window.__jindo2_callback[id]);}if(this.option("callbackname")==""){this.option("callbackname","_callback");}return{callbackname:this.option("callbackname"),id:id,name:"window.__jindo2_callback."+id};}});jindo.$Ajax.JSONPRequest=jindo.$Class({_headers:{},_respHeaders:{},_script:null,_onerror:null,$init:function(fpOption){this.option=fpOption;},_callback:function(data){if(this._onerror){clearTimeout(this._onerror);this._onerror=null;}var self=this;this.responseJSON=data;this.onload(this);setTimeout(function(){self.abort();},10);},abort:function(){if(this._script){try{this._script.parentNode.removeChild(this._script);}catch(e){}}},open:function(method,url){this.responseJSON=null;this._url=url;},send:function(data){var t=this;var info=this._getCallbackInfo();var head=document.getElementsByTagName("head")[0];this._script=jindo.$(" + + + + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/basic.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/basic.js new file mode 100644 index 0000000..7f0121b --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/basic.js @@ -0,0 +1,346 @@ +jQuery.fn.bindAll = function(options) { + var $this = this; + jQuery.each(options, function(key, val){ + $this.bind(key, val); + }); + return this; +} + +jQuery(function ($) { + 'use strict'; + + var ed_nonce = ''; + + if( !!opener && !!opener.window && !!opener.window.nhn ){ + ed_nonce = opener.window.nhn.husky.SE2M_Configuration.SE2M_Accessibility.ed_nonce; + } + + // Change this to the location of your server-side upload handler: + var gnu = { + url : './php/?_nonce='+ed_nonce, + container_el : 'body', + dreg_area : '#drag_area', + dreg_area_list : '#drag_area > ul', + progress_bar : '#progress .progress-bar', + filter : /^(image\/bmp|image\/gif|image\/jpg|image\/jpeg|image\/png)$/i, + files : [], + file_limit : 10, //한번에 올릴수 파일갯수 제한 + imgw : 100, + imgh : 70, + file_api_support : !!(window.ProgressEvent && window.FileReader), + $elTextGuide : $("#guide_text"), + init : function(){ + $(this.dreg_area_list).sortable({ + 'cursor':'pointer', + 'placeholder':'placeholder' + }); + $(this.dreg_area_list).disableSelection(); + if( this.file_api_support ) this.$elTextGuide.removeClass("hidebg").addClass("showbg"); + }, + file_push : function(file){ + var othis = this, + last = othis.files.length; + + othis.files.push(file); + }, + _readymodebg : function(){ + if( this.file_api_support ) { + var sClass = this.$elTextGuide.attr('class'); + if(sClass.indexOf('hidebg') > 0){ + this.$elTextGuide.removeClass('hidebg'); + this.$elTextGuide.addClass('showbg'); + } + } + }, + _startmodebg : function(){ + if( this.file_api_support ) { + var sClass = this.$elTextGuide.attr('class'); + if(sClass.indexOf('hidebg') < 0){ + this.$elTextGuide.removeClass('showbg'); + this.$elTextGuide.addClass('hidebg'); + } + } + }, + _delete : function(e){ + e.preventDefault(); + var othis = gnu, + $button = $(e.currentTarget), + delete_url = $button.attr("data-delete"); + if( delete_url ){ + $.ajax({ + url: othis.url+"&del=1&file="+ delete_url + }).done(function (result) { + }); + } + $button.parents('li.sort_list').fadeOut(300, function(){ + $(this).remove(); + var $dreg_area = $(othis.dreg_area_list); + $dreg_area.sortable('refresh'); + if( !$dreg_area.children('li').length ) othis._readymodebg(); + }); + }, + _add : function(e, data, preload){ + var othis = this; + othis._startmodebg(); + data.context = $('
  • ').addClass("sort_list").appendTo(this.dreg_area_list); + $.each(data.files, function (index, file) { + if ( !preload && !othis.filter.test(file.type)) { + data.context.remove(); + alert('이미지만 허용합니다.'); + return true; + } + var node = $('
    ') + .append($('').text(file.name)) + .append($('').addClass("delete_img").attr({"data-delete":file.name,"data-url":file.url}).html("삭제")), + $img = "", + size_text = ''; + + if ( preload && preload != 'swfupload' ){ + var ret = othis.get_ratio( file.width, file.height ), + size_text = file.width+" x "+file.height; + $img = ""; + + } + if (!index) { + node + .prepend('
    ') + .prepend($img); + if(size_text){ + node.append('
    ') + .append($('').text(size_text)) + } + } + node.appendTo(data.context); + node.find(".delete_img").on("click", othis._delete); + }); + $(othis.dreg_area_list).sortable('refresh'); + }, + get_file_all : function(){ + var othis = this, + oDate = new Date(); + $.ajax({ + // Uncomment the following to send cross-domain cookies: + //xhrFields: {withCredentials: true}, + //url: $('#fileupload').fileupload('option', 'url'), + url: this.url+"&t="+ oDate.getTime(), + dataType: 'json', + context: $('#fileupload')[0] + }).always(function () { + //$(this).removeClass('fileupload-processing'); + }).done(function (result) { + $.each(result.files, function (index, data) { + var tmp = { files : [] }; + tmp.files[0] = data; + othis._add( $.Event('add'), tmp, 'preload' ); + }); + }); + }, + _processalways : function(e, data){ + var index = data.index, + file = data.files[index], + node = $(data.context.children()[index]); + if (file.error) { + node + .append('
    ') + .append($('').text(file.error)); + } + if (index + 1 === data.files.length) { + data.context.find('button') + .text('Upload') + .prop('disabled', !!data.files.error); + } + }, + obj_to_arr : function(obj){ + var array = $.map(obj, function(value, index) { + return [value]; + }); + return array; + }, + _done : function(e, data){ + var othis = this; + $.each(data.result.files, function (index, file) { + if (file.url && !file.error) { + var ret = othis.get_ratio( file.width, file.height ), + node = $(data.context.children()[index]), + size_text = file.width+" x "+file.height, + //$img = "", + link = $('') + .attr('target', '_blank') + .prop('href', file.url); + node + //.wrap(link) + .append('
    ') + .append($('').text(size_text)) + .find("img.pre_thumb").attr({"src":file.url,"width":ret['width'],"height":ret['height']}) + .end().find(".delete_img").attr({"data-delete":file.name,"data-url":file.url}); + } else if (file.error) { + var error = $('').text(file.error); + $(data.context.children()[index]) + .append('
    ') + .append(error); + } + othis.file_push(file); + }); + }, + get_ratio : function(width, height){ + var ratio = 0, + ret_img = []; + if( !width || !height ){ + ret_img['width'] = this.imgw; + ret_img['height'] = this.imgh; + return ret_img; + } + if(width > this.imgw){ + ratio = this.imgw / width; + height = height * ratio; + width = this.imgw; + } + if( height > this.imgh ){ + ratio = this.imgh / height; + width = width * ratio; + height = this.imgh; + } + ret_img['width'] = parseInt(width); + ret_img['height'] = parseInt(height); + return ret_img; + }, + setPhotoToEditor : function(oFileInfo){ + if (!!opener && !!opener.nhn && !!opener.nhn.husky && !!opener.nhn.husky.PopUpManager) { + //스마트 에디터 플러그인을 통해서 넣는 방법 (oFileInfo는 Array) + opener.nhn.husky.PopUpManager.setCallback(window, 'SET_PHOTO', [oFileInfo]); + //본문에 바로 tag를 넣는 방법 (oFileInfo는 String으로 ) + //opener.nhn.husky.PopUpManager.setCallback(window, 'PASTE_HTML', [oFileInfo]); + } + } + } + + $('#fileupload').fileupload({ + url: gnu.url, + dataType: 'json', + container_el: gnu.container_el, + dropZone: $(gnu.dreg_area), + autoUpload: true, + sequentialUploads: true, + acceptFileTypes: /(\.|\/)(gif|jpe?g|bmp|png)$/i, + // Enable image resizing, except for Android and Opera, + // which actually support image resizing, but fail to + // send Blob objects via XHR requests: + disableImageResize: true, + limit_filesLength : gnu.file_limit + }).on('fileuploadadd', function (e, data) { + gnu._add(e, data); + }).on('fileuploadprocessalways', function (e, data) { + gnu._processalways(e, data); + }).on('fileuploaddone', function (e, data) { + + gnu._done( e, data ); + + }).on('fileuploadfail', function (e, data) { + $.each(data.files, function (index, file) { + var error = $('').text('File upload failed.'); + $(data.context.children()[index]) + .append('
    ') + .append(error); + }); + }).prop('disabled', !$.support.fileInput) + .parent().addClass($.support.fileInput ? undefined : 'disabled'); + + gnu.init(); + + var listeners = { + data : {}, + log : false, + swfuploadLoaded: function(event){ + if(this.log) $('.log', this).append('
  • Loaded
  • '); + }, + fileQueued: function(event, file){ + if(this.log) $('.log', this).append('
  • File queued - '+file.name+'
  • '); + // start the upload once it is queued + // but only if this queue is not disabled + if (!$('input[name=disabled]:checked', this).length) { + $(this).swfupload('startUpload'); + } + }, + fileQueueError: function(event, file, errorCode, message){ + switch (errorCode) + { + case -100 : + alert("파일을 "+message+"개 이하로 선택해주세요."); + break; + } + if(this.log) $('.log', this).append('
  • File queue error - '+message+'
  • '); + }, + fileDialogStart: function(event){ + if(this.log) $('.log', this).append('
  • File dialog start
  • '); + }, + fileDialogComplete: function(event, numFilesSelected, numFilesQueued){ + if(this.log) $('.log', this).append('
  • File dialog complete
  • '); + }, + uploadStart: function(event, file){ + listeners.data.files = $.makeArray(file); + gnu._add( event, listeners.data, 'swfupload' ); + if(this.log) $('.log', this).append('
  • Upload start - '+file.name+'
  • '); + }, + uploadProgress: function(event, file, bytesLoaded){ + if(this.log) $('.log', this).append('
  • Upload progress - '+bytesLoaded+'
  • '); + }, + uploadSuccess: function(event, file, serverData){ + listeners.data.result = jQuery.parseJSON( serverData ); + gnu._done( event, listeners.data ); + if(this.log) $('.log', this).append('
  • Upload success - '+file.name+'
  • '); + + }, + uploadComplete: function(event, file){ + if(this.log) $('.log', this).append('
  • Upload complete - '+file.name+'
  • '); + // upload has completed, lets try the next one in the queue + // but only if this queue is not disabled + if (!$('input[name=disabled]:checked', this).length) { + $(this).swfupload('startUpload'); + } + }, + uploadError: function(event, file, errorCode, message){ + if(this.log) $('.log', this).append('
  • Upload error - '+message+'
  • '); + } + }; + + $(gnu.container_el).bindAll(listeners); + /* listeners이벤트 */ + + $(gnu.dreg_area).bind('drop dragover', function (e) { + e.preventDefault(); + if( !gnu.file_api_support && e.type == 'drop' ) alert("브라우저가 드래그 앤 드랍을 지원하지 않습니다."); + }); + $("#all_remove_btn").bind("click", function(e){ + e.preventDefault(); + if( $(gnu.dreg_area_list).children().length ){ + if (confirm("추가한 이미지가 있습니다.정말 삭제 하시겠습니까?")){ + $(gnu.dreg_area_list).find(".delete_img").each( function(i){ + $(this).trigger("click"); + }); + $(gnu.dreg_area_list).sortable('refresh'); + } + } + }); + $("#img_upload_submit").bind("click", function(e){ + e.preventDefault(); + var aResult = [], j = 0; + $(gnu.dreg_area_list).find(".delete_img").each( function(i, f){ + if( !$(this).attr("data-url") ) return true; + aResult[j] = []; + aResult[j]['bNewLine'] = 'true'; + aResult[j]['sAlign'] = ''; + aResult[j]['sFileName'] = $(this).attr("data-delete"); + aResult[j]['sFileURL'] = $(this).attr("data-url"); + j++; + }); + if( aResult.length ){ + gnu.setPhotoToEditor(aResult); + aResult = null; + } + window.close(); + }); + $("#close_w_btn").bind("click", function(e){ + e.preventDefault(); + window.close(); + }); +}); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-1.8.3.min.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-1.8.3.min.js new file mode 100644 index 0000000..3883779 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
    a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
    t
    ",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
    ",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
    ",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

    ",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
    ","
    "]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
    ").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-ui.min.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-ui.min.js new file mode 100644 index 0000000..192dc36 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery-ui.min.js @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.10.1 - 2013-02-15 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js +* Copyright 2013 jQuery Foundation and other contributors; Licensed MIT */ +(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.10.1",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)}})})(jQuery),function(e,t){var n=0,r=Array.prototype.slice,i=e.cleanData;e.cleanData=function(t){for(var n=0,r;(r=t[n])!=null;n++)try{e(r).triggerHandler("remove")}catch(s){}i(t)},e.widget=function(t,n,r){var i,s,o,u,a={},f=t.split(".")[0];t=t.split(".")[1],i=f+"-"+t,r||(r=n,n=e.Widget),e.expr[":"][i.toLowerCase()]=function(t){return!!e.data(t,i)},e[f]=e[f]||{},s=e[f][t],o=e[f][t]=function(e,t){if(!this._createWidget)return new o(e,t);arguments.length&&this._createWidget(e,t)},e.extend(o,s,{version:r.version,_proto:e.extend({},r),_childConstructors:[]}),u=new n,u.options=e.widget.extend({},u.options),e.each(r,function(t,r){if(!e.isFunction(r)){a[t]=r;return}a[t]=function(){var e=function(){return n.prototype[t].apply(this,arguments)},i=function(e){return n.prototype[t].apply(this,e)};return function(){var t=this._super,n=this._superApply,s;return this._super=e,this._superApply=i,s=r.apply(this,arguments),this._super=t,this._superApply=n,s}}()}),o.prototype=e.widget.extend(u,{widgetEventPrefix:s?u.widgetEventPrefix:t},a,{constructor:o,namespace:f,widgetName:t,widgetFullName:i}),s?(e.each(s._childConstructors,function(t,n){var r=n.prototype;e.widget(r.namespace+"."+r.widgetName,o,n._proto)}),delete s._childConstructors):n._childConstructors.push(o),e.widget.bridge(t,o)},e.widget.extend=function(n){var i=r.call(arguments,1),s=0,o=i.length,u,a;for(;s",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})}(jQuery),function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.10.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){this.options.helper==="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e("
    ").css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!=="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!=="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n,r=this,i=!1,s=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(s=e.ui.ddmanager.drop(this,t)),this.dropped&&(s=this.dropped,this.dropped=!1),n=this.element[0];while(n&&(n=n.parentNode))n===document&&(i=!0);return!i&&this.options.helper==="original"?!1:(this.options.revert==="invalid"&&!s||this.options.revert==="valid"&&s||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){r._trigger("stop",t)!==!1&&r._clear()}):this._trigger("stop",t)!==!1&&this._clear(),!1)},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").addBack().each(function(){this===t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper==="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo==="parent"?this.element[0].parentNode:n.appendTo),r[0]!==this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition==="absolute"&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()==="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition==="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,n,r,i=this.options;i.containment==="parent"&&(i.containment=this.helper[0].parentNode);if(i.containment==="document"||i.containment==="window")this.containment=[i.containment==="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,i.containment==="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(i.containment==="document"?0:e(window).scrollLeft())+e(i.containment==="document"?document:window).width()-this.helperProportions.width-this.margins.left,(i.containment==="document"?0:e(window).scrollTop())+(e(i.containment==="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(i.containment)&&i.containment.constructor!==Array){n=e(i.containment),r=n[0];if(!r)return;t=e(r).css("overflow")!=="hidden",this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(t?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(t?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else i.containment.constructor===Array&&(this.containment=i.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t==="absolute"?1:-1,i=this.cssPosition!=="absolute"||this.scrollParent[0]!==document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,s=/(html|body)/i.test(i[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():s?0:i.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():s?0:i.scrollLeft())*r}},_generatePosition:function(t){var n,r,i,s,o=this.options,u=this.cssPosition!=="absolute"||this.scrollParent[0]!==document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,a=/(html|body)/i.test(u[0].tagName),f=t.pageX,l=t.pageY;return this.originalPosition&&(this.containment&&(this.relative_container?(r=this.relative_container.offset(),n=[this.containment[0]+r.left,this.containment[1]+r.top,this.containment[2]+r.left,this.containment[3]+r.top]):n=this.containment,t.pageX-this.offset.click.leftn[2]&&(f=n[2]+this.offset.click.left),t.pageY-this.offset.click.top>n[3]&&(l=n[3]+this.offset.click.top)),o.grid&&(i=o.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/o.grid[1])*o.grid[1]:this.originalPageY,l=n?i-this.offset.click.top>=n[1]||i-this.offset.click.top>n[3]?i:i-this.offset.click.top>=n[1]?i-o.grid[1]:i+o.grid[1]:i,s=o.grid[0]?this.originalPageX+Math.round((f-this.originalPageX)/o.grid[0])*o.grid[0]:this.originalPageX,f=n?s-this.offset.click.left>=n[0]||s-this.offset.click.left>n[2]?s:s-this.offset.click.left>=n[0]?s-o.grid[0]:s+o.grid[0]:s)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():a?0:u.scrollTop()),left:f-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():a?0:u.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"),this.helper[0]!==this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1},_trigger:function(t,n,r){return r=r||this._uiHash(),e.ui.plugin.call(this,t,[n,r]),t==="drag"&&(this.positionAbs=this._convertPositionTo("absolute")),e.Widget.prototype._trigger.call(this,t,n,r)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),e.ui.plugin.add("draggable","connectToSortable",{start:function(t,n){var r=e(this).data("ui-draggable"),i=r.options,s=e.extend({},n,{item:r.element});r.sortables=[],e(i.connectToSortable).each(function(){var n=e.data(this,"ui-sortable");n&&!n.options.disabled&&(r.sortables.push({instance:n,shouldRevert:n.options.revert}),n.refreshPositions(),n._trigger("activate",t,s))})},stop:function(t,n){var r=e(this).data("ui-draggable"),i=e.extend({},n,{item:r.element});e.each(r.sortables,function(){this.instance.isOver?(this.instance.isOver=0,r.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(t),this.instance.options.helper=this.instance.options._helper,r.options.helper==="original"&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",t,i))})},drag:function(t,n){var r=e(this).data("ui-draggable"),i=this;e.each(r.sortables,function(){var s=!1,o=this;this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this.instance._intersectsWith(this.instance.containerCache)&&(s=!0,e.each(r.sortables,function(){return this.instance.positionAbs=r.positionAbs,this.instance.helperProportions=r.helperProportions,this.instance.offset.click=r.offset.click,this!==o&&this.instance._intersectsWith(this.instance.containerCache)&&e.contains(o.instance.element[0],this.instance.element[0])&&(s=!1),s})),s?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=e(i).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return n.helper[0]},t.target=this.instance.currentItem[0],this.instance._mouseCapture(t,!0),this.instance._mouseStart(t,!0,!0),this.instance.offset.click.top=r.offset.click.top,this.instance.offset.click.left=r.offset.click.left,this.instance.offset.parent.left-=r.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=r.offset.parent.top-this.instance.offset.parent.top,r._trigger("toSortable",t),r.dropped=this.instance.element,r.currentItem=r.element,this.instance.fromOutside=r),this.instance.currentItem&&this.instance._mouseDrag(t)):this.instance.isOver&&(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",t,this.instance._uiHash(this.instance)),this.instance._mouseStop(t,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),r._trigger("fromSortable",t),r.dropped=!1)})}}),e.ui.plugin.add("draggable","cursor",{start:function(){var t=e("body"),n=e(this).data("ui-draggable").options;t.css("cursor")&&(n._cursor=t.css("cursor")),t.css("cursor",n.cursor)},stop:function(){var t=e(this).data("ui-draggable").options;t._cursor&&e("body").css("cursor",t._cursor)}}),e.ui.plugin.add("draggable","opacity",{start:function(t,n){var r=e(n.helper),i=e(this).data("ui-draggable").options;r.css("opacity")&&(i._opacity=r.css("opacity")),r.css("opacity",i.opacity)},stop:function(t,n){var r=e(this).data("ui-draggable").options;r._opacity&&e(n.helper).css("opacity",r._opacity)}}),e.ui.plugin.add("draggable","scroll",{start:function(){var t=e(this).data("ui-draggable");t.scrollParent[0]!==document&&t.scrollParent[0].tagName!=="HTML"&&(t.overflowOffset=t.scrollParent.offset())},drag:function(t){var n=e(this).data("ui-draggable"),r=n.options,i=!1;if(n.scrollParent[0]!==document&&n.scrollParent[0].tagName!=="HTML"){if(!r.axis||r.axis!=="x")n.overflowOffset.top+n.scrollParent[0].offsetHeight-t.pageY=0;c--){u=p.snapElements[c].left,a=u+p.snapElements[c].width,f=p.snapElements[c].top,l=f+p.snapElements[c].height;if(!(u-vt&&e=h&&a<=p||f>=h&&f<=p||ap)&&(o>=l&&o<=c||u>=l&&u<=c||oc);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r,i,s=e.ui.ddmanager.droppables[t.options.scope]||[],o=n?n.type:null,u=(t.currentItem||t.element).find(":data(ui-droppable)").addBack();e:for(r=0;r
    ").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.data("ui-resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=u.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor===String){this.handles==="all"&&(this.handles="n,e,s,w,se,sw,ne,nw"),t=this.handles.split(","),this.handles={};for(n=0;n"),i.css({zIndex:u.zIndex}),"se"===r&&i.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[r]=".ui-resizable-"+r,this.element.append(i)}this._renderAxis=function(t){var n,r,i,s;t=t||this.element;for(n in this.handles){this.handles[n].constructor===String&&(this.handles[n]=e(this.handles[n],this.element).show()),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)&&(r=e(this.handles[n],this.element),s=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth(),i=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize());if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){o.resizing||(this.className&&(i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),o.axis=i&&i[1]?i[1]:"se")}),u.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(u.disabled)return;e(this).removeClass("ui-resizable-autohide"),o._handles.show()}).mouseleave(function(){if(u.disabled)return;o.resizing||(e(this).addClass("ui-resizable-autohide"),o._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t,n=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(n(this.element),t=this.element,this.originalElement.css({position:t.css("position"),width:t.outerWidth(),height:t.outerHeight(),top:t.css("top"),left:t.css("left")}).insertAfter(t),t.remove()),this.originalElement.css("resize",this.originalResizeStyle),n(this.originalElement),this},_mouseCapture:function(t){var n,r,i=!1;for(n in this.handles){r=e(this.handles[n])[0];if(r===t.target||e.contains(r,t.target))i=!0}return!this.options.disabled&&i},_mouseStart:function(t){var r,i,s,o=this.options,u=this.element.position(),a=this.element;return this.resizing=!0,/absolute/.test(a.css("position"))?a.css({position:"absolute",top:a.css("top"),left:a.css("left")}):a.is(".ui-draggable")&&a.css({position:"absolute",top:u.top,left:u.left}),this._renderProxy(),r=n(this.helper.css("left")),i=n(this.helper.css("top")),o.containment&&(r+=e(o.containment).scrollLeft()||0,i+=e(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:r,top:i},this.size=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.originalPosition={left:r,top:i},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof o.aspectRatio=="number"?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=e(".ui-resizable-"+this.axis).css("cursor"),e("body").css("cursor",s==="auto"?this.axis+"-resize":s),a.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var n,r=this.helper,i={},s=this.originalMousePosition,o=this.axis,u=this.position.top,a=this.position.left,f=this.size.width,l=this.size.height,c=t.pageX-s.left||0,h=t.pageY-s.top||0,p=this._change[o];if(!p)return!1;n=p.apply(this,[t,c,h]),this._updateVirtualBoundaries(t.shiftKey);if(this._aspectRatio||t.shiftKey)n=this._updateRatio(n,t);return n=this._respectSize(n,t),this._updateCache(n),this._propagate("resize",t),this.position.top!==u&&(i.top=this.position.top+"px"),this.position.left!==a&&(i.left=this.position.left+"px"),this.size.width!==f&&(i.width=this.size.width+"px"),this.size.height!==l&&(i.height=this.size.height+"px"),r.css(i),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),e.isEmptyObject(i)||this._trigger("resize",t,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n,r,i,s,o,u,a,f=this.options,l=this;return this._helper&&(n=this._proportionallyResizeElements,r=n.length&&/textarea/i.test(n[0].nodeName),i=r&&e.ui.hasScroll(n[0],"left")?0:l.sizeDiff.height,s=r?0:l.sizeDiff.width,o={width:l.helper.width()-s,height:l.helper.height()-i},u=parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left)||null,a=parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top)||null,f.animate||this.element.css(e.extend(o,{top:a,left:u})),l.helper.height(l.size.height),l.helper.width(l.size.width),this._helper&&!f.animate&&this._proportionallyResize()),e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t,n,i,s,o,u=this.options;o={minWidth:r(u.minWidth)?u.minWidth:0,maxWidth:r(u.maxWidth)?u.maxWidth:Infinity,minHeight:r(u.minHeight)?u.minHeight:0,maxHeight:r(u.maxHeight)?u.maxHeight:Infinity};if(this._aspectRatio||e)t=o.minHeight*this.aspectRatio,i=o.minWidth/this.aspectRatio,n=o.maxHeight*this.aspectRatio,s=o.maxWidth/this.aspectRatio,t>o.minWidth&&(o.minWidth=t),i>o.minHeight&&(o.minHeight=i),ne.width,u=r(e.height)&&t.minHeight&&t.minHeight>e.height,a=this.originalPosition.left+this.originalSize.width,f=this.position.top+this.size.height,l=/sw|nw|w/.test(n),c=/nw|ne|n/.test(n);return o&&(e.width=t.minWidth),u&&(e.height=t.minHeight),i&&(e.width=t.maxWidth),s&&(e.height=t.maxHeight),o&&l&&(e.left=a-t.minWidth),i&&l&&(e.left=a-t.maxWidth),u&&c&&(e.top=f-t.minHeight),s&&c&&(e.top=f-t.maxHeight),!e.width&&!e.height&&!e.left&&e.top?e.top=null:!e.width&&!e.height&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){if(!this._proportionallyResizeElements.length)return;var e,t,n,r,i,s=this.helper||this.element;for(e=0;e"),this.helper.addClass(this._helper).css({width:this.element.outerWidth()-1,height:this.element.outerHeight()-1,position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(e,t){return{width:this.originalSize.width+t}},w:function(e,t){var n=this.originalSize,r=this.originalPosition;return{left:r.left+t,width:n.width-t}},n:function(e,t,n){var r=this.originalSize,i=this.originalPosition;return{top:i.top+n,height:r.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!=="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","animate",{stop:function(t){var n=e(this).data("ui-resizable"),r=n.options,i=n._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:n.sizeDiff.height,u=s?0:n.sizeDiff.width,a={width:n.size.width-u,height:n.size.height-o},f=parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left)||null,l=parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top)||null;n.element.animate(e.extend(a,l&&f?{top:l,left:f}:{}),{duration:r.animateDuration,easing:r.animateEasing,step:function(){var r={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};i&&i.length&&e(i[0]).css({width:r.width,height:r.height}),n._updateCache(r),n._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(){var t,r,i,s,o,u,a,f=e(this).data("ui-resizable"),l=f.options,c=f.element,h=l.containment,p=h instanceof e?h.get(0):/parent/.test(h)?c.parent().get(0):h;if(!p)return;f.containerElement=e(p),/document/.test(h)||h===document?(f.containerOffset={left:0,top:0},f.containerPosition={left:0,top:0},f.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}):(t=e(p),r=[],e(["Top","Right","Left","Bottom"]).each(function(e,i){r[e]=n(t.css("padding"+i))}),f.containerOffset=t.offset(),f.containerPosition=t.position(),f.containerSize={height:t.innerHeight()-r[3],width:t.innerWidth()-r[1]},i=f.containerOffset,s=f.containerSize.height,o=f.containerSize.width,u=e.ui.hasScroll(p,"left")?p.scrollWidth:o,a=e.ui.hasScroll(p)?p.scrollHeight:s,f.parentData={element:p,left:i.left,top:i.top,width:u,height:a})},resize:function(t){var n,r,i,s,o=e(this).data("ui-resizable"),u=o.options,a=o.containerOffset,f=o.position,l=o._aspectRatio||t.shiftKey,c={top:0,left:0},h=o.containerElement;h[0]!==document&&/static/.test(h.css("position"))&&(c=a),f.left<(o._helper?a.left:0)&&(o.size.width=o.size.width+(o._helper?o.position.left-a.left:o.position.left-c.left),l&&(o.size.height=o.size.width/o.aspectRatio),o.position.left=u.helper?a.left:0),f.top<(o._helper?a.top:0)&&(o.size.height=o.size.height+(o._helper?o.position.top-a.top:o.position.top),l&&(o.size.width=o.size.height*o.aspectRatio),o.position.top=o._helper?a.top:0),o.offset.left=o.parentData.left+o.position.left,o.offset.top=o.parentData.top+o.position.top,n=Math.abs((o._helper?o.offset.left-c.left:o.offset.left-c.left)+o.sizeDiff.width),r=Math.abs((o._helper?o.offset.top-c.top:o.offset.top-a.top)+o.sizeDiff.height),i=o.containerElement.get(0)===o.element.parent().get(0),s=/relative|absolute/.test(o.containerElement.css("position")),i&&s&&(n-=o.parentData.left),n+o.size.width>=o.parentData.width&&(o.size.width=o.parentData.width-n,l&&(o.size.height=o.size.width/o.aspectRatio)),r+o.size.height>=o.parentData.height&&(o.size.height=o.parentData.height-r,l&&(o.size.width=o.size.height*o.aspectRatio))},stop:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.containerOffset,i=t.containerPosition,s=t.containerElement,o=e(t.helper),u=o.offset(),a=o.outerWidth()-t.sizeDiff.width,f=o.outerHeight()-t.sizeDiff.height;t._helper&&!n.animate&&/relative/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f}),t._helper&&!n.animate&&/static/.test(s.css("position"))&&e(this).css({left:u.left-i.left-r.left,width:a,height:f})}}),e.ui.plugin.add("resizable","alsoResize",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=function(t){e(t).each(function(){var t=e(this);t.data("ui-resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof n.alsoResize=="object"&&!n.alsoResize.parentNode?n.alsoResize.length?(n.alsoResize=n.alsoResize[0],r(n.alsoResize)):e.each(n.alsoResize,function(e){r(e)}):r(n.alsoResize)},resize:function(t,n){var r=e(this).data("ui-resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("ui-resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","ghost",{start:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:r.height,width:r.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof n.ghost=="string"?n.ghost:""),t.ghost.appendTo(t.helper)},resize:function(){var t=e(this).data("ui-resizable");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=e(this).data("ui-resizable");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(){var t=e(this).data("ui-resizable"),n=t.options,r=t.size,i=t.originalSize,s=t.originalPosition,o=t.axis,u=typeof n.grid=="number"?[n.grid,n.grid]:n.grid,a=u[0]||1,f=u[1]||1,l=Math.round((r.width-i.width)/a)*a,c=Math.round((r.height-i.height)/f)*f,h=i.width+l,p=i.height+c,d=n.maxWidth&&n.maxWidthh,g=n.minHeight&&n.minHeight>p;n.grid=u,m&&(h+=a),g&&(p+=f),d&&(h-=a),v&&(p-=f),/^(se|s|e)$/.test(o)?(t.size.width=h,t.size.height=p):/^(ne)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.top=s.top-c):/^(sw)$/.test(o)?(t.size.width=h,t.size.height=p,t.position.left=s.left-l):(t.size.width=h,t.size.height=p,t.position.top=s.top-c,t.position.left=s.left-l)}})}(jQuery),function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.10.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var t,n=this;this.element.addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){t=e(n.options.filter,n.element[0]),t.addClass("ui-selectee"),t.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=t.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
    ")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this,r=this.options;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.pageX,top:t.pageY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().addBack().each(function(){var r,i=e.data(this,"selectable-item");if(i)return r=!t.metaKey&&!t.ctrlKey||!i.$element.hasClass("ui-selected"),i.$element.removeClass(r?"ui-unselecting":"ui-selected").addClass(r?"ui-selecting":"ui-unselecting"),i.unselecting=!r,i.selecting=r,i.selected=r,r?n._trigger("selecting",t,{selecting:i.element}):n._trigger("unselecting",t,{unselecting:i.element}),!1})},_mouseDrag:function(t){this.dragged=!0;if(this.options.disabled)return;var n,r=this,i=this.options,s=this.opos[0],o=this.opos[1],u=t.pageX,a=t.pageY;return s>u&&(n=u,u=s,s=n),o>a&&(n=a,a=o,o=n),this.helper.css({left:s,top:o,width:u-s,height:a-o}),this.selectees.each(function(){var n=e.data(this,"selectable-item"),f=!1;if(!n||n.element===r.element[0])return;i.tolerance==="touch"?f=!(n.left>u||n.righta||n.bottoms&&n.righto&&n.bottomt&&e *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=null,i=!1,s=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type==="static")return!1;this._refreshItems(t),e(t.target).parents().each(function(){if(e.data(this,s.widgetName+"-item")===s)return r=e(this),!1}),e.data(t.target,s.widgetName+"-item")===s&&(r=e(t.target));if(!r)return!1;if(this.options.handle&&!n){e(this.options.handle,r).find("*").addBack().each(function(){this===t.target&&(i=!0)});if(!i)return!1}return this.currentItem=r,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i,s=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,s.cursorAt&&this._adjustOffsetFromHelper(s.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),s.containment&&this._setContainment(),s.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",s.cursor)),s.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",s.opacity)),s.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",s.zIndex)),this.scrollParent[0]!==document&&this.scrollParent[0].tagName!=="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(i=this.containers.length-1;i>=0;i--)this.containers[i]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!s.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var n,r,i,s,o=this.options,u=!1;this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&this.scrollParent[0].tagName!=="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;n--){r=this.items[n],i=r.item[0],s=this._intersectsWithPointer(r);if(!s)continue;if(r.instance!==this.currentContainer)continue;if(i!==this.currentItem[0]&&this.placeholder[s===1?"next":"prev"]()[0]!==i&&!e.contains(this.placeholder[0],i)&&(this.options.type==="semi-dynamic"?!e.contains(this.element[0],i):!0)){this.direction=s===1?"down":"up";if(this.options.tolerance!=="pointer"&&!this._intersectsWithSides(r))break;this._rearrange(t,r),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper==="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!=="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!==0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n,r,i,s,o=[],u=[],a=this._connectWith();if(a&&t)for(n=a.length-1;n>=0;n--){i=e(a[n]);for(r=i.length-1;r>=0;r--)s=e.data(i[r],this.widgetFullName),s&&s!==this&&!s.options.disabled&&u.push([e.isFunction(s.options.items)?s.options.items.call(s.element):e(s.options.items,s.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),s])}u.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(n=u.length-1;n>=0;n--)u[n][0].each(function(){o.push(this)});return e(o)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n=0;n--){i=e(h[n]);for(r=i.length-1;r>=0;r--)s=e.data(i[r],this.widgetFullName),s&&s!==this&&!s.options.disabled&&(c.push([e.isFunction(s.options.items)?s.options.items.call(s.element[0],t,{item:this.currentItem}):e(s.options.items,s.element),s]),this.containers.push(s))}for(n=c.length-1;n>=0;n--){o=c[n][1],u=c[n][0];for(r=0,f=u.length;r=0;n--){r=this.items[n];if(r.instance!==this.currentContainer&&this.currentContainer&&r.item[0]!==this.currentItem[0])continue;i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item,t||(r.width=i.outerWidth(),r.height=i.outerHeight()),s=i.offset(),r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(n=this.containers.length-1;n>=0;n--)s=this.containers[n].element.offset(),this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var n,r=t.options;if(!r.placeholder||r.placeholder.constructor===String)n=r.placeholder,r.placeholder={element:function(){var r=e(document.createElement(t.currentItem[0].nodeName)).addClass(n||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return n||(r.style.visibility="hidden"),r},update:function(e,i){if(n&&!r.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}};t.placeholder=e(r.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),r.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n,r,i,s,o,u,a,f,l,c=null,h=null;for(n=this.containers.length-1;n>=0;n--){if(e.contains(this.currentItem[0],this.containers[n].element[0]))continue;if(this._intersectsWith(this.containers[n].containerCache)){if(c&&e.contains(this.containers[n].element[0],c.element[0]))continue;c=this.containers[n],h=n}else this.containers[n].containerCache.over&&(this.containers[n]._trigger("out",t,this._uiHash(this)),this.containers[n].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[h]._trigger("over",t,this._uiHash(this)),this.containers[h].containerCache.over=1;else{i=1e4,s=null,o=this.containers[h].floating?"left":"top",u=this.containers[h].floating?"width":"height",a=this.positionAbs[o]+this.offset.click[o];for(r=this.items.length-1;r>=0;r--){if(!e.contains(this.containers[h].element[0],this.items[r].item[0]))continue;if(this.items[r].item[0]===this.currentItem[0])continue;f=this.items[r].item.offset()[o],l=!1,Math.abs(f-a)>Math.abs(f+this.items[r][u]-a)&&(l=!0,f+=this.items[r][u]),Math.abs(f-a)this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top)),i.grid&&(n=this.originalPageY+Math.round((o-this.originalPageY)/i.grid[1])*i.grid[1],o=this.containment?n-this.offset.click.top>=this.containment[1]&&n-this.offset.click.top<=this.containment[3]?n:n-this.offset.click.top>=this.containment[1]?n-i.grid[1]:n+i.grid[1]:n,r=this.originalPageX+Math.round((s-this.originalPageX)/i.grid[0])*i.grid[0],s=this.containment?r-this.offset.click.left>=this.containment[0]&&r-this.offset.click.left<=this.containment[2]?r:r-this.offset.click.left>=this.containment[0]?r-i.grid[0]:r+i.grid[0]:r)),{top:o-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(this.cssPosition==="fixed"?-this.scrollParent.scrollTop():a?0:u.scrollTop()),left:s-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(this.cssPosition==="fixed"?-this.scrollParent.scrollLeft():a?0:u.scrollLeft())}},_rearrange:function(e,t,n,r){n?n[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],this.direction==="down"?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var i=this.counter;this._delay(function(){i===this.counter&&this.refreshPositions(!r)})},_clear:function(t,n){this.reverting=!1;var r,i=[];!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null;if(this.helper[0]===this.currentItem[0]){for(r in this._storedCSS)if(this._storedCSS[r]==="auto"||this._storedCSS[r]==="static")this._storedCSS[r]="";this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();this.fromOutside&&!n&&i.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),(this.fromOutside||this.domPosition.prev!==this.currentItem.prev().not(".ui-sortable-helper")[0]||this.domPosition.parent!==this.currentItem.parent()[0])&&!n&&i.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(n||(i.push(function(e){this._trigger("remove",e,this._uiHash())}),i.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),i.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer))));for(r=this.containers.length-1;r>=0;r--)n||i.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[r])),this.containers[r].containerCache.over&&(i.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[r])),this.containers[r].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex==="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(r=0;re?0:r.max")[0],l,c=e.each;f.style.cssText="background-color:rgba(1,1,1,.5)",a.rgba=f.style.backgroundColor.indexOf("rgba")>-1,c(o,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),s.fn=e.extend(s.prototype,{parse:function(n,r,i,u){if(n===t)return this._rgba=[null,null,null,null],this;if(n.jquery||n.nodeType)n=e(n).css(r),r=t;var a=this,f=e.type(n),d=this._rgba=[];r!==t&&(n=[n,r,i,u],f="array");if(f==="string")return this.parse(p(n)||l._default);if(f==="array")return c(o.rgba.props,function(e,t){d[t.idx]=h(n[t.idx],t)}),this;if(f==="object")return n instanceof s?c(o,function(e,t){n[t.cache]&&(a[t.cache]=n[t.cache].slice())}):c(o,function(t,r){var i=r.cache;c(r.props,function(e,t){if(!a[i]&&r.to){if(e==="alpha"||n[e]==null)return;a[i]=r.to(a._rgba)}a[i][t.idx]=h(n[e],t,!0)}),a[i]&&e.inArray(null,a[i].slice(0,3))<0&&(a[i][3]=1,r.from&&(a._rgba=r.from(a[i])))}),this},is:function(e){var t=s(e),n=!0,r=this;return c(o,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],c(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return c(o,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=s(e),r=n._space(),i=o[r],a=this.alpha()===0?s("transparent"):this,f=a[i.cache]||i.to(a._rgba),l=f.slice();return n=n[i.cache],c(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],a=u[r.type]||{};if(o===null)return;s===null?l[i]=o:(a.mod&&(o-s>a.mod/2?s+=a.mod:s-o>a.mod/2&&(s-=a.mod)),l[i]=h((o-s)*t+s,r))}),this[r](l)},blend:function(t){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=s(t)._rgba;return s(e.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var t="rgba(",n=e.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),t="rgb("),t+n.join()+")"},toHslaString:function(){var t="hsla(",n=e.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),t="hsl("),t+n.join()+")"},toHexString:function(t){var n=this._rgba.slice(),r=n.pop();return t&&n.push(~~(r*255)),"#"+e.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),s.fn.parse.prototype=s.fn,o.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,u===0?c=0:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},o.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(d(o,s,t+1/3)*255),Math.round(d(o,s,t)*255),Math.round(d(o,s,t-1/3)*255),i]},c(o,function(n,i){var o=i.props,u=i.cache,a=i.to,f=i.from;s.fn[n]=function(n){a&&!this[u]&&(this[u]=a(this._rgba));if(n===t)return this[u].slice();var r,i=e.type(n),l=i==="array"||i==="object"?n:arguments,p=this[u].slice();return c(o,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=p[t.idx]),p[t.idx]=h(n,t)}),f?(r=s(f(p)),r[u]=p,r):s(p)},c(o,function(t,i){if(s.fn[t])return;s.fn[t]=function(s){var o=e.type(s),u=t==="alpha"?this._hsla?"hsla":"rgba":n,a=this[u](),f=a[i.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=e.type(s)),s==null&&i.empty?this:(o==="string"&&(l=r.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[i.idx]=s,this[u](a)))}})}),s.hook=function(t){var n=t.split(" ");c(n,function(t,n){e.cssHooks[n]={set:function(t,r){var i,o,u="";if(r!=="transparent"&&(e.type(r)!=="string"||(i=p(r)))){r=s(i||r);if(!a.rgba&&r._rgba[3]!==1){o=n==="backgroundColor"?t.parentNode:t;while((u===""||u==="transparent")&&o&&o.style)try{u=e.css(o,"backgroundColor"),o=o.parentNode}catch(f){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{t.style[n]=r}catch(f){}}},e.fx.step[n]=function(t){t.colorInit||(t.start=s(t.elem,n),t.end=s(t.end),t.colorInit=!0),e.cssHooks[n].set(t.elem,t.start.transition(t.end,t.pos))}})},s.hook(n),e.cssHooks.borderColor={expand:function(e){var t={};return c(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},l=e.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(t){var n,r,i=t.ownerDocument.defaultView?t.ownerDocument.defaultView.getComputedStyle(t,null):t.currentStyle,s={};if(i&&i.length&&i[0]&&i[i[0]]){r=i.length;while(r--)n=i[r],typeof i[n]=="string"&&(s[e.camelCase(n)]=i[n])}else for(n in i)typeof i[n]=="string"&&(s[n]=i[n]);return s}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").addBack():r;f=f.map(function(){var t=e(this);return{el:t,start:i(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=e.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return arguments.length>1?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass.apply(this,arguments)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function r(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function i(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]}e.extend(e.effects,{version:"1.10.1",save:function(e,t){for(var r=0;r").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function o(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,o=t.mode;(r.is(":hidden")?o==="hide":o==="show")?u():s.call(r[0],t,u)}var t=r.apply(this,arguments),n=t.mode,i=t.queue,s=e.effects.effect[t.effect];return e.fx.off||!s?n?this[n](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):i===!1?this.each(o):this.queue(i||"fx",o)},_show:e.fn.show,show:function(e){if(i(e))return this._show.apply(this,arguments);var t=r.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(i(e))return this._hide.apply(this,arguments);var t=r.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(i(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=r.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery),function(e,t){var n=0,r={},i={};r.height=r.paddingTop=r.paddingBottom=r.borderTopWidth=r.borderBottomWidth="hide",i.height=i.paddingTop=i.paddingBottom=i.borderTopWidth=i.borderBottomWidth="show",e.widget("ui.accordion",{version:"1.10.1",options:{active:0,animate:{},collapsible:!1,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset").attr("role","tablist"),!t.collapsible&&(t.active===!1||t.active==null)&&(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():e(),content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t=this.options;this._processPanels();if(t.active===!1&&t.collapsible===!0||!this.headers.length)t.active=!1,this.active=e();t.active===!1?this._activate(0):this.active.length&&!e.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=e()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){this.headers=this.element.find(this.options.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").filter(":not(.ui-accordion-content-active)").hide()},_refresh:function(){var t,r=this.options,i=r.heightStyle,s=this.element.parent(),o=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n);this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active ui-corner-top").removeClass("ui-corner-all"),this.active.next().addClass("ui-accordion-content-active").show(),this.headers.attr("role","tab").each(function(t){var n=e(this),r=n.attr("id"),i=n.next(),s=i.attr("id");r||(r=o+"-header-"+t,n.attr("id",r)),s||(s=o+"-panel-"+t,i.attr("id",s)),n.attr("aria-controls",s),i.attr("aria-labelledby",r)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(r.event),i==="fill"?(t=s.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):i==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={keydown:"_keydown"};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,n),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r,i=this.element[0].nodeName.toLowerCase(),s=i==="textarea",o=i==="input";this.isMultiLine=s?!0:o?!1:this.element.prop("isContentEditable"),this.valueMethod=this.element[s||o?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("
    "+"",L=c?"":"";for(E=0;E<7;E++)A=(E+l)%7,L+="=5?" class='ui-datepicker-week-end'":"")+">"+""+p[A]+"";k+=L+"",O=this._getDaysInMonth(et,Z),et===e.selectedYear&&Z===e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,O)),M=(this._getFirstDayOfMonth(et,Z)-l+7)%7,_=Math.ceil((M+O)/7),D=K?this.maxRows>_?this.maxRows:_:_,this.maxRows=D,P=this._daylightSavingAdjust(new Date(et,Z,1-M));for(H=0;H",B=c?"":"";for(E=0;E<7;E++)j=m?m.apply(e.input?e.input[0]:null,[P]):[!0,""],F=P.getMonth()!==Z,I=F&&!y||!j[0]||G&&PY,B+="",P.setDate(P.getDate()+1),P=this._daylightSavingAdjust(P);k+=B+""}Z++,Z>11&&(Z=0,et++),k+="
    "+this._get(e,"weekHeader")+"
    "+this._get(e,"calculateWeek")(P)+""+(F&&!g?" ":I?""+P.getDate()+"":""+P.getDate()+"")+"
    "+(K?""+(V[0]>0&&T===V[1]-1?"
    ":""):""),x+=k}w+=x}return w+=f,e._keyEvent=!1,w},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a,f,l,c,h,p,d,v,m=this._get(e,"changeMonth"),g=this._get(e,"changeYear"),y=this._get(e,"showMonthAfterYear"),b="
    ",w="";if(s||!m)w+=""+o[t]+"";else{a=r&&r.getFullYear()===n,f=i&&i.getFullYear()===n,w+=""}y||(b+=w+(s||!m||!g?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!g)b+=""+n+"";else{c=this._get(e,"yearRange").split(":"),h=(new Date).getFullYear(),p=function(e){var t=e.match(/c[+\-].*/)?n+parseInt(e.substring(1),10):e.match(/[+\-].*/)?h+parseInt(e,10):parseInt(e,10);return isNaN(t)?h:t},d=p(c[0]),v=Math.max(d,p(c[1]||"")),d=r?Math.max(d,r.getFullYear()):d,v=i?Math.min(v,i.getFullYear()):v,e.yearshtml+="",b+=e.yearshtml,e.yearshtml=null}}return b+=this._get(e,"yearSuffix"),y&&(b+=(s||!m||!g?" ":"")+w),b+="
    ",b},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n==="Y"?t:0),i=e.drawMonth+(n==="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n==="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n==="M"||n==="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n,r,i=this._getMinMaxDate(e,"min"),s=this._getMinMaxDate(e,"max"),o=null,u=null,a=this._get(e,"yearRange");return a&&(n=a.split(":"),r=(new Date).getFullYear(),o=parseInt(n[0],10),u=parseInt(n[1],10),n[0].match(/[+\-].*/)&&(o+=r),n[1].match(/[+\-].*/)&&(u+=r)),(!i||t.getTime()>=i.getTime())&&(!s||t.getTime()<=s.getTime())&&(!o||t.getFullYear()>=o)&&(!u||t.getFullYear()<=u)},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),e.fn.datepicker=function(t){if(!this.length)return this;e.datepicker.initialized||(e(document).mousedown(e.datepicker._checkExternalClick),e.datepicker.initialized=!0),e("#"+e.datepicker._mainDivId).length===0&&e("body").append(e.datepicker.dpDiv);var n=Array.prototype.slice.call(arguments,1);return typeof t!="string"||t!=="isDisabled"&&t!=="getDate"&&t!=="widget"?t==="option"&&arguments.length===2&&typeof arguments[1]=="string"?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(n)):this.each(function(){typeof t=="string"?e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this].concat(n)):e.datepicker._attachDatepicker(this,t)}):e.datepicker["_"+t+"Datepicker"].apply(e.datepicker,[this[0]].concat(n))},e.datepicker=new s,e.datepicker.initialized=!1,e.datepicker.uuid=(new Date).getTime(),e.datepicker.version="1.10.1",window["DP_jQuery_"+r]=e}(jQuery),function(e,t){var n={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},r={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.10.1",options:{appendTo:"body",autoOpen:!0,buttons:[],closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),this.options.title=this.options.title||this.originalTitle,this._createWrapper(),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(this.uiDialog),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&e.fn.draggable&&this._makeDraggable(),this.options.resizable&&e.fn.resizable&&this._makeResizable(),this._isOpen=!1},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var t=this.options.appendTo;return t&&(t.jquery||t.nodeType)?e(t):this.document.find(t||"body").eq(0)},_destroy:function(){var e,t=this.originalPosition;this._destroyOverlay(),this.element.removeUniqueId().removeClass("ui-dialog-content ui-widget-content").css(this.originalCss).detach(),this.uiDialog.stop(!0,!0).remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},disable:e.noop,enable:e.noop,close:function(t){var n=this;if(!this._isOpen||this._trigger("beforeClose",t)===!1)return;this._isOpen=!1,this._destroyOverlay(),this.opener.filter(":focusable").focus().length||e(this.document[0].activeElement).blur(),this._hide(this.uiDialog,this.options.hide,function(){n._trigger("close",t)})},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,t){var n=!!this.uiDialog.nextAll(":visible").insertBefore(this.uiDialog).length;return n&&!t&&this._trigger("focus",e),n},open:function(){var t=this;if(this._isOpen){this._moveToTop()&&this._focusTabbable();return}this._isOpen=!0,this.opener=e(this.document[0].activeElement),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this._show(this.uiDialog,this.options.show,function(){t._focusTabbable(),t._trigger("focus")}),this._trigger("open")},_focusTabbable:function(){var e=this.element.find("[autofocus]");e.length||(e=this.element.find(":tabbable")),e.length||(e=this.uiDialogButtonPane.find(":tabbable")),e.length||(e=this.uiDialogTitlebarClose.filter(":tabbable")),e.length||(e=this.uiDialog),e.eq(0).focus()},_keepFocus:function(t){function n(){var t=this.document[0].activeElement,n=this.uiDialog[0]===t||e.contains(this.uiDialog[0],t);n||this._focusTabbable()}t.preventDefault(),n.call(this),this._delay(n)},_createWrapper:function(){this.uiDialog=e("
    '; + +// 상단 HTML +echo '
    '.conv_content($fm['fm_head_html'], 1).'
    '; +?> + + + + + +
    + +
    +

    목록

    +
      + $v){ + if(empty($v)) + continue; + ?> +
    1. +

      +
      + +
      +
      +
    2. + +
    +
    + 검색된 게시물이 없습니다.

    '; + } else { + echo '
    등록된 FAQ가 없습니다.'; + if($is_admin) + echo '
    FAQ를 새로 등록하시려면 FAQ관리 메뉴를 이용하십시오.'; + echo '
    '; + } + } + ?> +
    + + + +'.conv_content($fm['fm_tail_html'], 1).''; + +if ($timg_src) + echo '
    '; +?> + +
    + FAQ 검색 + +
    + + + + +
    +
    + + +FAQ 수정'; +?> + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/faq/basic/style.css b/AvocadoEdition/skin/faq/basic/style.css new file mode 100644 index 0000000..e64b833 --- /dev/null +++ b/AvocadoEdition/skin/faq/basic/style.css @@ -0,0 +1,23 @@ +@charset "utf-8"; + +#bo_cate h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_cate ul {margin-bottom:10px;padding-left:1px;zoom:1} +#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_cate li {float:left;margin-bottom:-1px} +#bo_cate a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:90px;border:1px solid #ddd;background:#f7f7f7;color:#888;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} +#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none} +#bo_cate #bo_cate_on {z-index:2;border:1px solid #565e60;background:#fff;color:#565e60;font-weight:bold} + +#faq_wrap {margin:10px 0 30px} +#faq_wrap h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +.faq_admin {text-align:right} +#faq_wrap ol {margin:0;padding:0;list-style:none} +#faq_con {border:1px solid #e9e9e9;border-top:0} +#faq_con h3 a {display:block;padding:10px;border-top:1px solid #e9e9e9;background:#f2f5f9;text-decoration:none} +#faq_con .con_inner {display:none;padding:10px;line-height:1.8em} +#faq_con .con_closer {margin:10px 0 0;text-align:right} +#faq_con .closer_btn {margin:0;padding:0;border:0;background:transparent} +.faq_tolist {padding:0 10px;text-align:right} +.faq_img {text-align:center} + +#faq_sch {text-align:center} \ No newline at end of file diff --git a/AvocadoEdition/skin/latest/basic/img/icon_file.gif b/AvocadoEdition/skin/latest/basic/img/icon_file.gif new file mode 100644 index 0000000000000000000000000000000000000000..cca47f566ac0db655fb2ab0f56628b64958e48b2 GIT binary patch literal 107 zcmZ?wbhEHb-Wqsc#^P~2x#@rVooH@5wHB9i@BozKb;P9uI^*c|UyXO5@>VyLmgEat< Cr6(f* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/img/icon_hot.gif b/AvocadoEdition/skin/latest/basic/img/icon_hot.gif new file mode 100644 index 0000000000000000000000000000000000000000..c95b839aeef0c1e26a4bab4ea50cd6d3f1969d7f GIT binary patch literal 97 zcmZ?wbhEHbzHen|7VvwFnzUPlarEA ZqW~YXyUO~T+#YkUoJ%V_>ib05Q5F AasU7T literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/img/icon_mobile.gif b/AvocadoEdition/skin/latest/basic/img/icon_mobile.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad934d23c440c83db0c4589596465cb087353e01 GIT binary patch literal 62 zcmZ?wbhEHbI6zOJt}3$`6RT1g06226*Z@+ongb7@ XU=fBkjtXNz0xpR_!)cQgkRbp&KI&WI literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/img/icon_movie.gif b/AvocadoEdition/skin/latest/basic/img/icon_movie.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb958f83f9c606f290a260714cd9a3cff043f3a2 GIT binary patch literal 110 zcmZ?wbhEHbZ% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/img/icon_reply.gif b/AvocadoEdition/skin/latest/basic/img/icon_reply.gif new file mode 100644 index 0000000000000000000000000000000000000000..91c135977b4f445a90c849310dc80efde1983830 GIT binary patch literal 77 zcmZ?wbhEHb&!1E4^4&ClEzh)PmWxV3{9A~!gB2-%RL5bHcgg3Zp^!+W)H2^A_AxQuL literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/img/icon_sound.gif b/AvocadoEdition/skin/latest/basic/img/icon_sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5188318a5cdc394b984125c0ddd376c5f57bbe4 GIT binary patch literal 113 zcmZ?wbhEHbE1CJY$zMikVi`-#gIi|DbmsXBWf6U5szE@->A`0*`&<;b@XASRrB8=E6~=S>Pbm I%fes{0AXt-SpWb4 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/latest/basic/latest.skin.php b/AvocadoEdition/skin/latest/basic/latest.skin.php new file mode 100644 index 0000000..989a3ee --- /dev/null +++ b/AvocadoEdition/skin/latest/basic/latest.skin.php @@ -0,0 +1,44 @@ +', 0); +?> + + +
    + +
      + +
    • + "; + if ($list[$i]['is_notice']) + echo "".$list[$i]['subject'].""; + else + echo $list[$i]['subject']; + + if ($list[$i]['comment_cnt']) + echo $list[$i]['comment_cnt']; + + echo ""; + + // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } + // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } + + if (isset($list[$i]['icon_new'])) echo " " . $list[$i]['icon_new']; + if (isset($list[$i]['icon_hot'])) echo " " . $list[$i]['icon_hot']; + if (isset($list[$i]['icon_file'])) echo " " . $list[$i]['icon_file']; + if (isset($list[$i]['icon_link'])) echo " " . $list[$i]['icon_link']; + if (isset($list[$i]['icon_secret'])) echo " " . $list[$i]['icon_secret']; + ?> +
    • + + +
    • 게시물이 없습니다.
    • + +
    + +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/latest/basic/style.css b/AvocadoEdition/skin/latest/basic/style.css new file mode 100644 index 0000000..096900e --- /dev/null +++ b/AvocadoEdition/skin/latest/basic/style.css @@ -0,0 +1,11 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 새글 스킨 (latest) */ +.lt_pc {float:left;margin-left:20px} +.lt {position:relative;float:left;margin-bottom:20px;padding-bottom:10px;width:354px;height:150px;border-bottom:1px solid #e9e9e9} +.lt ul {margin:0 0 10px;padding:0;list-style:none} +.lt li {padding:3px 0} +.lt .lt_title {display:block;padding:10px 0 8px} +.lt .lt_more {position:absolute;top:10px;right:0} +.lt .cnt_cmt {display:inline-block;margin:0 0 0 3px;font-weight:bold} \ No newline at end of file diff --git a/AvocadoEdition/skin/latest/rolling/latest.skin.php b/AvocadoEdition/skin/latest/rolling/latest.skin.php new file mode 100644 index 0000000..6260406 --- /dev/null +++ b/AvocadoEdition/skin/latest/rolling/latest.skin.php @@ -0,0 +1,43 @@ +', 0); +?> + +
    +
    NOTICE :
    +
    +
      + +
    • + "; + if ($list[$i]['is_notice']) + echo "".$list[$i]['subject'].""; + else + echo $list[$i]['subject']; + + if ($list[$i]['comment_cnt']) + echo $list[$i]['comment_cnt']; + + echo ""; + + // if ($list[$i]['link']['count']) { echo "[{$list[$i]['link']['count']}]"; } + // if ($list[$i]['file']['count']) { echo "<{$list[$i]['file']['count']}>"; } + + if (isset($list[$i]['icon_new'])) echo " " . $list[$i]['icon_new']; + if (isset($list[$i]['icon_hot'])) echo " " . $list[$i]['icon_hot']; + if (isset($list[$i]['icon_file'])) echo " " . $list[$i]['icon_file']; + if (isset($list[$i]['icon_link'])) echo " " . $list[$i]['icon_link']; + if (isset($list[$i]['icon_secret'])) echo " " . $list[$i]['icon_secret']; + ?> +
    • + + +
    • Comming Soon...
    • + +
    +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/latest/rolling/style.css b/AvocadoEdition/skin/latest/rolling/style.css new file mode 100644 index 0000000..e01df22 --- /dev/null +++ b/AvocadoEdition/skin/latest/rolling/style.css @@ -0,0 +1,10 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +.rolling-latest { position: relative; padding-left: 50px; } +.rolling-latest .title { + position: absolute; + top: 0; + left: 0; + bottom: 0; +} \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/formmail.skin.php b/AvocadoEdition/skin/member/basic/formmail.skin.php new file mode 100644 index 0000000..e57be62 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/formmail.skin.php @@ -0,0 +1,100 @@ +', 0); +?> + + +
    +

    님께 메일보내기

    + +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    메일쓰기
    형식 + + + +
    + + 첨부 파일은 누락될 수 있으므로 메일을 보낸 후 파일이 첨부 되었는지 반드시 확인해 주시기 바랍니다. +
    자동등록방지
    +
    + +
    + + +
    + +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/img/bak_admin_login_top_pattern.png b/AvocadoEdition/skin/member/basic/img/bak_admin_login_top_pattern.png new file mode 100644 index 0000000000000000000000000000000000000000..98f27a745ab080a32897ba44b12e5fa0cc07ef28 GIT binary patch literal 942 zcmaJ=%Wl&^6t!rBprRj8R->tes6_18X`I-KsS-OS7IhRQk(y;4dy-hGJ;Qi{ok&O( zJGSLN_yHDO^9!ulbln9K54~_dr47$*%^4tnWy>iIIDRqe?i>2&HInZ(b4-LZ&I%Yle zkncZ* zx1*T3k%w%{fLuWg0$(?kR?||OTG^~sWw}+=nzf3im}a@9Rb;tp=3EPV^AJTW=lT!a z##U}-g^=*b7NWs>-WzIJGc^dgelp5T)4Zw P$!?I{>R4Zz7a#usM9m=6 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/member/basic/img/zip_ico_up.gif b/AvocadoEdition/skin/member/basic/img/zip_ico_up.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1eff70fa850bea122f6924d8c3cd63f1d573c53 GIT binary patch literal 54 zcmZ?wbhEHb', 0); +?> + +
    + +
    +
    +

    + + 관리자 로그인 + + + AVOCADO EDITION Ver. + + + 관리자 비번을 잊을 시, DB 접속을 통해 직접 변경 하여야 합니다.
    + 최대한 비밀번호를 잊지 않도록 조심해 주시길 바랍니다.
    + DB 관리툴은 호스팅 업체에 문의해 주시길 바랍니다. +
    +

    +
    +
    + + + +
    +
    + +
    + + +
    + + +
    +
    + + +
    + +
    + + +
    + +
    + +
    +
    + + + +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/login.skin.php b/AvocadoEdition/skin/member/basic/login.skin.php new file mode 100644 index 0000000..6cf362d --- /dev/null +++ b/AvocadoEdition/skin/member/basic/login.skin.php @@ -0,0 +1,56 @@ +', 0); + + +/*********** Logo Data ************/ +$logo = get_logo('pc'); +$m_logo = get_logo('mo'); + +$logo_data = ""; +if($logo) $logo_data .= ""; +/*********************************/ +?> + + + +
    + +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/login_check.skin.php b/AvocadoEdition/skin/member/basic/login_check.skin.php new file mode 100644 index 0000000..95608c8 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/login_check.skin.php @@ -0,0 +1,5 @@ + diff --git a/AvocadoEdition/skin/member/basic/member_confirm.skin.php b/AvocadoEdition/skin/member/basic/member_confirm.skin.php new file mode 100644 index 0000000..0b37212 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/member_confirm.skin.php @@ -0,0 +1,54 @@ +', 0); +?> + + +
    +

    비밀번호 확인

    +
    +

    + 비밀번호를 한번 더 입력해주세요. + + 비밀번호를 입력하시면 회원탈퇴가 완료됩니다. + + 회원님의 정보를 안전하게 보호하기 위해 비밀번호를 한번 더 확인합니다. + +

    + +
    + +
    + + + +
    + +
    +
    + +
    + +
    + +
    + +
    + +
    +
    + + + +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/memo.skin.php b/AvocadoEdition/skin/member/basic/memo.skin.php new file mode 100644 index 0000000..48e6e05 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/memo.skin.php @@ -0,0 +1,10 @@ +', 0); + +?> + diff --git a/AvocadoEdition/skin/member/basic/memo_form.skin.php b/AvocadoEdition/skin/member/basic/memo_form.skin.php new file mode 100644 index 0000000..013b8db --- /dev/null +++ b/AvocadoEdition/skin/member/basic/memo_form.skin.php @@ -0,0 +1,47 @@ +', 0); +?> + + +
    +
    + + + + + + + + + + + + + + + + +
    + + 여러 회원에게 보낼때는 컴마(,)로 구분하세요. +
    +
    +
    + + +
    +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/memo_view.skin.php b/AvocadoEdition/skin/member/basic/memo_view.skin.php new file mode 100644 index 0000000..28257c8 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/memo_view.skin.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/password.skin.php b/AvocadoEdition/skin/member/basic/password.skin.php new file mode 100644 index 0000000..c90013c --- /dev/null +++ b/AvocadoEdition/skin/member/basic/password.skin.php @@ -0,0 +1,62 @@ +', 0); +?> + + +
    + +

    비밀번호 확인

    + +
    +

    + + 작성자만 글을 수정할 수 있습니다. + 작성자 본인이라면, 글 작성시 입력한 비밀번호를 입력하여 글을 수정할 수 있습니다. + + 작성자만 글을 삭제할 수 있습니다. + 작성자 본인이라면, 글 작성시 입력한 비밀번호를 입력하여 글을 삭제할 수 있습니다. + + 비밀글 기능으로 보호된 글입니다. + 작성자와 관리자만 열람하실 수 있습니다. 본인이라면 비밀번호를 입력하세요. + +

    + + +
    + +
    + + + + + + + + +
    + +
    + +
    + +
    + +
    + +
    +
    + + + +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/password_lost.skin.php b/AvocadoEdition/skin/member/basic/password_lost.skin.php new file mode 100644 index 0000000..b9062ac --- /dev/null +++ b/AvocadoEdition/skin/member/basic/password_lost.skin.php @@ -0,0 +1,47 @@ +', 0); +?> + + +
    +

    회원정보 찾기

    + +
    +
    +

    + 회원가입 시 등록하신 이메일 주소를 입력해 주세요.
    + 해당 이메일로 아이디와 비밀번호 정보를 보내드립니다. +

    + + +
    + +
    + + +
    +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/point.skin.php b/AvocadoEdition/skin/member/basic/point.skin.php new file mode 100644 index 0000000..d0e754f --- /dev/null +++ b/AvocadoEdition/skin/member/basic/point.skin.php @@ -0,0 +1,88 @@ +', 0); +?> + +
    +

    + +
    + + + + + + + + + + + + + 0) { + $point1 = '+' .number_format($row['po_point']); + $sum_point1 += $row['po_point']; + } else { + $point2 = number_format($row['po_point']); + $sum_point2 += $row['po_point']; + } + + $po_content = $row['po_content']; + + $expr = ''; + if($row['po_expired'] == 1) + $expr = ' txt_expired'; + ?> + + + + + + + + '; + else { + if ($sum_point1 > 0) + $sum_point1 = "+" . number_format($sum_point1); + $sum_point2 = number_format($sum_point2); + } + ?> + + + + + + + + + + + + +
    포인트 사용내역 목록
    일시내용만료일지급포인트사용포인트
    + + 만료 + +
    자료가 없습니다.
    소계
    보유포인트
    +
    + + + +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/profile.skin.php b/AvocadoEdition/skin/member/basic/profile.skin.php new file mode 100644 index 0000000..0b0535f --- /dev/null +++ b/AvocadoEdition/skin/member/basic/profile.skin.php @@ -0,0 +1,50 @@ +', 0); +?> + + +
    +

    님의 프로필

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    회원권한
    포인트
    홈페이지
    회원가입일= $mb['mb_level']) ? substr($mb['mb_datetime'],0,10) ." (".number_format($mb_reg_after)." 일)" : "알 수 없음"; ?>
    최종접속일= $mb['mb_level']) ? $mb['mb_today_login'] : "알 수 없음"; ?>
    +
    + +
    +

    인사말

    +

    +
    + +
    + +
    +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/register.skin.php b/AvocadoEdition/skin/member/basic/register.skin.php new file mode 100644 index 0000000..8861265 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/register.skin.php @@ -0,0 +1,70 @@ +', 0); +?> + + +
    + +

    + 오너 동의 사항 + 《 Community Joining Assent 》 +

    + + + +
    +
    + +
    +

    커뮤니티 활동 규칙

    +
    + +
    +
    + + +
    +
    + +
    +

    캐릭터 유의사항

    +
    + +
    +
    + + +
    +
    + +
    + +
    + +
    + +
    + +
    + + + + diff --git a/AvocadoEdition/skin/member/basic/register_form.skin.php b/AvocadoEdition/skin/member/basic/register_form.skin.php new file mode 100644 index 0000000..25bca8d --- /dev/null +++ b/AvocadoEdition/skin/member/basic/register_form.skin.php @@ -0,0 +1,133 @@ +', 0); +?> + + + + + + + +
    + +

    + 계정 정보 + 《 Community Register Form 》 +

    + +
    +
    + + + + + + + + + + + date("Y-m-d", G5_SERVER_TIME - ($config['cf_nick_modify'] * 86400))) { // 닉네임수정일이 지나지 않았다면 ?> + + + + + + + + + + + + + + + + + + + + + + + +
    아이디 + class="frm_input " minlength="3" maxlength="20"> + +
    비밀번호 class="frm_input " minlength="3" maxlength="20">
    비밀번호 확인 class="frm_input " minlength="3" maxlength="20">
    + + + + + + + + + + + + + + + + +
    닉네임 + +
    생년 + +
    + +
    + + 취소 +
    +
    +
    +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/register_result.skin.php b/AvocadoEdition/skin/member/basic/register_result.skin.php new file mode 100644 index 0000000..af1952a --- /dev/null +++ b/AvocadoEdition/skin/member/basic/register_result.skin.php @@ -0,0 +1,39 @@ +', 0); +?> + +
    + +

    + 계정 생성 완료 + 《 Complete Community Account 》 +

    + +
    + +
    +

    정보관리 안내

    +
    +

    ""님의 가입을 진심으로 축하합니다.

    +

    회원님의 비밀번호는 아무도 알 수 없는 암호화 코드로 저장되므로 안심하셔도 좋습니다.

    +

    아이디, 비밀번호 분실시에는 총괄에게 문의해 주시길 바랍니다.

    +
    +
    + +
    +

    캐릭터 생성

    +
    +

    캐릭터 생성은 신청기간 동안 생성하실 수 있습니다.

    +

    로그인 후 [ MY PAGE > CHARACTER ] 메뉴를 통해 생성 및 수정 관리를 하실 수 있습니다.

    +

    신청기간이 끝난 뒤에 합격된 캐릭터들은 관리자 승인 후 MEMBER LIST 에 자동으로 등록됩니다.

    +
    +
    + +
    + +
    +
    +
    diff --git a/AvocadoEdition/skin/member/basic/scrap.skin.php b/AvocadoEdition/skin/member/basic/scrap.skin.php new file mode 100644 index 0000000..e890535 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/scrap.skin.php @@ -0,0 +1,46 @@ +', 0); +?> + + +
    +

    + +
    + + + + + + + + + + + + + + + + + + + + + + + "; ?> + +
    스크랩 목록
    번호게시판제목보관일시삭제
    삭제
    자료가 없습니다.
    +
    + + + +
    + +
    +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/scrap_popin.skin.php b/AvocadoEdition/skin/member/basic/scrap_popin.skin.php new file mode 100644 index 0000000..81f82a5 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/scrap_popin.skin.php @@ -0,0 +1,41 @@ +', 0); +?> + + +
    +

    스크랩하기

    + +
    + + + +
    + + + + + + + + + + + + +
    제목 확인 및 댓글 쓰기
    제목
    +
    + +

    + 스크랩을 하시면서 감사 혹은 격려의 댓글을 남기실 수 있습니다. +

    + +
    + +
    +
    +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/style.admin.css b/AvocadoEdition/skin/member/basic/style.admin.css new file mode 100644 index 0000000..73651e5 --- /dev/null +++ b/AvocadoEdition/skin/member/basic/style.admin.css @@ -0,0 +1,231 @@ +@charset "utf-8"; +@import url(//fonts.googleapis.com/earlyaccess/notosanskr.css); +@font-face { + font-family: 'icon'; + src: url('../../../css/fonts/icomoon.eot?y5isk6'); + src: url('../../../css/fonts/icomoon.eot?y5isk6#iefix') format('embedded-opentype'), + url('../../../css/fonts/icomoon.ttf?y5isk6') format('truetype'), + url('../../../css/fonts/icomoon.woff?y5isk6') format('woff'), + url('../../../css/fonts/icomoon.svg?y5isk6#icomoon') format('svg'); + font-weight: normal; + font-style: normal; +} + +html, body { position: relative; height: 100%; background: #fff; } + +#login_page_box { position: relative; height: 100%; } +#login_page_box:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + box-sizing: border-box; + border-top: 8px solid #29c7ca; + background: url('./img/bak_admin_login_top_pattern.png'); + z-index: 0; +} +#login_page_box:after { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + + background: rgba(0,0,0,0); + background: -moz-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%); + background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(0,0,0,0)), color-stop(65%, rgba(0,0,0,0)), color-stop(100%, rgba(0,0,0,0.5))); + background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%); + background: -o-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%); + background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%); + background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0) 65%, rgba(0,0,0,0.5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#000000', GradientType=0 ); +} + +#login_title { + display: block; + position: relative; + height: 50%; + padding-bottom: 130px; + box-sizing: border-box; + z-index: 3; +} +#login_title .inner { + position: relative; + width: 100%; + height: 100%; +} +#login_title h1 { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); + font-family: 'Noto Sans KR', sans-serif; + font-size: 35px; + font-weight: 600; +} + +#login_title em { + font-style: normal; + color: #29c7ca; + text-align: center; + line-height: 1.5em; +} +#login_title em strong { + color: #fff; +} +#login_title span { + display: block; + font-size: 16px; + font-weight: 400; + color: #999; + text-align: center; +} +#login_title sup { + display: block; + position: relative; + font-size: 13px; + font-weight: 300; + text-align: center; + padding: 0; + margin-top: 20px; + color: #777; +} + +#mb_login { + position: absolute; + top: 50%; + left: 50%; + width: 500px; + height: 260px; + + border-top: 5px solid #29c7ca; + + transform: translateX(-50%) translateY(-50%); + background: #fff; + + -webkit-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.49); + -moz-box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.49); + box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.49); + + z-index: 5; +} + + +#mb_login:before { + content: ""; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: -20px; + background: #fff; + z-index: 0; +} + +#mb_login .inner { + position: relative; + padding: 30px; + z-index: 1; +} + +#mb_login fieldset.input { + display: block; + position: relative; + margin-bottom: 5px; + margin-right: 130px; +} +#mb_login fieldset.input input { + display: block; + width: 100%; + box-sizing: border-box; + + background: #fff !important; + color: #3a3a3b; + height: 45px; + padding: 0 15px 0 45px; + font-size: 15px; + font-family: 'Noto Sans KR', sans-serif; + outline: none; + border: 1px solid #eaeaea; +} +#mb_login fieldset.input input:focus { border: 2px solid #29c7ca; } + +#mb_login fieldset.input label { + display: block; + position: absolute; + top: 0; + left: 0; + width: 45px; + height: 45px; + line-height: 45px; + overflow: hidden; + text-indent: -999px; + +} +#mb_login fieldset.input label:before { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + text-indent: 0; + text-align: center; + font-family: 'icon'; + font-size: 16px; + color: #ccc; +} +#mb_login fieldset.input input:focus + label:before { color: #29c7ca; } +#mb_login fieldset.input label.login_id:before { content: "\e976"; } +#mb_login fieldset.input label.login_pw:before { content: "\e98e"; } + +#mb_login fieldset.input input:-webkit-autofill { + transition: background-color 50000s ease-in-out 0s; + -webkit-box-shadow: 0 0 0 30px white inset; + -webkit-text-fill-color: #3a3a3b !important; +} + +#mb_login fieldset.check { + display: block; + position: relative; + padding: 5px; + background: #f6f6f6; + border: 1px solid #ebebeb; + color: #3a3a3a; + margin: 5px 130px 5px 0; + font-size: 11px; +} +#mb_login fieldset.check label { cursor: pointer; } + +#mb_login fieldset.button { + display: block; + position: absolute; + top: 30px; + right: 30px; + width: 126px; + height: 128px; +} +#mb_login fieldset.button .btn_submit { + display: block; + width: 100%; + height: 100%; + background: #29c7ca; + font-family: 'Noto Sans KR', sans-serif; + font-size: 18px; + border: none; + cursor: pointer; + color: #fff; +} + +#copyright { + padding-top: 30px; + font-size: 12px; + color: #aaa; + text-align: center; +} \ No newline at end of file diff --git a/AvocadoEdition/skin/member/basic/style.css b/AvocadoEdition/skin/member/basic/style.css new file mode 100644 index 0000000..672dcea --- /dev/null +++ b/AvocadoEdition/skin/member/basic/style.css @@ -0,0 +1,114 @@ +@charset "utf-8"; + +#member_page { + position: relative; + overflow: hidden; + max-width: 800px; + margin: 0 auto; + padding-bottom: 80px; +} + +#member_page .agree-pannel .theme-box { + height: 300px; + overflow: auto; +} + +#member_page .member-title { + font-size: 24px; + padding-top: 20px; + text-align: center; +} +#member_page .member-title * { display: block; } +#member_page .member-title span { + font-size: 15px; + font-weight: 600; +} +#member_page .member-contents { padding-top: 20px; } + +#member_page .member-contents h2 { + font-size: 16px; + line-height: 1.5em; + padding-bottom: 10px; +} + +#member_page .member-contents section { + padding-bottom: 30px; +} + +#member_page .member-contents .theme-box { + padding: 15px; + line-height: 1.8em; +} + +#member_page .check-agree { + padding-top: 10px; + text-align: right; +} +#member_page .check-agree input { display: none; } +#member_page .check-agree input + label:before { + content: "\ea53"; + display: inline-block; + vertical-align: middle; + font-family: 'icon'; + margin-right: 5px; + font-size: 18px; +} +#member_page .check-agree input:checked + label:before { + content: "\ea52"; +} + + + +.member-form { + width: 100%; + margin-bottom: 30px; +} +.member-form th { + font-size: 13px; + font-weight: 400; + text-align: left; +} + + + +/*** PASSWORD ***/ + +#password_box { + display: block; + position: absolute; + top: 50%; + left: 50%; + margin-top: -150px; + margin-left: -150px; + width: 300px; + height: 200px; +} + +#password_box h1 {display:none;} +#password_box h1 + .theme-box { border-top-width: 0; margin-bottom: 3px; } + +#password_box .pass-form { + position: relative; + padding-right: 80px; + margin-top: 10px; +} +#password_box .pass-form fieldset { display: block; } +#password_box .pass-form fieldset + fieldset { margin-top: 3px; } +#password_box .pass-form .box-btn { + display: block; + position: absolute; + margin: 0; + top: 0; + right: 0; + bottom: 0; + width: 70px; +} +#password_box .pass-form input[type="password"] { width: 100%; } +#password_box .pass-form .box-btn .ui-btn { + width: 100%; + height: 100%; + padding: 0; +} +#password_box .btn_confirm .ui-btn { + width: 100%; +} diff --git a/AvocadoEdition/skin/new/basic/new.skin.php b/AvocadoEdition/skin/new/basic/new.skin.php new file mode 100644 index 0000000..2558d81 --- /dev/null +++ b/AvocadoEdition/skin/new/basic/new.skin.php @@ -0,0 +1,144 @@ +', 0); +?> + + +
    + 상세검색 +
    + + + + + + +

    회원 아이디만 검색 가능

    +
    + +
    + + + +
    + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; + ?> + +
    + + + 그룹게시판제목이름일시
    + + + + +
    게시물이 없습니다.
    +
    + + +
    + +
    + +
    + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/new/basic/style.css b/AvocadoEdition/skin/new/basic/style.css new file mode 100644 index 0000000..b1f56b6 --- /dev/null +++ b/AvocadoEdition/skin/new/basic/style.css @@ -0,0 +1,7 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 최근게시물 스킨 (new) */ +#new_sch {margin-bottom:10px;text-align:right} +#new_sch legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} +#new_sch p {padding:5px 0 0;font-size:0.95em;text-align:right;letter-spacing:-0.1em} \ No newline at end of file diff --git a/AvocadoEdition/skin/outlogin/basic/outlogin.skin.1.php b/AvocadoEdition/skin/outlogin/basic/outlogin.skin.1.php new file mode 100644 index 0000000..87b2fa5 --- /dev/null +++ b/AvocadoEdition/skin/outlogin/basic/outlogin.skin.1.php @@ -0,0 +1,34 @@ +', 0); +?> + + + diff --git a/AvocadoEdition/skin/outlogin/basic/outlogin.skin.2.php b/AvocadoEdition/skin/outlogin/basic/outlogin.skin.2.php new file mode 100644 index 0000000..3cb034b --- /dev/null +++ b/AvocadoEdition/skin/outlogin/basic/outlogin.skin.2.php @@ -0,0 +1,76 @@ +', 0); +?> + + +
    +
    + + + "; + } else { + echo ""; + } +} else { + if($is_add_character) { + echo "캐릭터 생성"; + } else { + echo ""; + } +} ?> +
    + +
    +{$character['ch_name']}

    "; + } +?> +

    + + + 관리자 + +

    +보유중인 캐릭터가 없습니다.

    "; + } else { + echo "

    캐릭터 생성기간이 아닙니다.

    "; + } + } +?> + + +
    +
    + diff --git a/AvocadoEdition/skin/outlogin/basic/style.css b/AvocadoEdition/skin/outlogin/basic/style.css new file mode 100644 index 0000000..93b3494 --- /dev/null +++ b/AvocadoEdition/skin/outlogin/basic/style.css @@ -0,0 +1,158 @@ +@charset "utf-8"; + +.login-skin-basic { + display: block; + position: relative; +} + +.login-skin-basic fieldset { + display: block; + position: relative; + margin-bottom: 3px; + margin-right: 75px; +} +.login-skin-basic fieldset input[type="text"], +.login-skin-basic fieldset input[type="password"] { display: block; width: 100%; padding-left: 30px; } +.login-skin-basic .box-id:before { + content: "\e976"; + font-family: 'icon'; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 10px; + line-height: 30px; +} +.login-skin-basic .box-pw:before { + content: "\e98d"; + font-family: 'icon'; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 10px; + line-height: 30px; +} + +.login-skin-basic fieldset.box-btn { + position: absolute; + top: 0; + right: 0; + width: 72px; + height: 63px; + + margin-right: 0; +} +.login-skin-basic fieldset.box-btn button { width: 100%; height: 100%; } +.login-skin-basic fieldset.box-join { margin-right: 0; } +.login-skin-basic fieldset.box-join .ui-btn { width: 100%; } + + +.logined-skin-basic { + position: relative; + padding-left: 80px; + height: 90px; +} +.logined-skin-basic .ui-thumb { + position: absolute; + top: 0; + left: 0; + width: 70px; + height: 90px; + overflow: hidden; +} +.logined-skin-basic .ui-thumb .thumb-box { + display: block; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + background: rgba(0, 0, 0, 0.5); +} +.logined-skin-basic .ui-thumb .thumb-box img { + min-width: 100%; + height: 100%; + max-width: 120%; +} +.logined-skin-basic .ui-thumb .ui-btn { + display: block; + width: 100%; + height: 100%; + line-height: 1.2em; + padding: 8px; +} +.logined-skin-basic .ui-thumb .ui-btn:before { + content: "\e973"; + display: block; + padding-top: 10px; + padding-bottom: 10px; + font-family: 'icon'; + font-size: 20px; +} +.logined-skin-basic .ui-thumb .ui-btn.etc:before { + content: "\ea4e"; + padding-top: 30px; +} +.logined-skin-basic .info { position: relative; height: 100%; } +.logined-skin-basic .info .name, +.logined-skin-basic .info .character { + display: block; + position: relative; + font-size: 14px; + font-weight: 600; +} + +.logined-skin-basic .info .character + .name { + padding-top: 5px; + font-size: 13px; + font-weight: 400; +} + +.logined-skin-basic .info .name .ui-btn { + font-size: 11px; + height: 20px; + line-height: 18px; + padding: 0 8px; + margin-left: 5px; +} + +.logined-skin-basic .info .descript { + padding: 5px 0; + font-size: 12px; +} + +.logined-skin-basic .control-group { + display: block; + position: absolute; + left: 0; + right: 0; + bottom: 0; + overflow: hidden; +} +.logined-skin-basic .control-group li { + display: block; + position: relative; + width: 33.33%; + float: left; +} +.logined-skin-basic .control-group .ui-btn { + display: block; + width: 100%; + letter-spacing: -1px; + font-size: 12px; + padding: 0 5px; +} +.logined-skin-basic .control-group .ui-btn i { + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + text-align: center; + line-height: 18px; + color: #fff; + background: #8d3333; + border-radius: 100%; + font-size: 11px; + +} +.logined-skin-basic .control-group li + li .ui-btn { border-left-width: 0; } \ No newline at end of file diff --git a/AvocadoEdition/skin/poll/basic/poll.skin.php b/AvocadoEdition/skin/poll/basic/poll.skin.php new file mode 100644 index 0000000..2317618 --- /dev/null +++ b/AvocadoEdition/skin/poll/basic/poll.skin.php @@ -0,0 +1,65 @@ +', 0); +?> + + +
    + + +
    +
    +

    +
    +
      + +
    • + +
    + +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/poll/basic/poll_result.skin.php b/AvocadoEdition/skin/poll/basic/poll_result.skin.php new file mode 100644 index 0000000..fedf718 --- /dev/null +++ b/AvocadoEdition/skin/poll/basic/poll_result.skin.php @@ -0,0 +1,125 @@ +', 0); +?> + + +
    + +
    +

    결과

    + +
    +
    전체
    +
    +
      + +
    1. +

      + + + 퍼센트 +

      +
      + +
      +
    2. + +
    +
    +
    +
    + + + + +
    +

    기타의견

    + + +
    +
    +

    님의 의견

    + + +
    +

    + +

    +
    + "; } ?> +
    +
    + + + = $po['po_level']) { ?> +
    + + + + +

    + +
    + + + + + + + + + + + + + + + + + + + +
    자동등록방지
    +
    + +
    + +
    +
    + + +
    + + + + + + + +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/poll/basic/style.css b/AvocadoEdition/skin/poll/basic/style.css new file mode 100644 index 0000000..cbe40a9 --- /dev/null +++ b/AvocadoEdition/skin/poll/basic/style.css @@ -0,0 +1,87 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* ### 기본 스타일 커스터마이징 시작 ### */ + +#poll a.btn_admin {} /* 관리자 전용 버튼 */ +#poll a.btn_admin:focus, #poll a.btn_admin:hover {} + +#poll_result .tbl_frm table {} +#poll_result .tbl_frm .frm_info {} +#poll_result .tbl_frm .frm_address {} +#poll_result .tbl_frm .frm_file {} +#poll_result .tbl_frm caption {} + +#poll_result .tbl_frm01 {} +#poll_result .tbl_frm01 th {} +#poll_result .tbl_frm01 td {} +#poll_result .tbl_frm01 textarea, #poll_result tbl_frm01 .frm_input {} +#poll_result .tbl_frm01 textarea {} +/* +#poll_result .tbl_frm01 #captcha {} +#poll_result .tbl_frm01 #captcha input {} +*/ +#poll_result .tbl_frm01 a {} + +/* 필수입력 */ +#poll_result .required, #poll_result textarea.required {} + +#poll_result .btn_confirm {} /* 서식단계 진행 */ +#poll_result .btn_submit {} +#poll_result button.btn_submit {} +#poll_result .win_btn {} /* 새창용 */ +#poll_result .win_btn button {} +#poll_result .win_btn input {} +#poll_result .win_btn a {} +#poll_result .win_btn a:focus, #poll_result .win_btn a:hover {} + +/* ### 기본 스타일 커스터마이징 끝 ### */ + +/* 설문조사 스킨 */ + +#poll header {position:relative;padding:15px 14px 0} +#poll h2 { text-align: center; border-bottom: 1px solid #fff; padding-bottom: 20px; margin-bottom: 20px; } +#poll header .btn_admin {margin-top:5px;width:158px;text-align:center} +#poll header p {padding:5px 0 0} +#poll ul {margin:0 0 10px;padding:5px 14px;list-style:none} +#poll li {padding:3px 0} +#poll footer {padding:0 14px 14px; text-align: center;} + +/* 설문조사 결과 (새창) */ +#poll_result { padding: 20px 0; } +#poll_result section {margin:0 20px 20px;padding:15px;} +#poll_result .tbl_wrap {margin:0} +#poll_result h2 {margin:0;padding:20px 0} +#poll_result a {} +#poll_result .sv_member, +#poll_result .sv_guest {font-weight:bold} +#poll_result_list {margin:0 auto 20px} +#poll_result_list h2 {text-align:center} +#poll_result_list dl, +#poll_result_list dt, +#poll_result_list dd {margin:0;padding:0} +#poll_result_list dl {padding-bottom:30px} +#poll_result_list dt {margin-right:5%;color:#e8180d;text-align:right} +#poll_result_list ol {margin:0;padding-left:30px} +#poll_result_list li {margin-top:10px} +#poll_result_list p {position:relative;margin:0;padding:5px 0} +#poll_result_list p strong {position:absolute;top:5px;right:5%;padding-right:80px;width:100px;text-align:right} +#poll_result_list p span {position:absolute;top:5px;right:5%;width:80px;color:#68999c;text-align:right} +.poll_result_graph {position:relative;margin-right:5%;height:5px;background:#eee} +.poll_result_graph span {position:absolute;top:0;left:0;height:5px;background:#565e60;font-size:0.1em} +#poll_result_cmt {} +#poll_result_cmt h2 {text-align:center} +#poll_result_cmt h3 {margin:0 0 10px} +#poll_result_cmt article {margin:0 0 15px;border-bottom:1px solid #eee} +#poll_result_cmt h1 {position:absolute;margin:0;padding:0;border:0;font-size:0;text-indent:-9999em;line-height:0;overflow:hidden} +.poll_datetime {display:inline-block;margin-left:10px} +#poll_result_cmt p {padding:3px 0} +#poll_result_cmt fieldset {margin-bottom:0;text-align:left} +#poll_result_cmt fieldset p {margin:0 0 15px;padding:3px 0 0px;text-align:left} +#poll_result_cmt footer {text-align:right} +#poll_result_wcmt {margin:0 0 10px} +.poll_cmt_del a {display:inline-block;padding-bottom:10px} +#poll_result_oth {margin:0 auto 20px;width:93%} +#poll_result_oth h2 {padding:0 0 10px} +#poll_result_oth ul {margin:0;padding:0;list-style:none} +#poll_result_oth a {display:block;padding:10px 0;border-bottom:1px solid #eee} \ No newline at end of file diff --git a/AvocadoEdition/skin/popular/basic/popular.skin.php b/AvocadoEdition/skin/popular/basic/popular.skin.php new file mode 100644 index 0000000..49e0b99 --- /dev/null +++ b/AvocadoEdition/skin/popular/basic/popular.skin.php @@ -0,0 +1,19 @@ +', 0); +?> + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/popular/basic/style.css b/AvocadoEdition/skin/popular/basic/style.css new file mode 100644 index 0000000..dd7d21a --- /dev/null +++ b/AvocadoEdition/skin/popular/basic/style.css @@ -0,0 +1,12 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 인기검색어 */ +#popular {border-bottom:1px dotted #dde4e9} +#popular div {margin:0 auto;width:970px;zoom:1} +#popular div:after {display:block;visibility:hidden;clear:both;content:""} +#popular h2 {float:left;padding:10px 45px 10px 0} +#popular ul {float:left;margin:0;padding:0;list-style:none} +#popular li {float:left} +#popular a {display:inline-block;padding:10px;text-decoration:none} +#popular a:focus, #popular a:hover {} \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/img/btn_close.gif b/AvocadoEdition/skin/qa/basic/img/btn_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..040b180ac6584ae612ef2886487110f0ad079963 GIT binary patch literal 211 zcmZ?wbhEHbC>lw|Nj2|^XJd+Ki|K7yLIc<@85r}UAy+@_wT|Ns9P2m!^PEMO%%AQEIJ18abSL2rs@7wgh> zI-xzeYYr882T$7a>~-(!J@=MOy}Z$ltNl`73Cq0Bi3wIGB-b=ECVhGFY*&ANIg94( d^Unm859R4|2rw-)wA%9i`(c-qSMQw}tN}eeW+eas literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/img/icon_answer.gif b/AvocadoEdition/skin/qa/basic/img/icon_answer.gif new file mode 100644 index 0000000000000000000000000000000000000000..91c135977b4f445a90c849310dc80efde1983830 GIT binary patch literal 77 zcmZ?wbhEHb-Wqsc#^P~2x#@rVooH@5wHB9i@BozKb;P9uI^*c|UyXO5@>VyLmgEat< Cr6(f* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/img/icon_hot.gif b/AvocadoEdition/skin/qa/basic/img/icon_hot.gif new file mode 100644 index 0000000000000000000000000000000000000000..c95b839aeef0c1e26a4bab4ea50cd6d3f1969d7f GIT binary patch literal 97 zcmZ?wbhEHbzHen|7VvwFnzUPlarEA ZqW~YXyUO~T+#YkUoJ%V_>ib05Q5F AasU7T literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/img/icon_mobile.gif b/AvocadoEdition/skin/qa/basic/img/icon_mobile.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad934d23c440c83db0c4589596465cb087353e01 GIT binary patch literal 62 zcmZ?wbhEHbZ% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/img/icon_secret.gif b/AvocadoEdition/skin/qa/basic/img/icon_secret.gif new file mode 100644 index 0000000000000000000000000000000000000000..c04899f14fa727b64223f6c5457877c6c939639d GIT binary patch literal 97 zcmZ?wbhEHb&!1E4^4&ClEzh)PmWxV3{9A~!gB2-%RL5bHcgg3Zp^!+W)H2^A_AxQuL literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/img/icon_sound.gif b/AvocadoEdition/skin/qa/basic/img/icon_sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5188318a5cdc394b984125c0ddd376c5f57bbe4 GIT binary patch literal 113 zcmZ?wbhEHbE1CJY$zMikVi`-#gIi|DbmsXBWf6U5szE@->A`0*`&<;b@XASRrB8=E6~=S>Pbm I%fes{0AXt-SpWb4 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/qa/basic/list.skin.php b/AvocadoEdition/skin/qa/basic/list.skin.php new file mode 100644 index 0000000..8589fb7 --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/list.skin.php @@ -0,0 +1,146 @@ +', 0); +?> + + + +
    + +
    +
    + + + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + '; } ?> + +
    목록
    번호 + + + 제목작성자상태등록일
    + + + + + + + +
    게시물이 없습니다.
    + + +
    + + + +
    +
    +
    + + + + + + + + + +
    + 게시물 검색 + +
    + + + + +
    +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/style.css b/AvocadoEdition/skin/qa/basic/style.css new file mode 100644 index 0000000..2719f01 --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/style.css @@ -0,0 +1,33 @@ +@charset "utf-8"; + + +/** Notice Box **/ +.board-notice { width: 264px; padding: 10px; margin: 0 auto; text-align: center; box-sizing: border-box; } +.btn_bo_user { padding: 15px 0; } +/* +@media all and (max-width: 640px) { + + .theme-form.write, + .theme-form.write tbody, + .theme-form.write thead, + .theme-form.write tr, + .theme-form.write td, + .theme-form.write th { + display: block; + position: relative; + height: auto !important; + } + + .theme-form.write tr { + box-sizing: content-box; + } + .theme-form.write th { + background: none !important; + border: none !important; + text-align: left; + padding: 10px 20px 8px 20px !important; + } + .theme-form.write td { + padding: 0px 20px 10px 20px !important; + } +}*/ \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/view.answer.skin.php b/AvocadoEdition/skin/qa/basic/view.answer.skin.php new file mode 100644 index 0000000..946e426 --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/view.answer.skin.php @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + +
    답변
    + +
    + +
    + +
    +
    + + 답변수정 + + + 답변삭제 + +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/view.answerform.skin.php b/AvocadoEdition/skin/qa/basic/view.answerform.skin.php new file mode 100644 index 0000000..e2364bd --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/view.answerform.skin.php @@ -0,0 +1,120 @@ + + +
    + +

    답변등록

    + +
    + + + + + + '; + } else { + $option .= "\n".''."\n".''; + } + + echo $option_hidden; + ?> + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    +
    + + + +

    고객님의 문의에 대한 답변을 준비 중입니다.

    + +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/view.skin.php b/AvocadoEdition/skin/qa/basic/view.skin.php new file mode 100644 index 0000000..29db689 --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/view.skin.php @@ -0,0 +1,128 @@ +', 0); +?> + + + + + + + + + + + + + + + + + + + + + + + 0) { ?> + + + + + + + + + + +
    제목
    작성자
    작성일
    첨부파일 + +
  • + + 첨부 + + +
  • + +
    + \n"; + + for ($i=0; $i<$view['img_count']; $i++) { + //echo $view['img_file'][$i]; + echo get_view_thumbnail($view['img_file'][$i], $qaconfig['qa_image_width']); + } + + echo "\n"; + } + ?> + + +
    + +
    + +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/qa/basic/write.skin.php b/AvocadoEdition/skin/qa/basic/write.skin.php new file mode 100644 index 0000000..7c78b51 --- /dev/null +++ b/AvocadoEdition/skin/qa/basic/write.skin.php @@ -0,0 +1,167 @@ +', 0); +?> + + +
    + + + + + +'; +} else { + $option .= "\n".''."\n".''; +} + +echo $option_hidden; +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + class="frm_input email" size="50" maxlength="100"> + > + +
    + +
    + +
    파일 #1 + + + + +
    파일 #2 + + + + +
    + +
    + +
    + + 목록 +
    +
    + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/search/basic/search.skin.php b/AvocadoEdition/skin/search/basic/search.skin.php new file mode 100644 index 0000000..e341efa --- /dev/null +++ b/AvocadoEdition/skin/search/basic/search.skin.php @@ -0,0 +1,140 @@ +', 0); +?> + + +
    + +
    + 상세검색 + + + + + + + + + + + + id="sop_or" name="sop"> + + id="sop_and" name="sop"> + +
    +
    + +
    + + +
    +

    전체검색 결과

    +
    +
    게시판
    +
    +
    게시물
    +
    +
    +

    / 페이지 열람 중

    +
    + + + + + +
    검색된 자료가 하나도 없습니다.
    + + +
    + +
    + +

    게시판 내 결과

    +
      + 댓글 | '; + $comment_href = '#c_'.$list[$idx][$i]['wr_id']; + } + else + { + $comment_def = ''; + $comment_href = ''; + } + ?> + +
    • + + 새창 +

      + + +
    • + +
    + + +
    + +
    + + + +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/search/basic/style.css b/AvocadoEdition/skin/search/basic/style.css new file mode 100644 index 0000000..4ce7a97 --- /dev/null +++ b/AvocadoEdition/skin/search/basic/style.css @@ -0,0 +1,29 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 전체검색결과 스킨 */ +#sch_res_detail {padding:0 0 10px;border-bottom:1px solid #e9e9e9;text-align:center} +#sch_res_detail legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} +#sch_res_ov {margin:0 0 10px;padding:10px;border-bottom:1px solid #e9e9e9;background:#f5f6fa;zoom:1} +#sch_res_ov:after {display:block;visibility:hidden;clear:both;content:""} +#sch_res_ov h2 {float:left} +#sch_res_ov dl {float:left;margin:0 0 0 10px} +#sch_res_ov dt {float:left} +#sch_res_ov dd {float:left;margin:0 10px 0 5px} +#sch_res_ov p {float:right;margin:0;padding:0;line-height:1em} + +#sch_res_board {margin:0 0 10px;padding-left:1px;list-style:none;zoom:1} +#sch_res_board:after {display:block;visibility:hidden;clear:both;content:""} +#sch_res_board li {float:left;margin-bottom:-1px} +#sch_res_board a {display:block;position:relative;margin-left:-1px;padding:6px 0 5px;width:180px;border:1px solid #ddd;text-align:center;letter-spacing:-0.1em;line-height:1.2em;cursor:pointer} +#sch_res_board a:focus, #sch_res_board a:hover, #sch_res_board a:active {text-decoration:none} +#sch_res_board .cnt_cmt {font-weight:normal !important} + +.sch_res_list {margin:0 0 10px;padding:10px 0 15px} +.sch_res_list h2 {margin:0 0 15px;font-size:1.2em} +.sch_res_list ul {margin:0;padding:0;list-style:none} +.sch_res_list li {margin:0 0 10px;padding:0 0 10px;border-bottom:1px solid #e9e9e9} +.sch_res_title {display:inline-block;margin:0 0 5px} +.sch_res_list p {margin:0 0 10px;line-height:1.8em} +.sch_more {text-align:right} +.sch_on {color:#ff3061} \ No newline at end of file diff --git a/AvocadoEdition/skin/visit/basic/style.css b/AvocadoEdition/skin/visit/basic/style.css new file mode 100644 index 0000000..350e4e8 --- /dev/null +++ b/AvocadoEdition/skin/visit/basic/style.css @@ -0,0 +1,13 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + +/* 방문자 집계 */ +#visit {border-bottom:1px dotted #dde4e9} +#visit div {margin:0 auto;width:970px;zoom:1} +#visit div:after {display:block;visibility:hidden;clear:both;content:""} +#visit h2 {float:left;padding:10px 45px 10px 0} +#visit dl {float:left;margin:0 0 0 10px;padding:0} +#visit dt {float:left;margin:0;padding:10px 0 10px} +#visit dd {float:left;margin:0 30px 0 0;padding:10px} +#visit a {display:inline-block;padding:10px;text-decoration:none} +#visit a:focus, #visit a:hover {} \ No newline at end of file diff --git a/AvocadoEdition/skin/visit/basic/visit.skin.php b/AvocadoEdition/skin/visit/basic/visit.skin.php new file mode 100644 index 0000000..87e481d --- /dev/null +++ b/AvocadoEdition/skin/visit/basic/visit.skin.php @@ -0,0 +1,27 @@ +', 0); +?> + + +
    +
    +

    접속자집계

    +
    +
    오늘
    +
    +
    어제
    +
    +
    최대
    +
    +
    전체
    +
    +
    + 상세보기 +
    +
    + \ No newline at end of file diff --git a/AvocadoEdition/tail.php b/AvocadoEdition/tail.php new file mode 100644 index 0000000..1e6dd87 --- /dev/null +++ b/AvocadoEdition/tail.php @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/tail.sub.php b/AvocadoEdition/tail.sub.php new file mode 100644 index 0000000..e136a01 --- /dev/null +++ b/AvocadoEdition/tail.sub.php @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.bgm.php b/AvocadoEdition/templete/txt.bgm.php new file mode 100644 index 0000000..43449b1 --- /dev/null +++ b/AvocadoEdition/templete/txt.bgm.php @@ -0,0 +1,53 @@ + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.join.php b/AvocadoEdition/templete/txt.join.php new file mode 100644 index 0000000..e3f15fd --- /dev/null +++ b/AvocadoEdition/templete/txt.join.php @@ -0,0 +1,3 @@ + +회원가입 + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.login.php b/AvocadoEdition/templete/txt.login.php new file mode 100644 index 0000000..52cfc66 --- /dev/null +++ b/AvocadoEdition/templete/txt.login.php @@ -0,0 +1,3 @@ + +로그인 + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.logout.php b/AvocadoEdition/templete/txt.logout.php new file mode 100644 index 0000000..cebc809 --- /dev/null +++ b/AvocadoEdition/templete/txt.logout.php @@ -0,0 +1,3 @@ + +로그아웃 + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.mypage.php b/AvocadoEdition/templete/txt.mypage.php new file mode 100644 index 0000000..254adda --- /dev/null +++ b/AvocadoEdition/templete/txt.mypage.php @@ -0,0 +1,3 @@ + +마이페이지 + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.outlogin.php b/AvocadoEdition/templete/txt.outlogin.php new file mode 100644 index 0000000..d2a0832 --- /dev/null +++ b/AvocadoEdition/templete/txt.outlogin.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.twitter.php b/AvocadoEdition/templete/txt.twitter.php new file mode 100644 index 0000000..abb6738 --- /dev/null +++ b/AvocadoEdition/templete/txt.twitter.php @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/AvocadoEdition/templete/txt.visual.php b/AvocadoEdition/templete/txt.visual.php new file mode 100644 index 0000000..c4091e2 --- /dev/null +++ b/AvocadoEdition/templete/txt.visual.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/_common.php b/AvocadoEdition/theme/basic/_common.php new file mode 100644 index 0000000..c7ed3c4 --- /dev/null +++ b/AvocadoEdition/theme/basic/_common.php @@ -0,0 +1,2 @@ +', 0); +?> + +
    + +
    +
      + +
    • +
      + + + + + + + +
      + +

      + 커플
      + 일 째입니다. +

      +
    • + +
    + +
    +
    diff --git a/AvocadoEdition/theme/basic/css/couple.css b/AvocadoEdition/theme/basic/css/couple.css new file mode 100644 index 0000000..b7cb714 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/couple.css @@ -0,0 +1,13 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 커플란 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +#couple_page { position: relative; padding: 50px 0; } +#couple_list { text-align: center; } +#couple_list li { display: block; padding-bottom: 50px; } diff --git a/AvocadoEdition/theme/basic/css/default.css b/AvocadoEdition/theme/basic/css/default.css new file mode 100644 index 0000000..c8114b1 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/default.css @@ -0,0 +1,146 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 스타일 초기화 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +/**************************************** + Import +****************************************/ + +@import url(./swiper.css); +@font-face { + font-family: 'icon'; + src: url('./fonts/icomoon.eot?y5isk6'); + src: url('./fonts/icomoon.eot?y5isk6#iefix') format('embedded-opentype'), + url('./fonts/icomoon.ttf?y5isk6') format('truetype'), + url('./fonts/icomoon.woff?y5isk6') format('woff'), + url('./fonts/icomoon.svg?y5isk6#icomoon') format('svg'); + font-weight: normal; + font-style: normal; +} +.sound_only { display: none; } + + +/**************************************** + 소스코드 초기화 +****************************************/ + +html {overflow-y:auto} +body {margin:0;padding:0;} +html, h1, h2, h3, h4, h5, h6, form, fieldset, img {margin:0;padding:0;border:0} +h1, h2, h3, h4, h5, h6 {} +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {display:block} +ul, li {margin:0;padding:0;list-style:none} +legend {display: none;} +label, input, button, select, img {vertical-align:middle} +input, button {margin:0;padding:0;} +button {cursor:pointer} +textarea, select {font-size:1em} +select {margin:0} +p {margin:0;padding:0;word-break:break-all} +hr {display:none} +pre {overflow-x:scroll;} +a:link, a:visited {text-decoration:none} +a:hover, a:focus, a:active {text-decoration:none} + +ul,li { margin: 0; padding: 0; } +i,sup,em { font-style: normal; } + +label { cursor: pointer; } + +img { max-width: 100%; vertical-align: middle; } +table { width: 100%; } + + +/**************************************** + 기본 레이아웃 정의 +****************************************/ + +.fix-layout {max-width: 1000px; margin: 0 auto; padding: 0 10px; } +.fix-layout .fix-layout { padding: 0; margin:0; } + +#body {min-height:100%; box-sizing:border-box; padding:30px 0;} + + +/**************************************** + 애니메이션 효과 지정 / 초기화 +****************************************/ + +* {transition: all .3s ease; -webkit-transition: all .3s ease; -ms-transition: all .3s ease;} + +.trans, +.trans *, +.trans *:after, +.trans *:before { -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; } + +.none-trans, +.none-trans *, +.none-trans *:after, +.none-trans *:before { -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; } + + +/**************************************** + 텍스트 코드 정렬 +****************************************/ + +.txt-left { text-align: left; } +.txt-center { text-align: center; } +.txt-right { text-align: right; } + + +/**************************************** + 스크롤 스타일 정의 +****************************************/ + +/* scrollbar : ie except */ +*::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);background-color: rgba(0, 0, 0, 0.2);} +*::-webkit-scrollbar { width: 5px; height: 5px; background-color: transparent;} +*::-webkit-scrollbar-thumb { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); background: #fff677; border: none; border-radius: 6.0em; } + + +/********************** + 폼 스타일 +**********************/ + +.theme-form { width: 100%; } + + +/************************************************************** + Web Size Viewer Control - 반응형 코딩 + - + 모바일 기준 :width 1024px +***************************************************************/ + +@media all and (min-width:1025px) { + .only-pc {} + .only-ta {display:none !important;} + .only-mo {display:none !important;} + + .not-pc {display:none !important;} + .not-ta {} + .not-mo {} +} + +@media all and (max-width:1024px) and (min-width:1025px) { + .only-pc {display:none !important;} + .only-ta {} + .only-mo {display:none !important;} + + .not-pc {} + .not-ta {display:none !important;} + .not-mo {} +} +@media all and (max-width:1025px) { + .only-pc {display:none !important;} + .only-ta {display:none !important;} + .only-mo {} + + .not-pc {} + .not-ta {} + .not-mo {display:none !important;} +} diff --git a/AvocadoEdition/theme/basic/css/emoticon.css b/AvocadoEdition/theme/basic/css/emoticon.css new file mode 100644 index 0000000..1af86db --- /dev/null +++ b/AvocadoEdition/theme/basic/css/emoticon.css @@ -0,0 +1,45 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 자비란 이모티콘 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + + +#emoticon_page {position:relative; padding:20px; margin:0 auto; box-sizing:border-box;} +#emoticon_page:after {content:""; display:block; clear:both;} + +#page_title {display:block; font-size:18px; padding:10px 0; text-align:center;} +#page_title li {display:inline-block;} +#page_title li a {line-height:55px; font-size:18px; padding:0 20px;} + + +/********************************* + 반응형 처리 +**********************************/ + +@media all and (max-width:670px) { + .fix-layout {padding:0;} + #page_title li a {font-size:14px; padding:0 10px; line-height:40px;} + #lnb_mark {width:70px;} + +} +@media all and (max-width:670px) { + #emoticon_page:before {left:10px; right:10px;} +} + + +/********************************* + 리스트 +**********************************/ + +#emoticon_content {position:relative; text-align:center;} +#emoticon_content .no-data {text-align:center; width:100%; line-height:100px;} +#emoticon_content li {display:inline-block; position:relative; width:80px;} +#emoticon_content li em {display:block; position:relative; width:80px; height:80px; vertical-align:middle; background:rgba(0, 0, 0, 0.3); border-radius:10px; overflow:hidden;} +#emoticon_content li em:before {content:""; display:inline-block; vertical-align:middle; width:0; height:100%;} +#emoticon_content li em img {display:inline-block; vertical-align:middle; max-width:95%;} +#emoticon_content li span {display:block; padding:5px 0 10px 0; font-size:12px;} \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/css/enter.css b/AvocadoEdition/theme/basic/css/enter.css new file mode 100644 index 0000000..e5dccf5 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/enter.css @@ -0,0 +1,29 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 대문 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + + +/********************************* + 인트로 스타일 정의 +**********************************/ + +html, body {height:100%; margin:0; padding:0;} + +.wrapper {display:table; width:100%; height:100%; position:relative; z-index:1;} +.wrapper > .inner {display:table-cell; vertical-align:middle; text-align:center;} + +.index-logo {display:block; padding:10px; margin-top:-80px; word-break:keep-all; text-align:center; font-size:14px; padding-bottom:23px;} +.index-logo img {max-width:70%;} +.index-logo p {padding:10px 0;} + +.index-logo a {display:inline-block; text-decoration:none;} + +@media all and (max-width:640px) { .index-logo {font-size:14px;} } +@media all and (max-width:480px) { .index-logo {font-size:13px;} } +@media all and (max-width:380px) { .index-logo {font-size:12px;} } \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/css/index.css b/AvocadoEdition/theme/basic/css/index.css new file mode 100644 index 0000000..b7045d5 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/index.css @@ -0,0 +1,31 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 인덱스 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +/**************************************************** + Index Wrap Style +*****************************************************/ + +html, body { position: relative; height: 100%; margin: 0; padding: 0; overflow: hidden; } + + +/**************************************************** + Index User Style +*****************************************************/ +#wrap { height: 100%; } +#wrapper { width: 100%; height: 100%; } +#wrapper iframe { width: 100%; height: 100%; background-color: transparent; overflow:scroll; } + +#bgm { position: fixed; top: 0; right: 0; text-align: center; width: 145px; z-index: -999; } +#bgm a { display: none; width: 15px; height: 15px; text-indent: -999px; overflow: hidden; } +#bgm a.on { display: inline-block; } +#site_bgm_box { width: 0px; height: 0px; overflow: hidden; } + + + diff --git a/AvocadoEdition/theme/basic/css/intro.css b/AvocadoEdition/theme/basic/css/intro.css new file mode 100644 index 0000000..b0ae559 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/intro.css @@ -0,0 +1,22 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 인트로 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + + +/********************************* + 인트로 스타일 정의 +**********************************/ + +html.close-intro, +.close-intro body {height:auto;} +html.close-intro {overflow-y:auto;} + +#intro_wrap {position:fixed; top:0; left:0; right:0; bottom:0; text-align:center; z-index:9999; background:#000;} + +#intro_wrap .intro-item {display:block; position:absolute; top:0; left:0; right:0; bottom:0; overflow-y:auto;} diff --git a/AvocadoEdition/theme/basic/css/login.css b/AvocadoEdition/theme/basic/css/login.css new file mode 100644 index 0000000..978a64d --- /dev/null +++ b/AvocadoEdition/theme/basic/css/login.css @@ -0,0 +1,25 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 로그인 화면 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +/**************************************************** + Login Style +****************************************************/ + +html, +body {height:100%;} +.loginWrap {display:table; width:100%; height:100%;} +.login-inner {display:table-cell; vertical-align:middle; text-align:center;} + +.login-logo {margin-top:-50px;} +.login-form-box {position:relative; box-sizing:border-box; max-width:280px; margin:0 auto; padding:5px;} +.login-form-box .inner {display:block; position:relative; padding-right:80px;} +.login-form-box button {display:block; position:absolute; right:0; top:0; width:75px; bottom:0; height:100%;} +.login-form-box fieldset + fieldset {margin-top:5px;} +.login-form-box input {width:100%;} \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/css/main.css b/AvocadoEdition/theme/basic/css/main.css new file mode 100644 index 0000000..97fe049 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/main.css @@ -0,0 +1,9 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * Basic 메인 화면 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : + - 최초 작성자 : + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ diff --git a/AvocadoEdition/theme/basic/css/member.css b/AvocadoEdition/theme/basic/css/member.css new file mode 100644 index 0000000..34e2325 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/member.css @@ -0,0 +1,120 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 멤버란 디자인 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + + +/**************************************************** + 신청자 목록 레이아웃 +****************************************************/ + +.ready-member-list {display:block; position:relative; overflow:hidden;} +.ready-member-list li {float:left; width:50%; margin-bottom:8px;} +.ready-member-list li.empty {width:100%; line-height:300px; text-align:center;} +.ready-member-list li .item {position:relative; padding:10px; margin:0 5px; } +.ready-member-list li .ui-thumb {display:block; position:absolute; top:10px; left:10px; width:80px; height:80px; overflow:hidden; box-sizing:border-box;} +.ready-member-list li .ui-thumb span {display:block; position:absolute; top:0; bottom:0; left:0; right:0; text-align:center; font-size:11px; line-height:96px; opacity:1;} +.ready-member-list li .ui-thumb span.ing {} +.ready-member-list li .ui-thumb span.com {display:none;} +.ready-member-list li .ui-thumb a:hover span {opacity:0;} + +.ready-member-list li .ui-profile {display:block; position:relative; margin-left:95px; min-height:85px;} +.ready-member-list li .ui-profile i {display:block; position:absolute; top:0; left:0; width:18px;} +.ready-member-list li .ui-profile .name {padding:5px 0;} +.ready-member-list li .ui-profile em {display:block; font-style:normal; font-size:11px;} +.ready-member-list li .ui-profile strong {font-size:14px;} +.ready-member-list li .ui-profile span {display:block; padding:3px 0; font-size:11px;} +.ready-member-list li .ui-profile span.owner {text-align:right; margin-top:5px; padding-top:5px;} + +/* 반응형 */ +@media all and (max-width:1024px) { + #submenu li.menu-first {display:block; text-align:center;} +} +@media all and (max-width:640px) { + .ready-member-list li {width:100%;} +} + + +/**************************************************** + 멤버 목록 레이아웃 +****************************************************/ + +.memberWrap {display:table; width:100%;} +.memberWrap > .member-box {display:table-cell; text-align:center; vertical-align:top;} +.member-list {text-align:center;} +.member-list li {display:inline-block; vertical-align:top; margin:5px;} +.member-list .item {display:block; position:relative; padding:0;} +.member-list .ui-profile {position:absolute; left:0; right:0; bottom:0; padding:5px; text-align:center;} + +@media all and (max-width:800px) { + .memberWrap, + .memberWrap > .member-box {display:block;} +} + + +/**************************************************** + 멤버 프로필 레이아웃 +****************************************************/ + +#character_profile .visual-area {position:relative;} +#character_profile #character_body {position:relative; z-index:0;} +#character_profile #character_body img {display:block; margin:0 auto;} +#character_profile #character_head {position:absolute; left:0; bottom:0; right:0; z-index:1;} + + +/**************************************************** + 인벤토리 스타일 +****************************************************/ + +.inventory-list {display:block; position:relative; overflow:hidden;} +.inventory-list li {display:block; float:left; padding:5px;} +.inventory-list a {display:block; position:relative; width:40px; height:40px; overflow:hidden;} +.inventory-list a img {display:block; position:relative; margin:0 auto;} +.inventory-list a i {display:block; position:absolute; right:1px; bottom:1px; background:rgba(0,0,0,.5); min-width:15px; height:15px; line-height:15px; color:#fff; font-size:10px; font-weight:800; padding:0 1px; text-align:center; z-index:2; box-sizing:border-box; border:none !important;} +.inventory-list a i.present:before {content:"\e99f"; font-family:'icon'; font-weight:400;} + +.title-list {display:block; position:relative; padding:20px 0;} +.title-list p {padding:5px;} +.title-list .item {display:inline-block; min-width:25%; padding: 5px; box-sizing:border-box; text-align:left; vertical-align:middle;} + + +/****************************************** + 관계란 스타일 +*******************************************/ + +.relation-member-list { position: relative; } +.relation-member-list > li { position:relative; padding-left: 90px; min-height:120px; margin-bottom: 20px; } +.relation-member-list .ui-thumb { position: absolute; top: 0; left: 0; width: 80px; overflow: hidden; } +.relation-member-list .rm-name { font-size: 14px; font-weight: 800; padding-right: 150px; padding-left: 10px; } + +.relation-member-list .rm-like-style { position: absolute; right: 0; top: 0;width: 80px; } +.relation-member-list .rm-like-style i { display: block; width: 13px; height: 15px; position: relative; float: left; margin: 0 1px;} +.relation-member-list .rm-like-style i:before { content: "\e9da"; font-family: 'icon'; font-style: normal; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; font-family: 'icon'; } +.relation-member-list .memo { font-family: 'Dotum'; padding:10px; margin: 5px 0; line-height: 1.2em; min-height: 30px; } + +.relation-member-list ol { display: block; position: relative; clear: both; text-align: right;padding-right: 10px; } +.relation-member-list ol li { display: inline-block; } +.relation-member-list ol li a.btn-log { display: block; position: relative; width: 20px; height: 20px; margin: 0 auto; } +.relation-member-list ol li a.btn-log:before { content: "\e925"; font-family: 'icon'; font-size: 15px; font-style: normal; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; font-family: 'icon'; } + +.relation-member-list .modify-box { display: none; } +.relation-member-list .state-modify { } +.relation-member-list .state-modify .rm-like-style, +.relation-member-list .state-modify .memo .ori-content, +.relation-member-list .state-modify ol { display: none; } +.relation-member-list .state-modify .modify-box { display: block; } + + +@media all and (max-width: 500px) { + .relation-member-list .rm-name { padding-right: 0; font-size: 13px; } + .relation-member-list .rm-like-style { position: relative; width: auto;overflow: hidden; } + + .relation-member-list > li { padding-left:0px; } + .relation-member-list .ui-thumb { width: 50px; } + .relation-member-list .info { min-height: 62px; margin-left: 60px; } +} diff --git a/AvocadoEdition/theme/basic/css/mypage.css b/AvocadoEdition/theme/basic/css/mypage.css new file mode 100644 index 0000000..ea2b498 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/mypage.css @@ -0,0 +1,256 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 마이페이지 스타일 정의 +-------------------------------------------------- + - 최초 작성일 : 2021.08.15 + - 최초 작성자 : 아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +/************************************************************** + 기본 레이아웃 +***************************************************************/ + +.mypageWrap {padding:20px 0;} +.mypageInside {position:relative;} +.my-inner {max-width:900px; padding:20px; margin:0 auto;} + +@media all and (max-width:640px) { + .mypageWrap {padding:10px 0px;} +} + + +/************************************************************** + 캐릭터 작성 폼 +***************************************************************/ + +.list-character-box {display:block; position:relative; margin:10px 0; overflow:hidden;} +.list-character-box .item {display:block; position:relative; color:#fff; margin:10px 0; padding:0;} +.list-character-box .item a {display:block; position:relative; padding:10px 10px 10px 100px; min-height:100px; box-sizing:border-box;} +.list-character-box .item a em {display:block; position:absolute; width:80px; height:80px; top:10px; left:10px; background:no-repeat 50% 50%; background-size:cover;} +.list-character-box .item strong {display:block; position:relative; margin-bottom:5px; font-size:18px; line-height:1.5; font-weight:800; font-family:'HeirofLight';} +.list-character-box .item span {display:inline-block; font-size:13px; color:#fff;} +.list-character-box .item span:after {content:" | "; margin:0 4px; opacity:.5;} +.list-character-box .item span:last-child:after {display:none;} +.list-character-box .item span i {margin-right:5px;} + + +/************************************************************** + 탭 설정 +***************************************************************/ + +#tab_list {display:block; position:relative; overflow:hidden; box-sizing:border-box; text-align:center; border:none;} +#tab_list ul {position:relative; z-index:1;} +#tab_list li {font-size:14px; font-weight:600; padding:5px;} +#tab_list li a {color:#fff; opacity:.7} +#tab_list li a.point, +#tab_list li a:hover {opacity:1;} +#tab_list li a.point:before {content:"《";} +#tab_list li a.point:after {content:"》";} + + +/************************************************************** + 로그 리스트 +***************************************************************/ + +.mypage-log-list {display:Block; position:relative;} +.mypage-log-list dl {position:relative; padding-left:100px; min-height:80px; margin:20px 15px; border-bottom:1px solid rgba(255, 255, 255, .2);} +.mypage-log-list dl dt {position:absolute; top:0; left:0; width:100px; height:80px; overflow:hidden;} +.mypage-log-list dl dt img {max-width:100%;} +.mypage-log-list dl dd {margin-left:10px;} +.mypage-log-list dl .comemnt-list li {overflow:hidden; padding-bottom:3px;} +.mypage-log-list dl .comemnt-list li + li {padding-top:3px; border-top:1px dashed rgba(255, 255, 255, .2);} +.mypage-log-list dl .comemnt-list li p {overflow:hidden; white-space:nowrap; text-overflow:ellipsis;} +.mypage-log-list dl .comemnt-list li p.con {opacity:.8;} +.mypage-log-list dl .comemnt-list li p .date {font-size:11px; font-family:'Dotum';} + +@media all and (max-width:500px) { + .mypage-log-list dl {padding-left:0; font-size:12px;} + .mypage-log-list dl dt {position:relative; width:auto; text-align:center;} + .mypage-log-list dl dd {padding-top:10px; margin-left:0;} + +} + + +/************************************************************** + 좋아요 추가한 로그 리스트 +***************************************************************/ + +.mypage-favorite-list {overflow:hidden;} +.mypage-favorite-list dl {width:20%; float:left; padding:3px; box-sizing:border-box;} +.mypage-favorite-list dl dt {display:block; position:relative;} +.mypage-favorite-list dl dt:before {content:""; display:block; position:relative; padding-top:100%;} +.mypage-favorite-list dl dt a {display:block; position:absolute; top:3px; left:3px; right:3px; bottom:3px; overflow:hidden; text-align:center;} +.mypage-favorite-list dl dt a img {position:absolute; top:50%; left:50%; transform:translateX(-50%) translateY(-50%);} +.mypage-favorite-list dl dd {margin:0; text-align:center; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;} + +@media all and (max-width:820px) {.mypage-favorite-list dl {width:25%;}} +@media all and (max-width:600px) {.mypage-favorite-list dl {width:33.33%;}} +@media all and (max-width:450px) {.mypage-favorite-list dl {width:50%;}} + +.mypage-log-list .no-data, +.mypage-favorite-list .no-data {text-align:center; line-height:150px;} + + +/************************************************************** + 마이페이지 캐릭터 관리 +***************************************************************/ + +.profile-viewer {display:block; position:relative; padding-left:100px;} +.profile-viewer .theme-box {padding:0;} +.profile-viewer .body {display:block; position:absolute; top:0; left:0; width:100px; bottom:0;} +.profile-viewer .body em {display:block; position:absolute; top:0; left:0; right:0; bottom:0; background:no-repeat 50% 0% rgba(0,0,0,.5);} +.profile-viewer .data {display:block; position:relative; margin-left:15px; padding-right:15px; padding-bottom:20px;} +.profile-viewer .data > .control {text-align:center; margin-bottom:20px; border-bottom:1px solid rgba(255,255,255,.5);} +.profile-viewer .data > .control a {display:inline-block; vertical-align:middle; padding:10px 0; color:#fff;} +.profile-viewer .data > .control a + a {margin-left:-4px;} +.profile-viewer .data > .control a + a:before {content:" · "; margin:0 10px; font-size:15px; vertical-align:middle;} +.profile-viewer .prof {display:block; position:relative;} + +.profile-viewer .prof .thumb-item {display:block; position:relative; max-width:100px; margin:0 auto; transform:scale(.9); -webkit-transform:scale(.9); text-align:center;} +.profile-viewer .prof .thumb-item a {display:block; background:rgba(0,0,0,.3); border:1px solid rgba(255,255,255,.3);} +.profile-viewer .prof .thumb-item em {display:block;} +.profile-viewer .prof .thumb-item em img {display:block;} +.profile-viewer .prof .thumb-item .name {display:block; padding:3px 10px; background:#000; color:#fff;} + +.profile-viewer .prof-data {text-align:center; padding:10px 0 30px;;} +.profile-viewer .prof-data p {padding-left:0;} +.profile-viewer .prof-data p:before {display:none;} +.profile-viewer .prof-data p strong {display:block; position:relative; font-size:16px;} +.profile-viewer .prof-data p + p {margin-top:5px; opacity:.7;} + +.profile-viewer .comment {padding:20px 0; text-align:center; font-size:18px; font-family:'HeirofLight';} +.profile-viewer .comment:before, +.profile-viewer .comment:after {content:'"';} +.profile-viewer .status-bar dd p {padding-left:0;} +.profile-viewer .status-bar dd p:before {display:none;} +.profile-viewer .mypage-box {padding:10px 0;} +.profile-viewer .no-data {text-align:center; opacity:.5; padding:50px 0;} + +@media all and (max-width:520px) { + .profile-viewer {padding-left:0;} + .profile-viewer .body {display:none;} + .profile-viewer .tab-box-group {margin:0 -15px;} +} + + +/** Quick Navigation **/ +#character_profile {position:relative; padding:20px 0 100px;} +#character_profile #profile_menu {display:block; position:absolute; top:20px; right:10px; z-index:10;} +#character_profile #profile_menu a {display:block; position:relative; margin-bottom:5px;} + +.relation-member-list {margin-top:30px;} +.relation-box .ui-btn {margin-top:10px;} + +.pattern-box .inner-wrap {} +.pattern-box .inner-wrap h4 {line-height:1.2; font-size:16px; margin-bottom:10px; border-left:4px solid #fff; padding-left:.5em;} + +@media all and (max-width:520px) { + .tbl-scroll {overflow:auto;} + .tbl-scroll > table {width:620px;} +} + +.inventory-list {display:block; position:relative; overflow:hidden;} +.inventory-list li {display:block; float:left; padding:5px;} +.inventory-list a {display:block; position:relative; width:40px; height:40px; overflow:hidden;} +.inventory-list a img {display:block; position:relative; margin:0 auto;} +.inventory-list a i {display:block; position:absolute; right:1px; bottom:1px; background:rgba(0,0,0,.5); min-width:15px; height:15px; line-height:15px; color:#fff; font-size:10px; font-weight:800; padding:0 1px; text-align:center; z-index:2; box-sizing:border-box; border:none !important;} +.inventory-list a i.present:before {content:"\e99f"; font-family:'icon'; font-weight:400;} + +.title-list {display:block; position:relative; padding:20px 0;} +.title-list p {padding:5px;} +.title-list .item {display:inline-block; min-width:25%; padding: 5px; box-sizing:border-box; text-align:left; vertical-align:middle;} + + +/******************************** + 쪽지란 +********************************/ + +.memo-inner {padding:30px 10px; max-width:640px; margin:0 auto; min-height:300px; overflow:hidden;} +.ui-list-control {text-align:right; padding-bottom:20px;} + +.message-item {display:block; position:relative; max-width:90%; width:570px; box-sizing:border-box; clear:both; margin-top:10px;} +.message-item.index {max-width:100%; width:100%;} +.message-item .thumb {display:block; position:absolute; top:0; width:80px; text-align:center;} +.message-item .thumb em {display:block; position:relative; padding-top:100%; background:no-repeat 50% 50%; background-size:cover; border:2px solid #656567;} +.message-item .thumb strong {display:block; padding-top:5px; font-size:13px; word-break:break-all;} +.message-item .con {display:block; position:relative; min-height:70px; padding:15px; box-sizing:border-box;} +.message-item .con:after {content:""; display:block; position:absolute; width:0; height:0; border:20px solid transparent; border-top-width:10px; border-bottom-width:0; top:0;} +.message-item .con .txt {font-size:14px;} +.message-item .con .txt a {display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; word-wrap:break-word; clear:both; overflow:hidden; height:2.8em; text-overflow:ellipsis; color:#fff;} +.message-item .con .control {display:block; margin-top:10px; font-size:12px; opacity:.7;} +.message-item .con .control .ui-btn {height:auto; line-height:1.2; padding:0 10px; border-radius:9em;} + +.message-item.you {padding-left:105px; float:left;} +.message-item.you .thumb {left:0;} +.message-item.you .con {background:rgba(103,103,103,.8); border-radius:0 10px 10px 10px;} +.message-item.you .con:after {border-top-color:rgba(103,103,103,.8); border-top-width:10px; border-right-width:0; left:-20px;} +.message-item.you .con .control {text-align:right;} + +.message-item.me {padding-right:105px; float:right; margin-top:20px;} +.message-item.me .thumb {right:0;} +.message-item.me .con {background:rgba(62,62,62,.8); border-radius:10px 0 10px 10px;} +.message-item.me .con:after {border-top-color:rgba(62,62,62,.8); border-left-width:0; right:-20px;} +.message-item.me .con .control {text-align:left;} + +.ui-chatting-list:after {content:""; display:block; clear:both; min-height:200px;} +.ui-memo-write {border-top:1px solid rgba(255,255,255,.2); padding-top:20px;} + +@media all and (max-width:640px) { + .message-item .thumb {width:60px;} + .message-item .con {min-height:50px; padding:10px;} + .message-item .con:after {border-left-width:10px; border-right-width:10px;} + .message-item .con .txt {font-size:12px;} + + .message-item.you {padding-left:75px;} + .message-item.you .con:after {left:-10px;} + + .message-item.me {padding-right:75px;} + .message-item.me .con:after {right:-10px;} +} +@media all and (max-width:420px) { + .message-item {max-width:100%;} + + .message-item.you {padding-left:75px;} + .message-item.me {padding-right:75px;} +} + + +/****************************************** + 관계란 스타일 +*******************************************/ + +.relation-member-list { position: relative; } +.relation-member-list > li { position:relative; padding-left: 90px; min-height:120px; margin-bottom: 20px; } +.relation-member-list .ui-thumb { position: absolute; top: 0; left: 0; width: 80px; overflow: hidden; } +.relation-member-list .rm-name { font-size: 14px; font-weight: 800; padding-right: 150px; padding-left: 10px; } + +.relation-member-list .rm-like-style { position: absolute; right: 0; top: 0;width: 80px; } +.relation-member-list .rm-like-style i { display: block; width: 13px; height: 15px; position: relative; float: left; margin: 0 1px;} +.relation-member-list .rm-like-style i:before { content: "\e9da"; font-family: 'icon'; font-style: normal; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; font-family: 'icon'; } +.relation-member-list .memo { font-family: 'Dotum'; padding:10px; margin: 5px 0; line-height: 1.2em; min-height: 30px; } + +.relation-member-list ol { display: block; position: relative; clear: both; text-align: right;padding-right: 10px; } +.relation-member-list ol li { display: inline-block; } +.relation-member-list ol li a.btn-log { display: block; position: relative; width: 20px; height: 20px; margin: 0 auto; } +.relation-member-list ol li a.btn-log:before { content: "\e925"; font-family: 'icon'; font-size: 15px; font-style: normal; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; font-family: 'icon'; } + + + +.relation-member-list .modify-box { display: none; } +.relation-member-list .state-modify { } +.relation-member-list .state-modify .rm-like-style, +.relation-member-list .state-modify .memo .ori-content, +.relation-member-list .state-modify ol { display: none; } +.relation-member-list .state-modify .modify-box { display: block; } + + +@media all and (max-width: 500px) { + .relation-member-list .rm-name { padding-right: 0; font-size: 13px; } + .relation-member-list .rm-like-style { position: relative; width: auto;overflow: hidden; } + + .relation-member-list > li { padding-left:0px; } + .relation-member-list .ui-thumb { width: 50px; } + .relation-member-list .info { min-height: 62px; margin-left: 60px; } +} diff --git a/AvocadoEdition/theme/basic/css/shop.css b/AvocadoEdition/theme/basic/css/shop.css new file mode 100644 index 0000000..da7c9a5 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/shop.css @@ -0,0 +1,64 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 상점 디자인 스타일 정의 +-------------------------------------------------- + - 최초 작성일 :2021.08.15 + - 최초 작성자 :아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + +#shop_page {position:relative; min-height:500px;} + + +/********************************* + NPC +**********************************/ + +#shop_npc {position:absolute; top:0px; bottom:0; left:0px; width:300px; z-index:1;} + + +/****************************************** + 아이템 정보 출력 +*******************************************/ + +#item_info {display:block; position:absolute; bottom:0px; left:0px; width:300px; box-sizing:border-box; z-index:3;} +#item_info #item_talk {} +#item_info #btn_buy {display:block; margin-right:-11px;} + +#item_simple_viewer {position:relative;} +#item_simple_viewer .item-thumb {position:absolute; top:0; left:0; width:50px;} +#item_simple_viewer .item-name {margin-left:60px; min-height:50px; font-size:16px; padding:5px 0; font-weight:600; box-sizing:border-box;} +#item_simple_viewer .item-name sup {display:block; margin:0; padding-top:4px; font-size:12px;} +#item_simple_viewer .item-content {padding:15px 0; font-size:11px;} + + +/********************************* + 아이템 리스트 +**********************************/ + +#item_list_box {position:relative; margin-left:350px; box-sizing:border-box; padding:20px 0; z-index:2;} +#shop_item_list {display:block; position:relative; box-sizing:border-box; z-index:0;} +#shop_item_list > ul {display:block; position:relative; box-sizing:border-box;} +#shop_item_list > ul li {display:inline-block; position:relative; text-align:center; margin-bottom:10px; font-size:11px;} +#shop_item_list li a {display:block; position:relative;} +#shop_item_list li span {display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;} +#shop_paging {display:block;} +#shop_paging .pg_wrap .pg_page {border:none;} + +#shop_cate {overflow:hidden; padding-bottom:20px;} +#shop_cate ul {display:block; overflow:hidden;} +#shop_cate li {float:left;} + + +/********************************* + 반응형 처리 +**********************************/ + +@media all and (max-width:640px) { + #shop_npc {display:none;} + #item_info {position:fixed; top:auto; left:0; right:0; bottom:0; width:auto; height:auto; z-index:9;} + #body .fix-layout {padding:0;} + #shop_page {height:auto; padding:10px;} + #item_list_box {margin-left:0;} +} \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/css/style.css b/AvocadoEdition/theme/basic/css/style.css new file mode 100644 index 0000000..36cf7f2 --- /dev/null +++ b/AvocadoEdition/theme/basic/css/style.css @@ -0,0 +1,436 @@ +@charset "utf-8"; +/* ----------------------------------------------- + * 사이트 전체 기본 스타일 정의 +-------------------------------------------------- + - 최초 작성일 :2021.08.15 + - 최초 작성자 :아보카도 + - 최종 수정일 : + - 최종 수정자 : +--------------------------------------------------*/ + + +/********************************* + 기본 스타일 +**********************************/ + +html, +body {height:100%;} + +body {line-height:1.5em; font-size:12px;} +caption {display:none;} +html.single:before {content:""; display:block; position:fixed; top:0; left:0; right:0; bottom:0; z-index:-1;} + + +/********************************* + 폼 요소 스타일 +**********************************/ + +button {font-size:12px;} +.form-input {display:block; line-height:30px !important;} +input[type="file"] {padding-left:0 !important;} + +.form-input, +input[type="text"], +input[type="password"], +input[type="file"], +select {box-sizing:border-box; height:30px; border-width:1px; border-style:solid; padding:0 10px; max-width:100%; font-size:12px; line-height:1.2;} + +.form-input, +input[type="text"].full, +input[type="password"].full, +input[type="file"].full, +select.full {width:100%;} + +textarea {box-sizing:border-box; border-width:1px; border-style:solid; padding:5px; width:100%; min-height:50px; font-size:12px; resize:none;} + + +/********************************* + Ajax 검색 리스트 +**********************************/ + +.ajax-list-box {height:100px; overflow-y:auto; margin-top:10px; padding:5px;} +.ajax-list-box ul, +.ajax-list-box li {display:block; margin:0; padding:0; position:relative;} +.ajax-list-box li {margin-bottom:5px;} +.ajax-list-box li a {display:block; position:relative; padding:10px; border-radius:3px; text-decoration:none; font-size:12px;} +.ajax-list-box li a .ui-thumb {position:absolute; top:10px; left:10px; width:30px; height:30px; line-height:30px; overflow:hidden; text-align:center;} +.ajax-list-box li a .ui-thumb img {max-width:100%;} +.ajax-list-box li a .ui-info {margin-left:40px;} +.ajax-list-box .no-data {line-height:50px; text-align:center; margin-top:10px;} + + +/********************************* + 기본 라인 스타일 +**********************************/ + +hr.line {display:block; position:relative; clear:both; margin:10px 0; border:none; padding:0; height:1px;} +hr.padding {display:block; clear:both; margin:0; padding:0; border:none; height:30px;} +hr.padding.small {height:5px;} + +#bo_v_img img {height:auto !important;} + + +/******************** + TWITTER +*********************/ + +.timeline-Body {border:none; font-size:12px; } +.timeline-Widget {background:none; opacity:.8;} +.timeline-Body-notification, +.timeline-Tweet-actions, +.timeline-Header {display:none;} +.timeline-Viewport {height:100%; overflow:auto;} +.timeline-TweetList {display:block; list-style:none; margin:0; padding:0;} + +.timeline-Tweet {position:relative; padding:20px 5px 20px 0;} +.timeline-Tweet:before {content:""; display:block; position:absolute; bottom:0; left:0; right:0; height:1px; border-top-width:1px; border-top-style:dashed;} +.timeline-TweetList li:first-child .timeline-Tweet {padding-top:0;} +.timeline-Tweet .timeline-Tweet-text {padding:0 10px;} + +.timeline-Tweet-inReplyTo {display:none;} +.TweetAuthor-link {display:block; position:relative; margin-bottom:10px; font-size:13px; font-weight:400; padding:2px 5px;} +.TweetAuthor-avatar {display:none;} +.TweetAuthor-screenName {font-size:11px; opacity:.5;} +.Interstitial-cookieConsentButton {display:none;} +.Interstitial-link {display:inline-block; vertical-align:middle; padding:2px 10px; margin:3px 0;} + +.timeline-Tweet-metadata {display:block; position:relative; font-size:11px; text-align:right; padding-right:10px;} +.timeline-Tweet-metadata a { } + +.MediaCard-mediaContainer { padding-bottom:20px !important; } + +.timeline-LoadMore { display:none; } +.Emoji { width:15px; vertical-align:middle; } +.NaturalImage-image, +.CroppedImage-image {height:auto !important;} +.u-floatLeft, .u-floatRight {display:none;} + + +/************************************************************** + 버튼 +***************************************************************/ + +.ui-btn {display:inline-block; position:relative; text-align:center; border-width:1px; border-style:solid; vertical-align:middle; height:28px; padding:0 15px; box-sizing:border-box; cursor:pointer;} +a.ui-btn {line-height:26px;} +.ui-btn.small {height:25px; line-height:23px; font-size:12px;} +.ui-btn.full {width:100%;} + +.ui-btn.admin {background:#8c1e1e; color:#fff; border-color:#691010;} +.ui-btn.disable {opacity:.3;} + +.ui-btn.ico {width:15px; height:15px; text-align:left; line-height:15px; padding:0; font-size:11px; overflow:hidden; text-indent:-999px;} +.ui-btn.ico.default {width:28px; height:28px; line-height:28px;} +.ui-btn.ico:before {display:block; position:absolute; top:0; left:0; right:0; bottom:0; text-align:center; text-indent:0; font-family:'icon';} +.ui-btn.ico.big {width:40px; height:40px; line-height:40px; font-size:18px;} +.ui-btn.ico.circle {border-radius:9.0em;} + +.ui-btn.ico.del {background:#a40000; color:#fff; border:none; border-radius:2px; margin-left:5px;} +.ui-btn.ico.del:before {content:"\e9ac";} +.ui-btn.ico.camera:before {content:"\e90f";} +.ui-btn.ico.search:before {content:"\e986";} +.ui-btn.ico.exp:before {content:"\e923";} +.ui-btn.ico.search:before {content:"\e986";} + + +/************************************************************** + 기본박스 +***************************************************************/ + +.theme-box {display:block; position:relative; padding:10px; box-sizing:border-box;} + + +/************************************************************** + 테이블 +***************************************************************/ + +table {width:100%; padding:0; border-spacing:0px; border:0; border-collapse:collapse; table-layout:fixed;} +th, td {border:none;} + +.theme-form { } +.theme-form td {padding:5px; height:30px;} +.theme-form th {padding:5px 10px;} +.theme-form .frm_info {display:block; font-size:12px; padding:0 0 8px 0;} + +.theme-list {table-layout:fixed;} +.theme-list thead th {height:30px;} +.theme-list td {padding:5px; height:30px;} +.theme-list td.no-data {padding:5px; text-align:center; line-height:200px;} + + +/************************************************************** + 도움말 정보 +**************************************************************/ + +.frm_info {display:block; font-size:12px; padding:0 0 8px 0; opacity:.7;} +.status-bar .frm_info {padding:0;} + + +/************************************************************** + Status Bar +***************************************************************/ + +.status-bar {display:block;} +.status-bar dl, +.status-bar dd, +.status-bar dt {margin:0; padding:0;} +.status-bar dl {display:block; position:relative; margin:1px 0; padding-left:100px; line-height:28px;} +.status-bar dt {position:absolute; top:0; left:0;} +.status-bar dd p {position:relative;} +.status-bar dd p span {display:block; position:absolute; top:0; left:0; bottom:0; z-index:0;} +.status-bar dd p sup {display:block; position:absolute; top:0; left:0; bottom:0; z-index:0;} +.status-bar dd p i {display:block; position:relative; padding-left:5px; font-size:11px; z-index:1;} + +/** Bar Control 추가 **/ +.status-bar dl.ui-control {padding-right:60px;} +.status-bar dl dd.control {display:block; position:absolute; top:0; bottom:0; right:0; width:60px;} +.status-bar dl dd.control a {display:block; position:relative; width:50%; float:left; margin:0; padding:0; text-indent:-999px; overflow:hidden;} +.status-bar dl dd.control a:before {content:""; display:block; position:absolute; top:0; left:0; right:0; bottom:0; text-indent:0; text-align:center; font-family:'icon';} +.status-bar dl dd.control a + a {border-left-width:0;} +.status-bar dl dd.control a[data-function="plus"]:before {content:'\ea0a';} +.status-bar dl dd.control a[data-function="minus"]:before {content:'\ea0b';} + + +/************************************************************** + 배경음악 이퀄라이저 효과 +***************************************************************/ + +html.single .bgm-player {display:none !important;} + +.bgm-player {text-align:center;} +.bgm-player .title {display:inline-block; vertical-align:middle; line-height:30px; font-size:13px;} +.bgm-player ul {display:inline-block; vertical-align:middle; margin-left:10px;} +.bar-equalizer {display:inline-block; vertical-align:middle; position:relative; width:90px; height:25px; margin:0 auto; overflow:hidden; text-align:center; box-sizing:border-box; margin-left:15px;} +.bar-equalizer i {display:block; float:left; width:1px; margin-right:2px; border-radius:5px; margin-top:15px; transform:translateY(-50%); transition:height 0.3s linear; -webkit-transition:height 0.3s linear;} +.bgm-player li {display:inline-block;} +.bgm-player li a {display:block; position:relative; width:100%; height:100%; line-height:27px; text-align:left; text-indent:-999px; overflow:hidden;} +.bgm-player li a:before {content:""; display:block; position:absolute; top:0; left:0; right:0; bottom:0; text-indent:0; text-align:center; font-family:'icon'; font-size:12px;} +.bgm-player li a.play:before {content:"\ea1c";} +.bgm-player li a.stop:before {content:"\ea1e";} + + +/******************************************* + 헤더 레이아웃 +********************************************/ + +/** 디자인 설정 안할 시 */ +#no_design_gnb {padding:20px 0; text-align:center; line-height:1.5em;} +#no_design_gnb li {display:block; margin-bottom:20px;} + +.close-header #header {width:0px !important;} +.close-header #body {margin-left:0 !important;} +.close-header body {min-width:0;} + +@media all and (max-width:1000px) { + .close-header #header {width:auto !important;} +} + +#header .fix-layout {padding:0;} +#logo img {max-width:225px;} + +/** 모바일 헤더 레이아웃 */ +@media all and (max-width:1024px) { + body {width:100%;} + #logo {padding:0; z-index:0; top:auto; left:auto; transform:translateX(0) translateY(0); position:relative; text-align:center;} + #body {margin-left:0px; padding-top:50px;} + + /* 헤더 위치 */ + #header .fix-layout {padding:0;} + #header {position:fixed; top:0; left:0; right:0; bottom:auto; z-index:999; width:auto; height:50px; overflow:visible;} + + /* 메인메뉴 */ + #gnb {position:fixed; top:0; right:-280px; bottom:0; width:280px; z-index:999; overflow-y:auto;} + #gnb_control_box {position:absolute; top:50%; margin-top:-20px; right:10px; width:40px; height:40px; border-radius:100%; text-align:center;} + #gnb_control_box:before {content:""; display:inline-block; width:0; height:100%; vertical-align:middle;} + #gnb_control_box img {display:inline-block; max-width:50%; max-height:50%; vertical-align:middle; margin-left:-12%; opacity:1;} + + /* 메뉴 열고 닫기 */ + #gnb_control_box, + #gnb_control_box * {transition:all 0s ease; -webkit-transition:all 0s ease; -ms-transition:all 0s ease;} + + /* 메뉴 열렸을 시 */ + .open-gnb #gnb {right:0;} + .open-gnb #gnb_control_box {position:fixed; top:0; left:0; right:0; bottom:0; z-index:99; background:rgba(0, 0, 0, 0.5); border-radius:0; width:auto; height:auto;} + .open-gnb #gnb_control_box img {opacity:0;} +} + + +/************************************************************** + 탭 설정 +***************************************************************/ + +#tab_list {display:block; position:relative; overflow:hidden; border-bottom-width:2px; border-bottom-style:solid;} +#tab_list li {display:block; position:relative; float:left;} +#tab_list li a {display:block; position:relative; border-bottom-width:0;} +#tab_list li + li a {border-left-width:0px;} + + +/************************************************************** + 페이지 설정 +***************************************************************/ + +.pg_wrap {display:block; position:relative; text-align:center; padding:20px 0;} +.pg_wrap .pg_page {display:inline-block; position:relative; height:30px; line-height:28px; min-width:30px; box-sizing:border-box; padding:0 5px; font-size:13px; text-align:center; vertical-align:middle; border-width:1px; border-style:solid;} +.pg_wrap .pg_control {overflow:hidden; text-align:left; text-indent:-999px;} +.pg_wrap .pg_control:before {font-family:'icon'; display:block; position:absolute; top:0; left:0; right:0; bottom:0; text-indent:0; text-align:center; font-size:14px;} +.pg_wrap .pg_start, +.pg_wrap .pg_end {display:none;} +.pg_wrap .pg_prev:before {content:"\ea23";} +.pg_wrap .pg_next:before {content:"\ea24";} + + +/**************************************************** + Search Box +****************************************************/ + +.searc-sub-box {position:relative; clear:both; padding:30px 0px;} +.ui-search-box {position:relative; padding-left:100px; padding-right:80px; margin-top:5px;} +.ui-search-box .sch_category {position:absolute; top:0; left:0; width:95px; line-height:30px;} +.ui-search-box .sch_button {position:absolute; top:0; right:0; width:75px;} +.ui-search-box span {display:block; padding:0 15px;} +.ui-search-box select, +.ui-search-box input[type="text"], +.ui-search-box button {display:block; width:100%;} + + +/**************************************************** + 인벤토리 팝업 뷰 +****************************************************/ + +.inven-popup-viewer, +.inven-popup-viewer * {-webkit-transition:none; -moz-transition:none; -ms-transition:none; -o-transition:none; font-family:'Dotum';} +.inven-popup-viewer .ajax-list-box {height:auto; padding:5px; font-size:11px; word-break:keep-all; line-height:1.5;} +.inven-popup-viewer {display:none; position:fixed; top:50%; left:50%; width:300px; height:370px; margin-left:-150px; margin-top:-185px;z-index:9000; padding:25px 40px; box-sizing:border-box;} +.inven-item-box {position:relative; margin-right:25px; padding-left:25px; border-right-width:0px;} +.inven_popup_viewer_close {display:none;} +.inven-popup-on .inven_popup_viewer_close {display:block; position:fixed; top:0; left:0; right:0; bottom:0; z-index:8900; -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px);} +.inven_popup_viewer_close a {display:block; position:absolute; top:0; left:0; right:0; bottom:0; OVERFLOW:hidden; text-indent:-999px;} + +.inven-popup-viewer.default-form .inner-content {position:relative; height:100%;} +.inven-popup-viewer.default-form .inner-content .error {position:absolute; top:left:0; right:0; text-align:center; line-height:100px; font-family:'Nanum Gothic';} +.inven-popup-viewer.default-form .inner-content a {} + +.inven-popup-viewer.default-form .info {position:relative; text-align:center; padding:15px 0;} +.inven-popup-viewer.default-form .info .ui-thumb {} +.inven-popup-viewer.default-form .info .ui-thumb img {width:50px; height:50px;} + +.inven-popup-viewer.default-form .text {position:relative; } +.inven-popup-viewer.default-form .text .title {font-size:14px; text-align:center; margin-bottom:10px; padding-bottom:10px;} +.inven-popup-viewer.default-form .text .title span {display:none;} + +.inven-popup-viewer.default-form .text .item-content-box {height:170px; overflow-y:auto;} +.inven-popup-viewer.default-form .text .item-content-box div {line-height:1.4em; text-align:center;} +.inven-popup-viewer.default-form .text div.default {} +.inven-popup-viewer.default-form .text div.effect { padding-top:15px;} +.inven-popup-viewer.default-form .text div.memo { padding-top:15px;} + +.inven-popup-viewer.default-form .control-box {clear:both; position:relative; padding:10px 0 0; text-align:center;} +.inven-popup-viewer.default-form .control-box li {display:inline-block;} +.inven-popup-viewer.default-form .control-box li a {display:block; } + +.inven-popup-viewer.default-form .add-item-form {position:relative; height:30%; margin-top:10px;} +.inven-popup-viewer.default-form .add-item-form .item-info {position:relative; margin-bottom:5px;} +.inven-popup-viewer.default-form .add-item-form .item-info label {display:none;} +.inven-popup-viewer.default-form .add-item-form .item-info span {display:block; font-size:11px; padding-top:8px;} +.inven-popup-viewer.default-form .add-item-form input {width:100%; box-sizing:border-box;} +.inven-popup-viewer.default-form .add-item-form .item-input {position:relative; margin-bottom:5px;} +.inven-popup-viewer.default-form .add-item-form .ui-style-btn.type4 {position:absolute; right:87px; bottom:-44px; height:25px; line-height:25px;} + +.inven-popup-viewer.default-form .send-item-form {position:relative; height:30%;} +.inven-popup-viewer.default-form .send-item-form input, +.inven-popup-viewer.default-form .send-item-form select {width:100%; box-sizing:border-box;} +.inven-popup-viewer.default-form .send-item-form input {padding:0 10px;} +.inven-popup-viewer.default-form .send-item-form .item-input {position:relative; margin-bottom:5px;} +.inven-popup-viewer.default-form .send-item-form .ui-style-btn.type4 {position:absolute; right:87px; bottom:-44px; height:25px; line-height:25px;} + + +/**************************************************** + Top 버튼 +****************************************************/ + +#goto_top {position:fixed; right:0; bottom:0; z-index:50;} +@media all and (max-width:580px) {#goto_top {width:50px;}} + + +/**************************************************** + 서브메뉴 레이아웃 +****************************************************/ + +#submenu {display:block; position:relative; text-align:center;} +#submenu li {display:inline-block; vertical-align:middle; font-size:13px; font-weight:600; padding:8px 10px;} +#subpage {margin-top:20px;} +#subpage section {padding-bottom:50px;} + +@media all and (max-width:1024px) { + #submenu {margin:0 -10px;} + #submenu li {padding:5px; font-size:12px;} + #subpage {margin-left:0;} +} + + +/**************************************************** + 페이지 타이틀 +****************************************************/ + +.page-title {font-size:18px; padding:10px 0 20px;} +.page-title span {font-size:14px; opacity:.8; font-weight:400;} + +.sub-title {font-size:14px; padding:0 0 10px;} +.sub-title:before {content:"\e906"; display:inline-block; vertical-align:middle; font-family:'icon'; margin-right:8px;} + + +/**************************************************** + 알람 팝업 +****************************************************/ + +.ui-memo-alram-box, +.ui-call-alram-box {display:none; position:fixed; top:0; left:0; right:0; z-index:999; text-align:center;} + + +/**************************************************** + 마퀴 (우 ▶ 좌) 흐름 +****************************************************/ + +.marquee span {display:block; position:relative; overflow:hidden;} +.marquee span i:after {content:""; white-space:nowrap; padding-right:50px;} + .marquee span i {margin:0; padding-left:100%; display:inline-block; white-space:nowrap; + -webkit-animation-name:marquee; + -webkit-animation-timing-function:linear; + -webkit-animation-duration:10s; + -webkit-animation-iteration-count:infinite; + -moz-animation-name:marquee; + -moz-animation-timing-function:linear; + -moz-animation-duration:10s; + -moz-animation-iteration-count:infinite; + -ms-animation-name:marquee; + -ms-animation-timing-function:linear; + -ms-animation-duration:10s; + -ms-animation-iteration-count:infinite; + -o-animation-name:marquee; + -o-animation-timing-function:linear; + -o-animation-duration:10s; + -o-animation-iteration-count:infinite; + animation-name:marquee; + animation-timing-function:linear; + animation-duration:10s; + animation-iteration-count:infinite; +} +@-webkit-keyframes marquee { + from {-webkit-transform:translate(0%);} + 99%,to {-webkit-transform:translate(-100%);} +} +@-moz-keyframes marquee { + from {-moz-transform:translate(0%);} + 99%,to {-moz-transform:translate(-100%);} +} +@-ms-keyframes marquee { + from {-ms-transform:translate(0%);} + 99%,to {-ms-transform:translate(-100%);} +} +@-o-keyframes marquee { + from {-o-transform:translate(0%);} + 99%,to {-o-transform:translate(-100%);} +} +@keyframes marquee { + from {transform:translate(0%);} + 99%,to {transform:translate(-100%);} +} \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/enter.php b/AvocadoEdition/theme/basic/enter.php new file mode 100644 index 0000000..5863039 --- /dev/null +++ b/AvocadoEdition/theme/basic/enter.php @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + <?=$g5['title']?> + + + + + + + + + + + + + + + diff --git a/AvocadoEdition/theme/basic/extend/theme.extend.php b/AvocadoEdition/theme/basic/extend/theme.extend.php new file mode 100644 index 0000000..a528b08 --- /dev/null +++ b/AvocadoEdition/theme/basic/extend/theme.extend.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/group.php b/AvocadoEdition/theme/basic/group.php new file mode 100644 index 0000000..34f9f73 --- /dev/null +++ b/AvocadoEdition/theme/basic/group.php @@ -0,0 +1,49 @@ + + +
    + + + 'mobile' "; +if(!$is_admin) + $sql .= " and bo_use_cert = '' "; +$sql .= " order by bo_order "; +$result = sql_query($sql); +for ($i=0; $row=sql_fetch_array($result); $i++) { + $lt_style = ""; + if ($i%3 !== 0) $lt_style = "margin-left:2%"; + else $lt_style = ""; +?> +
    + +
    + + +
    + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/tail.sub.php b/AvocadoEdition/theme/basic/tail.sub.php new file mode 100644 index 0000000..7f6186a --- /dev/null +++ b/AvocadoEdition/theme/basic/tail.sub.php @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file
    ").addClass("ui-dialog ui-widget ui-widget-content ui-corner-all ui-front "+this.options.dialogClass).hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._on(this.uiDialog,{keydown:function(t){if(this.options.closeOnEscape&&!t.isDefaultPrevented()&&t.keyCode&&t.keyCode===e.ui.keyCode.ESCAPE){t.preventDefault(),this.close(t);return}if(t.keyCode!==e.ui.keyCode.TAB)return;var n=this.uiDialog.find(":tabbable"),r=n.filter(":first"),i=n.filter(":last");t.target!==i[0]&&t.target!==this.uiDialog[0]||!!t.shiftKey?(t.target===r[0]||t.target===this.uiDialog[0])&&t.shiftKey&&(i.focus(1),t.preventDefault()):(r.focus(1),t.preventDefault())},mousedown:function(e){this._moveToTop(e)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var t;this.uiDialogTitlebar=e("
    ").addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(this.uiDialog),this._on(this.uiDialogTitlebar,{mousedown:function(t){e(t.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.focus()}}),this.uiDialogTitlebarClose=e("").button({label:this.options.closeText,icons:{primary:"ui-icon-closethick"},text:!1}).addClass("ui-dialog-titlebar-close").appendTo(this.uiDialogTitlebar),this._on(this.uiDialogTitlebarClose,{click:function(e){e.preventDefault(),this.close(e)}}),t=e("").uniqueId().addClass("ui-dialog-title").prependTo(this.uiDialogTitlebar),this._title(t),this.uiDialog.attr({"aria-labelledby":t.attr("id")})},_title:function(e){this.options.title||e.html(" "),e.text(this.options.title)},_createButtonPane:function(){this.uiDialogButtonPane=e("
    ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),this.uiButtonSet=e("
    ").addClass("ui-dialog-buttonset").appendTo(this.uiDialogButtonPane),this._createButtons()},_createButtons:function(){var t=this,n=this.options.buttons;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty();if(e.isEmptyObject(n)||e.isArray(n)&&!n.length){this.uiDialog.removeClass("ui-dialog-buttons");return}e.each(n,function(n,r){var i,s;r=e.isFunction(r)?{click:r,text:n}:r,r=e.extend({type:"button"},r),i=r.click,r.click=function(){i.apply(t.element[0],arguments)},s={icons:r.icons,text:r.showText},delete r.icons,delete r.showText,e("",r).button(s).appendTo(t.uiButtonSet)}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog)},_makeDraggable:function(){function r(e){return{position:e.position,offset:e.offset}}var t=this,n=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(n,i){e(this).addClass("ui-dialog-dragging"),t._blockFrames(),t._trigger("dragStart",n,r(i))},drag:function(e,n){t._trigger("drag",e,r(n))},stop:function(i,s){n.position=[s.position.left-t.document.scrollLeft(),s.position.top-t.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),t._unblockFrames(),t._trigger("dragStop",i,r(s))}})},_makeResizable:function(){function o(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}var t=this,n=this.options,r=n.resizable,i=this.uiDialog.css("position"),s=typeof r=="string"?r:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:n.maxWidth,maxHeight:n.maxHeight,minWidth:n.minWidth,minHeight:this._minHeight(),handles:s,start:function(n,r){e(this).addClass("ui-dialog-resizing"),t._blockFrames(),t._trigger("resizeStart",n,o(r))},resize:function(e,n){t._trigger("resize",e,o(n))},stop:function(r,i){n.height=e(this).height(),n.width=e(this).width(),e(this).removeClass("ui-dialog-resizing"),t._unblockFrames(),t._trigger("resizeStop",r,o(i))}}).css("position",i)},_minHeight:function(){var e=this.options;return e.height==="auto"?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(){var e=this.uiDialog.is(":visible");e||this.uiDialog.show(),this.uiDialog.position(this.options.position),e||this.uiDialog.hide()},_setOptions:function(t){var i=this,s=!1,o={};e.each(t,function(e,t){i._setOption(e,t),e in n&&(s=!0),e in r&&(o[e]=t)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",o)},_setOption:function(e,t){var n,r,i=this.uiDialog;e==="dialogClass"&&i.removeClass(this.options.dialogClass).addClass(t);if(e==="disabled")return;this._super(e,t),e==="appendTo"&&this.uiDialog.appendTo(this._appendTo()),e==="buttons"&&this._createButtons(),e==="closeText"&&this.uiDialogTitlebarClose.button({label:""+t}),e==="draggable"&&(n=i.is(":data(ui-draggable)"),n&&!t&&i.draggable("destroy"),!n&&t&&this._makeDraggable()),e==="position"&&this._position(),e==="resizable"&&(r=i.is(":data(ui-resizable)"),r&&!t&&i.resizable("destroy"),r&&typeof t=="string"&&i.resizable("option","handles",t),!r&&t!==!1&&this._makeResizable()),e==="title"&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title"))},_size:function(){var e,t,n,r=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),r.minWidth>r.width&&(r.width=r.minWidth),e=this.uiDialog.css({height:"auto",width:r.width}).outerHeight(),t=Math.max(0,r.minHeight-e),n=typeof r.maxHeight=="number"?Math.max(0,r.maxHeight-e):"none",r.height==="auto"?this.element.css({minHeight:t,maxHeight:n,height:"auto"}):this.element.height(Math.max(0,r.height-e)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var t=e(this);return e("
    ").css({position:"absolute",width:t.outerWidth(),height:t.outerHeight()}).appendTo(t.parent()).offset(t.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_createOverlay:function(){if(!this.options.modal)return;e.ui.dialog.overlayInstances||this._delay(function(){e.ui.dialog.overlayInstances&&this.document.bind("focusin.dialog",function(t){!e(t.target).closest(".ui-dialog").length&&!e(t.target).closest(".ui-datepicker").length&&(t.preventDefault(),e(".ui-dialog:visible:last .ui-dialog-content").data("ui-dialog")._focusTabbable())})}),this.overlay=e("
    ").addClass("ui-widget-overlay ui-front").appendTo(this._appendTo()),this._on(this.overlay,{mousedown:"_keepFocus"}),e.ui.dialog.overlayInstances++},_destroyOverlay:function(){if(!this.options.modal)return;this.overlay&&(e.ui.dialog.overlayInstances--,e.ui.dialog.overlayInstances||this.document.unbind("focusin.dialog"),this.overlay.remove(),this.overlay=null)}}),e.ui.dialog.overlayInstances=0,e.uiBackCompat!==!1&&e.widget("ui.dialog",e.ui.dialog,{_position:function(){var t=this.options.position,n=[],r=[0,0],i;if(t){if(typeof t=="string"||typeof t=="object"&&"0"in t)n=t.split?t.split(" "):[t[0],t[1]],n.length===1&&(n[1]=n[0]),e.each(["left","top"],function(e,t){+n[e]===n[e]&&(r[e]=n[e],n[e]=t)}),t={my:n[0]+(r[0]<0?r[0]:"+"+r[0])+" "+n[1]+(r[1]<0?r[1]:"+"+r[1]),at:n.join(" ")};t=e.extend({},e.ui.dialog.prototype.options.position,t)}else t=e.ui.dialog.prototype.options.position;i=this.uiDialog.is(":visible"),i||this.uiDialog.show(),this.uiDialog.position(t),i||this.uiDialog.hide()}})}(jQuery),function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}}(jQuery),function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}}(jQuery),function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}}(jQuery),function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}}(jQuery),function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
    ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}}(jQuery),function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}}(jQuery),function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}}(jQuery),function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}}(jQuery),function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}}(jQuery),function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u,outerHeight:a.outerHeight*u,outerWidth:a.outerWidth*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r,i,s,o=e(this),u=["position","top","bottom","left","right","width","height","overflow","opacity"],a=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],l=["fontSize"],c=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),d=t.restore||p!=="effect",v=t.scale||"both",m=t.origin||["middle","center"],g=o.css("position"),y=d?u:a,b={height:0,width:0,outerHeight:0,outerWidth:0};p==="show"&&o.show(),r={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},t.mode==="toggle"&&p==="show"?(o.from=t.to||b,o.to=t.from||r):(o.from=t.from||(p==="show"?b:r),o.to=t.to||(p==="hide"?b:r)),s={from:{y:o.from.height/r.height,x:o.from.width/r.width},to:{y:o.to.height/r.height,x:o.to.width/r.width}};if(v==="box"||v==="both")s.from.y!==s.to.y&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,s.from.y,o.from),o.to=e.effects.setTransition(o,c,s.to.y,o.to)),s.from.x!==s.to.x&&(y=y.concat(h),o.from=e.effects.setTransition(o,h,s.from.x,o.from),o.to=e.effects.setTransition(o,h,s.to.x,o.to));(v==="content"||v==="both")&&s.from.y!==s.to.y&&(y=y.concat(l).concat(f),o.from=e.effects.setTransition(o,l,s.from.y,o.from),o.to=e.effects.setTransition(o,l,s.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(i=e.effects.getBaseline(m,r),o.from.top=(r.outerHeight-o.outerHeight())*i.y,o.from.left=(r.outerWidth-o.outerWidth())*i.x,o.to.top=(r.outerHeight-o.to.outerHeight)*i.y,o.to.left=(r.outerWidth-o.to.outerWidth)*i.x),o.css(o.from);if(v==="content"||v==="both")c=c.concat(["marginTop","marginBottom"]).concat(l),h=h.concat(["marginLeft","marginRight"]),f=u.concat(c).concat(h),o.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width(),outerHeight:n.outerHeight(),outerWidth:n.outerWidth()};d&&e.effects.save(n,f),n.from={height:r.height*s.from.y,width:r.width*s.from.x,outerHeight:r.outerHeight*s.from.y,outerWidth:r.outerWidth*s.from.x},n.to={height:r.height*s.to.y,width:r.width*s.to.x,outerHeight:r.height*s.to.y,outerWidth:r.width*s.to.x},s.from.y!==s.to.y&&(n.from=e.effects.setTransition(n,c,s.from.y,n.from),n.to=e.effects.setTransition(n,c,s.to.y,n.to)),s.from.x!==s.to.x&&(n.from=e.effects.setTransition(n,h,s.from.x,n.from),n.to=e.effects.setTransition(n,h,s.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){d&&e.effects.restore(n,f)})});o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o.to.opacity===0&&o.css("opacity",o.from.opacity),p==="hide"&&o.hide(),e.effects.restore(o,y),d||(g==="static"?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,n){var r=parseInt(n,10),i=e?o.to.left:o.to.top;return n==="auto"?i+"px":r+i+"px"})})),e.effects.removeWrapper(o),n()}})}}(jQuery),function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}}(jQuery),function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}}(jQuery),function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e("
    ").appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}}(jQuery),function(e,t){e.widget("ui.menu",{version:"1.10.1",defaultElement:"
      ",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var n=e(t.target).closest(".ui-menu-item");!this.mouseHandled&&n.not(".ui-state-disabled").length&&(this.mouseHandled=!0,this.select(t),n.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus);r.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),r=t.prev("a"),i=e("").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-\u2014\u2013\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(e,t){e==="icons"&&this.element.find(".ui-menu-icon").removeClass(this.options.icons.submenu).addClass(t.submenu),this._super(e,t)},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()
    "),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};lr(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)a&&(v<0||v0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)10&&i<11,t.innerHTML="",n.removeChild(t)}()}(jQuery),function(e,t){e.widget("ui.progressbar",{version:"1.10.1",options:{max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min}),this.valueDiv=e("
    ").appendTo(this.element),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){if(e===t)return this.options.value;this.options.value=this._constrainedValue(e),this._refreshValue()},_constrainedValue:function(e){return e===t&&(e=this.options.value),this.indeterminate=e===!1,typeof e!="number"&&(e=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,e))},_setOptions:function(e){var t=e.value;delete e.value,this._super(e),this.options.value=this._constrainedValue(t),this._refreshValue()},_setOption:function(e,t){e==="max"&&(t=Math.max(this.min,t)),this._super(e,t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var t=this.options.value,n=this._percentage();this.valueDiv.toggle(this.indeterminate||t>this.min).toggleClass("ui-corner-right",t===this.options.max).width(n.toFixed(0)+"%"),this.element.toggleClass("ui-progressbar-indeterminate",this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=e("
    ").appendTo(this.valueDiv))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":t}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==t&&(this.oldValue=t,this._trigger("change")),t===this.options.max&&this._trigger("complete")}})}(jQuery),function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.10.1",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"),this._refresh(),this._setOption("disabled",this.options.disabled),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var t,n,r=this.options,i=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),s="",o=[];n=r.values&&r.values.length||1,i.length>n&&(i.slice(n).remove(),i=i.slice(0,n));for(t=i.length;t
    ").appendTo(this.element),n="ui-slider-range ui-widget-header ui-corner-all"):this.range.removeClass("ui-slider-range-min ui-slider-range-max").css({left:"",bottom:""}),this.range.addClass(n+(t.range==="min"||t.range==="max"?" ui-slider-range-"+t.range:""))):this.range=e([])},_setupEvents:function(){var e=this.handles.add(this.range).filter("a");this._off(e),this._on(e,this._handleEvents),this._hoverable(e),this._focusable(e)},_destroy:function(){this.handles.remove(),this.range.remove(),this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-widget ui-widget-content ui-corner-all"),this._mouseDestroy()},_mouseCapture:function(t){var n,r,i,s,o,u,a,f,l=this,c=this.options;return c.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),n={x:t.pageX,y:t.pageY},r=this._normValueFromMouse(n),i=this._valueMax()-this._valueMin()+1,this.handles.each(function(t){var n=Math.abs(r-l.values(t));if(i>n||i===n&&(t===l._lastChangedValue||l.values(t)===c.min))i=n,s=e(this),o=t}),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))},_handleEvents:{keydown:function(t){var r,i,s,o,u=e(t.target).data("ui-slider-handle-index");switch(t.keyCode){case e.ui.keyCode.HOME:case e.ui.keyCode.END:case e.ui.keyCode.PAGE_UP:case e.ui.keyCode.PAGE_DOWN:case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:t.preventDefault();if(!this._keySliding){this._keySliding=!0,e(t.target).addClass("ui-state-active"),r=this._start(t,u);if(r===!1)return}}o=this.options.step,this.options.values&&this.options.values.length?i=s=this.values(u):i=s=this.value();switch(t.keyCode){case e.ui.keyCode.HOME:s=this._valueMin();break;case e.ui.keyCode.END:s=this._valueMax();break;case e.ui.keyCode.PAGE_UP:s=this._trimAlignValue(i+(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.PAGE_DOWN:s=this._trimAlignValue(i-(this._valueMax()-this._valueMin())/n);break;case e.ui.keyCode.UP:case e.ui.keyCode.RIGHT:if(i===this._valueMax())return;s=this._trimAlignValue(i+o);break;case e.ui.keyCode.DOWN:case e.ui.keyCode.LEFT:if(i===this._valueMin())return;s=this._trimAlignValue(i-o)}this._slide(t,u,s)},click:function(e){e.preventDefault()},keyup:function(t){var n=e(t.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(t,n),this._change(t,n),e(t.target).removeClass("ui-state-active"))}}})}(jQuery),function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.10.1",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&decodeURIComponent(e.href.replace(r,""))===decodeURIComponent(location.href.replace(r,""))}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.10.1",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),n.active=this._initialActive(),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(n.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_initialActive:function(){var t=this.options.active,n=this.options.collapsible,r=location.hash.substring(1);if(t===null){r&&this.tabs.each(function(n,i){if(e(i).attr("aria-controls")===r)return t=n,!1}),t===null&&(t=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(t===null||t===-1)t=this.tabs.length?0:!1}return t!==!1&&(t=this.tabs.index(this.tabs.eq(t)),t===-1&&(t=n?!1:0)),!n&&t===!1&&this.anchors.length&&(t=0),t},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
    ").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r=this.element.parent();t==="fill"?(n=r.height(),n-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}})}(jQuery),function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.10.1",options:{content:function(){var t=e(this).attr("title")||"";return e("").text(t).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).addBack().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=this.delayedShow=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;clearInterval(this.delayedShow),i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
    ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
    ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})}(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-process.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-process.js new file mode 100644 index 0000000..8a6b929 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-process.js @@ -0,0 +1,172 @@ +/* + * jQuery File Upload Processing Plugin 1.3.0 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2012, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* jshint nomen:false */ +/* global define, window */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + './jquery.fileupload' + ], factory); + } else { + // Browser globals: + factory( + window.jQuery + ); + } +}(function ($) { + 'use strict'; + + var originalAdd = $.blueimp.fileupload.prototype.options.add; + + // The File Upload Processing plugin extends the fileupload widget + // with file processing functionality: + $.widget('blueimp.fileupload', $.blueimp.fileupload, { + + options: { + // The list of processing actions: + processQueue: [ + /* + { + action: 'log', + type: 'debug' + } + */ + ], + add: function (e, data) { + var $this = $(this); + data.process(function () { + return $this.fileupload('process', data); + }); + originalAdd.call(this, e, data); + } + }, + + processActions: { + /* + log: function (data, options) { + console[options.type]( + 'Processing "' + data.files[data.index].name + '"' + ); + } + */ + }, + + _processFile: function (data, originalData) { + var that = this, + dfd = $.Deferred().resolveWith(that, [data]), + chain = dfd.promise(); + this._trigger('process', null, data); + $.each(data.processQueue, function (i, settings) { + var func = function (data) { + if (originalData.errorThrown) { + return $.Deferred() + .rejectWith(that, [originalData]).promise(); + } + return that.processActions[settings.action].call( + that, + data, + settings + ); + }; + chain = chain.pipe(func, settings.always && func); + }); + chain + .done(function () { + that._trigger('processdone', null, data); + that._trigger('processalways', null, data); + }) + .fail(function () { + that._trigger('processfail', null, data); + that._trigger('processalways', null, data); + }); + return chain; + }, + + // Replaces the settings of each processQueue item that + // are strings starting with an "@", using the remaining + // substring as key for the option map, + // e.g. "@autoUpload" is replaced with options.autoUpload: + _transformProcessQueue: function (options) { + var processQueue = []; + $.each(options.processQueue, function () { + var settings = {}, + action = this.action, + prefix = this.prefix === true ? action : this.prefix; + $.each(this, function (key, value) { + if ($.type(value) === 'string' && + value.charAt(0) === '@') { + settings[key] = options[ + value.slice(1) || (prefix ? prefix + + key.charAt(0).toUpperCase() + key.slice(1) : key) + ]; + } else { + settings[key] = value; + } + + }); + processQueue.push(settings); + }); + options.processQueue = processQueue; + }, + + // Returns the number of files currently in the processsing queue: + processing: function () { + return this._processing; + }, + + // Processes the files given as files property of the data parameter, + // returns a Promise object that allows to bind callbacks: + process: function (data) { + var that = this, + options = $.extend({}, this.options, data); + if (options.processQueue && options.processQueue.length) { + this._transformProcessQueue(options); + if (this._processing === 0) { + this._trigger('processstart'); + } + $.each(data.files, function (index) { + var opts = index ? $.extend({}, options) : options, + func = function () { + if (data.errorThrown) { + return $.Deferred() + .rejectWith(that, [data]).promise(); + } + return that._processFile(opts, data); + }; + opts.index = index; + that._processing += 1; + that._processingQueue = that._processingQueue.pipe(func, func) + .always(function () { + that._processing -= 1; + if (that._processing === 0) { + that._trigger('processstop'); + } + }); + }); + } + return this._processingQueue; + }, + + _create: function () { + this._super(); + this._processing = 0; + this._processingQueue = $.Deferred().resolveWith(this) + .promise(); + } + + }); + +})); diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-ui.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-ui.js new file mode 100644 index 0000000..b9dab7d --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload-ui.js @@ -0,0 +1,699 @@ +/* + * jQuery File Upload User Interface Plugin 9.5.2 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* jshint nomen:false */ +/* global define, window */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + 'tmpl', + './jquery.fileupload-image', + './jquery.fileupload-audio', + './jquery.fileupload-video', + './jquery.fileupload-validate' + ], factory); + } else { + // Browser globals: + factory( + window.jQuery, + window.tmpl + ); + } +}(function ($, tmpl) { + 'use strict'; + + $.blueimp.fileupload.prototype._specialOptions.push( + 'filesContainer', + 'uploadTemplateId', + 'downloadTemplateId' + ); + + // The UI version extends the file upload widget + // and adds complete user interface interaction: + $.widget('blueimp.fileupload', $.blueimp.fileupload, { + + options: { + // By default, files added to the widget are uploaded as soon + // as the user clicks on the start buttons. To enable automatic + // uploads, set the following option to true: + autoUpload: false, + // The ID of the upload template: + uploadTemplateId: 'template-upload', + // The ID of the download template: + downloadTemplateId: 'template-download', + // The container for the list of files. If undefined, it is set to + // an element with class "files" inside of the widget element: + filesContainer: undefined, + // By default, files are appended to the files container. + // Set the following option to true, to prepend files instead: + prependFiles: false, + // The expected data type of the upload response, sets the dataType + // option of the $.ajax upload requests: + dataType: 'json', + + // Function returning the current number of files, + // used by the maxNumberOfFiles validation: + getNumberOfFiles: function () { + return this.filesContainer.children() + .not('.processing').length; + }, + + // Callback to retrieve the list of files from the server response: + getFilesFromResponse: function (data) { + if (data.result && $.isArray(data.result.files)) { + return data.result.files; + } + return []; + }, + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop or add API call). + // See the basic file upload widget for more information: + add: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var $this = $(this), + that = $this.data('blueimp-fileupload') || + $this.data('fileupload'), + options = that.options; + data.context = that._renderUpload(data.files) + .data('data', data) + .addClass('processing'); + options.filesContainer[ + options.prependFiles ? 'prepend' : 'append' + ](data.context); + that._forceReflow(data.context); + that._transition(data.context); + data.process(function () { + return $this.fileupload('process', data); + }).always(function () { + data.context.each(function (index) { + $(this).find('.size').text( + that._formatFileSize(data.files[index].size) + ); + }).removeClass('processing'); + that._renderPreviews(data); + }).done(function () { + data.context.find('.start').prop('disabled', false); + if ((that._trigger('added', e, data) !== false) && + (options.autoUpload || data.autoUpload) && + data.autoUpload !== false) { + data.submit(); + } + }).fail(function () { + if (data.files.error) { + data.context.each(function (index) { + var error = data.files[index].error; + if (error) { + $(this).find('.error').text(error); + } + }); + } + }); + }, + // Callback for the start of each file upload request: + send: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'); + if (data.context && data.dataType && + data.dataType.substr(0, 6) === 'iframe') { + // Iframe Transport does not support progress events. + // In lack of an indeterminate progress bar, we set + // the progress to 100%, showing the full animated bar: + data.context + .find('.progress').addClass( + !$.support.transition && 'progress-animated' + ) + .attr('aria-valuenow', 100) + .children().first().css( + 'width', + '100%' + ); + } + return that._trigger('sent', e, data); + }, + // Callback for successful uploads: + done: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + getFilesFromResponse = data.getFilesFromResponse || + that.options.getFilesFromResponse, + files = getFilesFromResponse(data), + template, + deferred; + if (data.context) { + data.context.each(function (index) { + var file = files[index] || + {error: 'Empty file upload result'}; + deferred = that._addFinishedDeferreds(); + that._transition($(this)).done( + function () { + var node = $(this); + template = that._renderDownload([file]) + .replaceAll(node); + that._forceReflow(template); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('completed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); + } + ); + } + ); + }); + } else { + template = that._renderDownload(files)[ + that.options.prependFiles ? 'prependTo' : 'appendTo' + ](that.options.filesContainer); + that._forceReflow(template); + deferred = that._addFinishedDeferreds(); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('completed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); + } + ); + } + }, + // Callback for failed (abort or error) uploads: + fail: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + template, + deferred; + if (data.context) { + data.context.each(function (index) { + if (data.errorThrown !== 'abort') { + var file = data.files[index]; + file.error = file.error || data.errorThrown || + true; + deferred = that._addFinishedDeferreds(); + that._transition($(this)).done( + function () { + var node = $(this); + template = that._renderDownload([file]) + .replaceAll(node); + that._forceReflow(template); + that._transition(template).done( + function () { + data.context = $(this); + that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); + } + ); + } + ); + } else { + deferred = that._addFinishedDeferreds(); + that._transition($(this)).done( + function () { + $(this).remove(); + that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); + } + ); + } + }); + } else if (data.errorThrown !== 'abort') { + data.context = that._renderUpload(data.files)[ + that.options.prependFiles ? 'prependTo' : 'appendTo' + ](that.options.filesContainer) + .data('data', data); + that._forceReflow(data.context); + deferred = that._addFinishedDeferreds(); + that._transition(data.context).done( + function () { + data.context = $(this); + that._trigger('failed', e, data); + that._trigger('finished', e, data); + deferred.resolve(); + } + ); + } else { + that._trigger('failed', e, data); + that._trigger('finished', e, data); + that._addFinishedDeferreds().resolve(); + } + }, + // Callback for upload progress events: + progress: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var progress = Math.floor(data.loaded / data.total * 100); + if (data.context) { + data.context.each(function () { + $(this).find('.progress') + .attr('aria-valuenow', progress) + .children().first().css( + 'width', + progress + '%' + ); + }); + } + }, + // Callback for global upload progress events: + progressall: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var $this = $(this), + progress = Math.floor(data.loaded / data.total * 100), + globalProgressNode = $this.find('.fileupload-progress'), + extendedProgressNode = globalProgressNode + .find('.progress-extended'); + if (extendedProgressNode.length) { + extendedProgressNode.html( + ($this.data('blueimp-fileupload') || $this.data('fileupload')) + ._renderExtendedProgress(data) + ); + } + globalProgressNode + .find('.progress') + .attr('aria-valuenow', progress) + .children().first().css( + 'width', + progress + '%' + ); + }, + // Callback for uploads start, equivalent to the global ajaxStart event: + start: function (e) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'); + that._resetFinishedDeferreds(); + that._transition($(this).find('.fileupload-progress')).done( + function () { + that._trigger('started', e); + } + ); + }, + // Callback for uploads stop, equivalent to the global ajaxStop event: + stop: function (e) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + deferred = that._addFinishedDeferreds(); + $.when.apply($, that._getFinishedDeferreds()) + .done(function () { + that._trigger('stopped', e); + }); + that._transition($(this).find('.fileupload-progress')).done( + function () { + $(this).find('.progress') + .attr('aria-valuenow', '0') + .children().first().css('width', '0%'); + $(this).find('.progress-extended').html(' '); + deferred.resolve(); + } + ); + }, + processstart: function (e) { + if (e.isDefaultPrevented()) { + return false; + } + $(this).addClass('fileupload-processing'); + }, + processstop: function (e) { + if (e.isDefaultPrevented()) { + return false; + } + $(this).removeClass('fileupload-processing'); + }, + // Callback for file deletion: + destroy: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + var that = $(this).data('blueimp-fileupload') || + $(this).data('fileupload'), + removeNode = function () { + that._transition(data.context).done( + function () { + $(this).remove(); + that._trigger('destroyed', e, data); + } + ); + }; + if (data.url) { + data.dataType = data.dataType || that.options.dataType; + $.ajax(data).done(removeNode).fail(function () { + that._trigger('destroyfailed', e, data); + }); + } else { + removeNode(); + } + } + }, + + _resetFinishedDeferreds: function () { + this._finishedUploads = []; + }, + + _addFinishedDeferreds: function (deferred) { + if (!deferred) { + deferred = $.Deferred(); + } + this._finishedUploads.push(deferred); + return deferred; + }, + + _getFinishedDeferreds: function () { + return this._finishedUploads; + }, + + // Link handler, that allows to download files + // by drag & drop of the links to the desktop: + _enableDragToDesktop: function () { + var link = $(this), + url = link.prop('href'), + name = link.prop('download'), + type = 'application/octet-stream'; + link.bind('dragstart', function (e) { + try { + e.originalEvent.dataTransfer.setData( + 'DownloadURL', + [type, name, url].join(':') + ); + } catch (ignore) {} + }); + }, + + _formatFileSize: function (bytes) { + if (typeof bytes !== 'number') { + return ''; + } + if (bytes >= 1000000000) { + return (bytes / 1000000000).toFixed(2) + ' GB'; + } + if (bytes >= 1000000) { + return (bytes / 1000000).toFixed(2) + ' MB'; + } + return (bytes / 1000).toFixed(2) + ' KB'; + }, + + _formatBitrate: function (bits) { + if (typeof bits !== 'number') { + return ''; + } + if (bits >= 1000000000) { + return (bits / 1000000000).toFixed(2) + ' Gbit/s'; + } + if (bits >= 1000000) { + return (bits / 1000000).toFixed(2) + ' Mbit/s'; + } + if (bits >= 1000) { + return (bits / 1000).toFixed(2) + ' kbit/s'; + } + return bits.toFixed(2) + ' bit/s'; + }, + + _formatTime: function (seconds) { + var date = new Date(seconds * 1000), + days = Math.floor(seconds / 86400); + days = days ? days + 'd ' : ''; + return days + + ('0' + date.getUTCHours()).slice(-2) + ':' + + ('0' + date.getUTCMinutes()).slice(-2) + ':' + + ('0' + date.getUTCSeconds()).slice(-2); + }, + + _formatPercentage: function (floatValue) { + return (floatValue * 100).toFixed(2) + ' %'; + }, + + _renderExtendedProgress: function (data) { + return this._formatBitrate(data.bitrate) + ' | ' + + this._formatTime( + (data.total - data.loaded) * 8 / data.bitrate + ) + ' | ' + + this._formatPercentage( + data.loaded / data.total + ) + ' | ' + + this._formatFileSize(data.loaded) + ' / ' + + this._formatFileSize(data.total); + }, + + _renderTemplate: function (func, files) { + if (!func) { + return $(); + } + var result = func({ + files: files, + formatFileSize: this._formatFileSize, + options: this.options + }); + if (result instanceof $) { + return result; + } + return $(this.options.templatesContainer).html(result).children(); + }, + + _renderPreviews: function (data) { + data.context.find('.preview').each(function (index, elm) { + $(elm).append(data.files[index].preview); + }); + }, + + _renderUpload: function (files) { + return this._renderTemplate( + this.options.uploadTemplate, + files + ); + }, + + _renderDownload: function (files) { + return this._renderTemplate( + this.options.downloadTemplate, + files + ).find('a[download]').each(this._enableDragToDesktop).end(); + }, + + _startHandler: function (e) { + e.preventDefault(); + var button = $(e.currentTarget), + template = button.closest('.template-upload'), + data = template.data('data'); + button.prop('disabled', true); + if (data && data.submit) { + data.submit(); + } + }, + + _cancelHandler: function (e) { + e.preventDefault(); + var template = $(e.currentTarget) + .closest('.template-upload,.template-download'), + data = template.data('data') || {}; + data.context = data.context || template; + if (data.abort) { + data.abort(); + } else { + data.errorThrown = 'abort'; + this._trigger('fail', e, data); + } + }, + + _deleteHandler: function (e) { + e.preventDefault(); + var button = $(e.currentTarget); + this._trigger('destroy', e, $.extend({ + context: button.closest('.template-download'), + type: 'DELETE' + }, button.data())); + }, + + _forceReflow: function (node) { + return $.support.transition && node.length && + node[0].offsetWidth; + }, + + _transition: function (node) { + var dfd = $.Deferred(); + if ($.support.transition && node.hasClass('fade') && node.is(':visible')) { + node.bind( + $.support.transition.end, + function (e) { + // Make sure we don't respond to other transitions events + // in the container element, e.g. from button elements: + if (e.target === node[0]) { + node.unbind($.support.transition.end); + dfd.resolveWith(node); + } + } + ).toggleClass('in'); + } else { + node.toggleClass('in'); + dfd.resolveWith(node); + } + return dfd; + }, + + _initButtonBarEventHandlers: function () { + var fileUploadButtonBar = this.element.find('.fileupload-buttonbar'), + filesList = this.options.filesContainer; + this._on(fileUploadButtonBar.find('.start'), { + click: function (e) { + e.preventDefault(); + filesList.find('.start').click(); + } + }); + this._on(fileUploadButtonBar.find('.cancel'), { + click: function (e) { + e.preventDefault(); + filesList.find('.cancel').click(); + } + }); + this._on(fileUploadButtonBar.find('.delete'), { + click: function (e) { + e.preventDefault(); + filesList.find('.toggle:checked') + .closest('.template-download') + .find('.delete').click(); + fileUploadButtonBar.find('.toggle') + .prop('checked', false); + } + }); + this._on(fileUploadButtonBar.find('.toggle'), { + change: function (e) { + filesList.find('.toggle').prop( + 'checked', + $(e.currentTarget).is(':checked') + ); + } + }); + }, + + _destroyButtonBarEventHandlers: function () { + this._off( + this.element.find('.fileupload-buttonbar') + .find('.start, .cancel, .delete'), + 'click' + ); + this._off( + this.element.find('.fileupload-buttonbar .toggle'), + 'change.' + ); + }, + + _initEventHandlers: function () { + this._super(); + this._on(this.options.filesContainer, { + 'click .start': this._startHandler, + 'click .cancel': this._cancelHandler, + 'click .delete': this._deleteHandler + }); + this._initButtonBarEventHandlers(); + }, + + _destroyEventHandlers: function () { + this._destroyButtonBarEventHandlers(); + this._off(this.options.filesContainer, 'click'); + this._super(); + }, + + _enableFileInputButton: function () { + this.element.find('.fileinput-button input') + .prop('disabled', false) + .parent().removeClass('disabled'); + }, + + _disableFileInputButton: function () { + this.element.find('.fileinput-button input') + .prop('disabled', true) + .parent().addClass('disabled'); + }, + + _initTemplates: function () { + var options = this.options; + options.templatesContainer = this.document[0].createElement( + options.filesContainer.prop('nodeName') + ); + if (tmpl) { + if (options.uploadTemplateId) { + options.uploadTemplate = tmpl(options.uploadTemplateId); + } + if (options.downloadTemplateId) { + options.downloadTemplate = tmpl(options.downloadTemplateId); + } + } + }, + + _initFilesContainer: function () { + var options = this.options; + if (options.filesContainer === undefined) { + options.filesContainer = this.element.find('.files'); + } else if (!(options.filesContainer instanceof $)) { + options.filesContainer = $(options.filesContainer); + } + }, + + _initSpecialOptions: function () { + this._super(); + this._initFilesContainer(); + this._initTemplates(); + }, + + _create: function () { + this._super(); + this._resetFinishedDeferreds(); + if (!$.support.fileInput) { + this._disableFileInputButton(); + } + }, + + enable: function () { + var wasDisabled = false; + if (this.options.disabled) { + wasDisabled = true; + } + this._super(); + if (wasDisabled) { + this.element.find('input, button').prop('disabled', false); + this._enableFileInputButton(); + } + }, + + disable: function () { + if (!this.options.disabled) { + this.element.find('input, button').prop('disabled', true); + this._disableFileInputButton(); + } + this._super(); + } + + }); + +})); diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload.js new file mode 100644 index 0000000..69430ec --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.fileupload.js @@ -0,0 +1,1462 @@ +/* + * jQuery File Upload Plugin 5.40.1 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2010, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* jshint nomen:false */ +/* global define, window, document, location, Blob, FormData */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define([ + 'jquery', + 'jquery.ui.widget' + ], factory); + } else { + // Browser globals: + factory(window.jQuery); + } +}(function ($) { + 'use strict'; + + // Detect file input support, based on + // http://viljamis.com/blog/2012/file-upload-support-on-mobile/ + $.support.fileInput = !(new RegExp( + // Handle devices which give false positives for the feature detection: + '(Android (1\\.[0156]|2\\.[01]))' + + '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' + + '|(w(eb)?OSBrowser)|(webOS)' + + '|(Kindle/(1\\.0|2\\.[05]|3\\.0))' + ).test(window.navigator.userAgent) || + // Feature detection for all other devices: + $('').prop('disabled')); + + // The FileReader API is not actually used, but works as feature detection, + // as some Safari versions (5?) support XHR file uploads via the FormData API, + // but not non-multipart XHR file uploads. + // window.XMLHttpRequestUpload is not available on IE10, so we check for + // window.ProgressEvent instead to detect XHR2 file upload capability: + $.support.xhrFileUpload = !!(window.ProgressEvent && window.FileReader); + $.support.xhrFormDataFileUpload = !!window.FormData; + + // Detect support for Blob slicing (required for chunked uploads): + $.support.blobSlice = window.Blob && (Blob.prototype.slice || + Blob.prototype.webkitSlice || Blob.prototype.mozSlice); + + // The fileupload widget listens for change events on file input fields defined + // via fileInput setting and paste or drop events of the given dropZone. + // In addition to the default jQuery Widget methods, the fileupload widget + // exposes the "add" and "send" methods, to add or directly send files using + // the fileupload API. + // By default, files added via file input selection, paste, drag & drop or + // "add" method are uploaded immediately, but it is possible to override + // the "add" callback option to queue file uploads. + $.widget('blueimp.fileupload', { + + options: { + // The drop target element(s), by the default the complete document. + // Set to null to disable drag & drop support: + dropZone: $(document), + // The paste target element(s), by the default the complete document. + // Set to null to disable paste support: + pasteZone: $(document), + // The file input field(s), that are listened to for change events. + // If undefined, it is set to the file input fields inside + // of the widget element on plugin initialization. + // Set to null to disable the change listener. + fileInput: undefined, + // By default, the file input field is replaced with a clone after + // each input field change event. This is required for iframe transport + // queues and allows change events to be fired for the same file + // selection, but can be disabled by setting the following option to false: + replaceFileInput: true, + // The parameter name for the file form data (the request argument name). + // If undefined or empty, the name property of the file input field is + // used, or "files[]" if the file input name property is also empty, + // can be a string or an array of strings: + paramName: undefined, + // By default, each file of a selection is uploaded using an individual + // request for XHR type uploads. Set to false to upload file + // selections in one request each: + singleFileUploads: true, + // To limit the number of files uploaded with one XHR request, + // set the following option to an integer greater than 0: + limitMultiFileUploads: undefined, + // The following option limits the number of files uploaded with one + // XHR request to keep the request size under or equal to the defined + // limit in bytes: + limitMultiFileUploadSize: undefined, + // Multipart file uploads add a number of bytes to each uploaded file, + // therefore the following option adds an overhead for each file used + // in the limitMultiFileUploadSize configuration: + limitMultiFileUploadSizeOverhead: 512, + // Set the following option to true to issue all file upload requests + // in a sequential order: + sequentialUploads: false, + // To limit the number of concurrent uploads, + // set the following option to an integer greater than 0: + limitConcurrentUploads: undefined, + // Set the following option to true to force iframe transport uploads: + forceIframeTransport: false, + // Set the following option to the location of a redirect url on the + // origin server, for cross-domain iframe transport uploads: + redirect: undefined, + // The parameter name for the redirect url, sent as part of the form + // data and set to 'redirect' if this option is empty: + redirectParamName: undefined, + // Set the following option to the location of a postMessage window, + // to enable postMessage transport uploads: + postMessage: undefined, + // By default, XHR file uploads are sent as multipart/form-data. + // The iframe transport is always using multipart/form-data. + // Set to false to enable non-multipart XHR uploads: + multipart: true, + // To upload large files in smaller chunks, set the following option + // to a preferred maximum chunk size. If set to 0, null or undefined, + // or the browser does not support the required Blob API, files will + // be uploaded as a whole. + maxChunkSize: undefined, + // When a non-multipart upload or a chunked multipart upload has been + // aborted, this option can be used to resume the upload by setting + // it to the size of the already uploaded bytes. This option is most + // useful when modifying the options object inside of the "add" or + // "send" callbacks, as the options are cloned for each file upload. + uploadedBytes: undefined, + // By default, failed (abort or error) file uploads are removed from the + // global progress calculation. Set the following option to false to + // prevent recalculating the global progress data: + recalculateProgress: true, + // Interval in milliseconds to calculate and trigger progress events: + progressInterval: 100, + // Interval in milliseconds to calculate progress bitrate: + bitrateInterval: 500, + // By default, uploads are started automatically when adding files: + autoUpload: true, + + // Error and info messages: + messages: { + uploadedBytes: 'Uploaded bytes exceed file size' + }, + + // Translation function, gets the message key to be translated + // and an object with context specific data as arguments: + i18n: function (message, context) { + message = this.messages[message] || message.toString(); + if (context) { + $.each(context, function (key, value) { + message = message.replace('{' + key + '}', value); + }); + } + return message; + }, + + // Additional form data to be sent along with the file uploads can be set + // using this option, which accepts an array of objects with name and + // value properties, a function returning such an array, a FormData + // object (for XHR file uploads), or a simple object. + // The form of the first fileInput is given as parameter to the function: + formData: function (form) { + return form.serializeArray(); + }, + + // The add callback is invoked as soon as files are added to the fileupload + // widget (via file input selection, drag & drop, paste or add API call). + // If the singleFileUploads option is enabled, this callback will be + // called once for each file in the selection for XHR file uploads, else + // once for each file selection. + // + // The upload starts when the submit method is invoked on the data parameter. + // The data object contains a files property holding the added files + // and allows you to override plugin options as well as define ajax settings. + // + // Listeners for this callback can also be bound the following way: + // .bind('fileuploadadd', func); + // + // data.submit() returns a Promise object and allows to attach additional + // handlers using jQuery's Deferred callbacks: + // data.submit().done(func).fail(func).always(func); + add: function (e, data) { + if (e.isDefaultPrevented()) { + return false; + } + if (data.autoUpload || (data.autoUpload !== false && + $(this).fileupload('option', 'autoUpload'))) { + data.process().done(function () { + data.submit(); + }); + } + }, + + // Other callbacks: + + // Callback for the submit event of each file upload: + // submit: function (e, data) {}, // .bind('fileuploadsubmit', func); + + // Callback for the start of each file upload request: + // send: function (e, data) {}, // .bind('fileuploadsend', func); + + // Callback for successful uploads: + // done: function (e, data) {}, // .bind('fileuploaddone', func); + + // Callback for failed (abort or error) uploads: + // fail: function (e, data) {}, // .bind('fileuploadfail', func); + + // Callback for completed (success, abort or error) requests: + // always: function (e, data) {}, // .bind('fileuploadalways', func); + + // Callback for upload progress events: + // progress: function (e, data) {}, // .bind('fileuploadprogress', func); + + // Callback for global upload progress events: + // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func); + + // Callback for uploads start, equivalent to the global ajaxStart event: + // start: function (e) {}, // .bind('fileuploadstart', func); + + // Callback for uploads stop, equivalent to the global ajaxStop event: + // stop: function (e) {}, // .bind('fileuploadstop', func); + + // Callback for change events of the fileInput(s): + // change: function (e, data) {}, // .bind('fileuploadchange', func); + + // Callback for paste events to the pasteZone(s): + // paste: function (e, data) {}, // .bind('fileuploadpaste', func); + + // Callback for drop events of the dropZone(s): + // drop: function (e, data) {}, // .bind('fileuploaddrop', func); + + // Callback for dragover events of the dropZone(s): + // dragover: function (e) {}, // .bind('fileuploaddragover', func); + + // Callback for the start of each chunk upload request: + // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func); + + // Callback for successful chunk uploads: + // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func); + + // Callback for failed (abort or error) chunk uploads: + // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func); + + // Callback for completed (success, abort or error) chunk upload requests: + // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func); + + // The plugin options are used as settings object for the ajax calls. + // The following are jQuery ajax settings required for the file uploads: + processData: false, + contentType: false, + cache: false, + container_el : null //사용자추가 + }, + + // A list of options that require reinitializing event listeners and/or + // special initialization code: + _specialOptions: [ + 'fileInput', + 'dropZone', + 'pasteZone', + 'multipart', + 'forceIframeTransport' + ], + + _blobSlice: $.support.blobSlice && function () { + var slice = this.slice || this.webkitSlice || this.mozSlice; + return slice.apply(this, arguments); + }, + + _BitrateTimer: function () { + this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime()); + this.loaded = 0; + this.bitrate = 0; + this.getBitrate = function (now, loaded, interval) { + var timeDiff = now - this.timestamp; + if (!this.bitrate || !interval || timeDiff > interval) { + this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8; + this.loaded = loaded; + this.timestamp = now; + } + return this.bitrate; + }; + }, + + _isXHRUpload: function (options) { + return !options.forceIframeTransport && + ((!options.multipart && $.support.xhrFileUpload) || + $.support.xhrFormDataFileUpload); + }, + + _getFormData: function (options) { + var formData; + if ($.type(options.formData) === 'function') { + return options.formData(options.form); + } + if ($.isArray(options.formData)) { + return options.formData; + } + if ($.type(options.formData) === 'object') { + formData = []; + $.each(options.formData, function (name, value) { + formData.push({name: name, value: value}); + }); + return formData; + } + return []; + }, + + _getTotal: function (files) { + var total = 0; + $.each(files, function (index, file) { + total += file.size || 1; + }); + + return total; + }, + + _initProgressObject: function (obj) { + var progress = { + loaded: 0, + total: 0, + bitrate: 0 + }; + if (obj._progress) { + $.extend(obj._progress, progress); + } else { + obj._progress = progress; + } + }, + + _initResponseObject: function (obj) { + var prop; + if (obj._response) { + for (prop in obj._response) { + if (obj._response.hasOwnProperty(prop)) { + delete obj._response[prop]; + } + } + } else { + obj._response = {}; + } + }, + + _onProgress: function (e, data) { + if (e.lengthComputable) { + var now = ((Date.now) ? Date.now() : (new Date()).getTime()), + loaded; + if (data._time && data.progressInterval && + (now - data._time < data.progressInterval) && + e.loaded !== e.total) { + return; + } + data._time = now; + loaded = Math.floor( + e.loaded / e.total * (data.chunkSize || data._progress.total) + ) + (data.uploadedBytes || 0); + // Add the difference from the previously loaded state + // to the global loaded counter: + this._progress.loaded += (loaded - data._progress.loaded); + this._progress.bitrate = this._bitrateTimer.getBitrate( + now, + this._progress.loaded, + data.bitrateInterval + ); + data._progress.loaded = data.loaded = loaded; + data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate( + now, + loaded, + data.bitrateInterval + ); + // Trigger a custom progress event with a total data property set + // to the file size(s) of the current upload and a loaded data + // property calculated accordingly: + this._trigger( + 'progress', + $.Event('progress', {delegatedEvent: e}), + data + ); + // Trigger a global progress event for all current file uploads, + // including ajax calls queued for sequential file uploads: + this._trigger( + 'progressall', + $.Event('progressall', {delegatedEvent: e}), + this._progress + ); + } + }, + + _initProgressListener: function (options) { + var that = this, + xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr(); + // Accesss to the native XHR object is required to add event listeners + // for the upload progress event: + if (xhr.upload) { + $(xhr.upload).bind('progress', function (e) { + var oe = e.originalEvent; + // Make sure the progress event properties get copied over: + e.lengthComputable = oe.lengthComputable; + e.loaded = oe.loaded; + e.total = oe.total; + that._onProgress(e, options); + }); + options.xhr = function () { + return xhr; + }; + } + }, + + _isInstanceOf: function (type, obj) { + // Cross-frame instanceof check + return Object.prototype.toString.call(obj) === '[object ' + type + ']'; + }, + + _initXHRData: function (options) { + var that = this, + formData, + file = options.files[0], + // Ignore non-multipart setting if not supported: + multipart = options.multipart || !$.support.xhrFileUpload, + paramName = $.type(options.paramName) === 'array' ? + options.paramName[0] : options.paramName; + options.headers = $.extend({}, options.headers); + if (options.contentRange) { + options.headers['Content-Range'] = options.contentRange; + } + if (!multipart || options.blob || !this._isInstanceOf('File', file)) { + options.headers['Content-Disposition'] = 'attachment; filename="' + + encodeURI(file.name) + '"'; + } + if (!multipart) { + options.contentType = file.type || 'application/octet-stream'; + options.data = options.blob || file; + } else if ($.support.xhrFormDataFileUpload) { + if (options.postMessage) { + // window.postMessage does not allow sending FormData + // objects, so we just add the File/Blob objects to + // the formData array and let the postMessage window + // create the FormData object out of this array: + formData = this._getFormData(options); + if (options.blob) { + formData.push({ + name: paramName, + value: options.blob + }); + } else { + $.each(options.files, function (index, file) { + formData.push({ + name: ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, + value: file + }); + }); + } + } else { + if (that._isInstanceOf('FormData', options.formData)) { + formData = options.formData; + } else { + formData = new FormData(); + $.each(this._getFormData(options), function (index, field) { + formData.append(field.name, field.value); + }); + } + if (options.blob) { + formData.append(paramName, options.blob, file.name); + } else { + $.each(options.files, function (index, file) { + // This check allows the tests to run with + // dummy objects: + if (that._isInstanceOf('File', file) || + that._isInstanceOf('Blob', file)) { + formData.append( + ($.type(options.paramName) === 'array' && + options.paramName[index]) || paramName, + file, + file.uploadName || file.name + ); + } + }); + } + } + options.data = formData; + } + // Blob reference is not needed anymore, free memory: + options.blob = null; + }, + + _initIframeSettings: function (options) { + var targetHost = $('').prop('href', options.url).prop('host'); + // Setting the dataType to iframe enables the iframe transport: + options.dataType = 'iframe ' + (options.dataType || ''); + // The iframe transport accepts a serialized array as form data: + options.formData = this._getFormData(options); + // Add redirect url to form data on cross-domain uploads: + if (options.redirect && targetHost && targetHost !== location.host) { + options.formData.push({ + name: options.redirectParamName || 'redirect', + value: options.redirect + }); + } + }, + + _initDataSettings: function (options) { + if (this._isXHRUpload(options)) { + if (!this._chunkedUpload(options, true)) { + if (!options.data) { + this._initXHRData(options); + } + this._initProgressListener(options); + } + if (options.postMessage) { + // Setting the dataType to postmessage enables the + // postMessage transport: + options.dataType = 'postmessage ' + (options.dataType || ''); + } + } else { + this._initIframeSettings(options); + } + }, + + _getParamName: function (options) { + var fileInput = $(options.fileInput), + paramName = options.paramName; + if (!paramName) { + paramName = []; + fileInput.each(function () { + var input = $(this), + name = input.prop('name') || 'files[]', + i = (input.prop('files') || [1]).length; + while (i) { + paramName.push(name); + i -= 1; + } + }); + if (!paramName.length) { + paramName = [fileInput.prop('name') || 'files[]']; + } + } else if (!$.isArray(paramName)) { + paramName = [paramName]; + } + return paramName; + }, + + _initFormSettings: function (options) { + // Retrieve missing options from the input field and the + // associated form, if available: + if (!options.form || !options.form.length) { + options.form = $(options.fileInput.prop('form')); + // If the given file input doesn't have an associated form, + // use the default widget file input's form: + if (!options.form.length) { + options.form = $(this.options.fileInput.prop('form')); + } + } + options.paramName = this._getParamName(options); + if (!options.url) { + options.url = options.form.prop('action') || location.href; + } + // The HTTP request method must be "POST" or "PUT": + options.type = (options.type || + ($.type(options.form.prop('method')) === 'string' && + options.form.prop('method')) || '' + ).toUpperCase(); + if (options.type !== 'POST' && options.type !== 'PUT' && + options.type !== 'PATCH') { + options.type = 'POST'; + } + if (!options.formAcceptCharset) { + options.formAcceptCharset = options.form.attr('accept-charset'); + } + }, + + _getAJAXSettings: function (data) { + var options = $.extend({}, this.options, data); + this._initFormSettings(options); + this._initDataSettings(options); + return options; + }, + + // jQuery 1.6 doesn't provide .state(), + // while jQuery 1.8+ removed .isRejected() and .isResolved(): + _getDeferredState: function (deferred) { + if (deferred.state) { + return deferred.state(); + } + if (deferred.isResolved()) { + return 'resolved'; + } + if (deferred.isRejected()) { + return 'rejected'; + } + return 'pending'; + }, + + // Maps jqXHR callbacks to the equivalent + // methods of the given Promise object: + _enhancePromise: function (promise) { + promise.success = promise.done; + promise.error = promise.fail; + promise.complete = promise.always; + return promise; + }, + + // Creates and returns a Promise object enhanced with + // the jqXHR methods abort, success, error and complete: + _getXHRPromise: function (resolveOrReject, context, args) { + var dfd = $.Deferred(), + promise = dfd.promise(); + context = context || this.options.context || promise; + if (resolveOrReject === true) { + dfd.resolveWith(context, args); + } else if (resolveOrReject === false) { + dfd.rejectWith(context, args); + } + promise.abort = dfd.promise; + return this._enhancePromise(promise); + }, + + // Adds convenience methods to the data callback argument: + _addConvenienceMethods: function (e, data) { + var that = this, + getPromise = function (args) { + return $.Deferred().resolveWith(that, args).promise(); + }; + data.process = function (resolveFunc, rejectFunc) { + if (resolveFunc || rejectFunc) { + data._processQueue = this._processQueue = + (this._processQueue || getPromise([this])).pipe( + function () { + if (data.errorThrown) { + return $.Deferred() + .rejectWith(that, [data]).promise(); + } + return getPromise(arguments); + } + ).pipe(resolveFunc, rejectFunc); + } + return this._processQueue || getPromise([this]); + }; + data.submit = function () { + if (this.state() !== 'pending') { + data.jqXHR = this.jqXHR = + (that._trigger( + 'submit', + $.Event('submit', {delegatedEvent: e}), + this + ) !== false) && that._onSend(e, this); + } + return this.jqXHR || that._getXHRPromise(); + }; + data.abort = function () { + if (this.jqXHR) { + return this.jqXHR.abort(); + } + this.errorThrown = 'abort'; + that._trigger('fail', null, this); + return that._getXHRPromise(false); + }; + data.state = function () { + if (this.jqXHR) { + return that._getDeferredState(this.jqXHR); + } + if (this._processQueue) { + return that._getDeferredState(this._processQueue); + } + }; + data.processing = function () { + return !this.jqXHR && this._processQueue && that + ._getDeferredState(this._processQueue) === 'pending'; + }; + data.progress = function () { + return this._progress; + }; + data.response = function () { + return this._response; + }; + }, + + // Parses the Range header from the server response + // and returns the uploaded bytes: + _getUploadedBytes: function (jqXHR) { + var range = jqXHR.getResponseHeader('Range'), + parts = range && range.split('-'), + upperBytesPos = parts && parts.length > 1 && + parseInt(parts[1], 10); + return upperBytesPos && upperBytesPos + 1; + }, + + // Uploads a file in multiple, sequential requests + // by splitting the file up in multiple blob chunks. + // If the second parameter is true, only tests if the file + // should be uploaded in chunks, but does not invoke any + // upload requests: + _chunkedUpload: function (options, testOnly) { + options.uploadedBytes = options.uploadedBytes || 0; + var that = this, + file = options.files[0], + fs = file.size, + ub = options.uploadedBytes, + mcs = options.maxChunkSize || fs, + slice = this._blobSlice, + dfd = $.Deferred(), + promise = dfd.promise(), + jqXHR, + upload; + if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) || + options.data) { + return false; + } + if (testOnly) { + return true; + } + if (ub >= fs) { + file.error = options.i18n('uploadedBytes'); + return this._getXHRPromise( + false, + options.context, + [null, 'error', file.error] + ); + } + // The chunk upload method: + upload = function () { + // Clone the options object for each chunk upload: + var o = $.extend({}, options), + currentLoaded = o._progress.loaded; + o.blob = slice.call( + file, + ub, + ub + mcs, + file.type + ); + // Store the current chunk size, as the blob itself + // will be dereferenced after data processing: + o.chunkSize = o.blob.size; + // Expose the chunk bytes position range: + o.contentRange = 'bytes ' + ub + '-' + + (ub + o.chunkSize - 1) + '/' + fs; + // Process the upload data (the blob and potential form data): + that._initXHRData(o); + // Add progress listeners for this chunk upload: + that._initProgressListener(o); + jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) || + that._getXHRPromise(false, o.context)) + .done(function (result, textStatus, jqXHR) { + ub = that._getUploadedBytes(jqXHR) || + (ub + o.chunkSize); + // Create a progress event if no final progress event + // with loaded equaling total has been triggered + // for this chunk: + if (currentLoaded + o.chunkSize - o._progress.loaded) { + that._onProgress($.Event('progress', { + lengthComputable: true, + loaded: ub - o.uploadedBytes, + total: ub - o.uploadedBytes + }), o); + } + options.uploadedBytes = o.uploadedBytes = ub; + o.result = result; + o.textStatus = textStatus; + o.jqXHR = jqXHR; + that._trigger('chunkdone', null, o); + that._trigger('chunkalways', null, o); + if (ub < fs) { + // File upload not yet complete, + // continue with the next chunk: + upload(); + } else { + dfd.resolveWith( + o.context, + [result, textStatus, jqXHR] + ); + } + }) + .fail(function (jqXHR, textStatus, errorThrown) { + o.jqXHR = jqXHR; + o.textStatus = textStatus; + o.errorThrown = errorThrown; + that._trigger('chunkfail', null, o); + that._trigger('chunkalways', null, o); + dfd.rejectWith( + o.context, + [jqXHR, textStatus, errorThrown] + ); + }); + }; + this._enhancePromise(promise); + promise.abort = function () { + return jqXHR.abort(); + }; + upload(); + return promise; + }, + + _beforeSend: function (e, data) { + if (this._active === 0) { + // the start callback is triggered when an upload starts + // and no other uploads are currently running, + // equivalent to the global ajaxStart event: + this._trigger('start'); + // Set timer for global bitrate progress calculation: + this._bitrateTimer = new this._BitrateTimer(); + // Reset the global progress values: + this._progress.loaded = this._progress.total = 0; + this._progress.bitrate = 0; + } + // Make sure the container objects for the .response() and + // .progress() methods on the data object are available + // and reset to their initial state: + this._initResponseObject(data); + this._initProgressObject(data); + data._progress.loaded = data.loaded = data.uploadedBytes || 0; + data._progress.total = data.total = this._getTotal(data.files) || 1; + data._progress.bitrate = data.bitrate = 0; + this._active += 1; + // Initialize the global progress values: + this._progress.loaded += data.loaded; + this._progress.total += data.total; + }, + + _onDone: function (result, textStatus, jqXHR, options) { + var total = options._progress.total, + response = options._response; + if (options._progress.loaded < total) { + // Create a progress event if no final progress event + // with loaded equaling total has been triggered: + this._onProgress($.Event('progress', { + lengthComputable: true, + loaded: total, + total: total + }), options); + } + response.result = options.result = result; + response.textStatus = options.textStatus = textStatus; + response.jqXHR = options.jqXHR = jqXHR; + this._trigger('done', null, options); + }, + + _onFail: function (jqXHR, textStatus, errorThrown, options) { + var response = options._response; + if (options.recalculateProgress) { + // Remove the failed (error or abort) file upload from + // the global progress calculation: + this._progress.loaded -= options._progress.loaded; + this._progress.total -= options._progress.total; + } + response.jqXHR = options.jqXHR = jqXHR; + response.textStatus = options.textStatus = textStatus; + response.errorThrown = options.errorThrown = errorThrown; + this._trigger('fail', null, options); + }, + + _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) { + // jqXHRorResult, textStatus and jqXHRorError are added to the + // options object via done and fail callbacks + this._trigger('always', null, options); + }, + + _onSend: function (e, data) { + if (!data.submit) { + this._addConvenienceMethods(e, data); + } + var that = this, + jqXHR, + aborted, + slot, + pipe, + options = that._getAJAXSettings(data), + send = function () { + that._sending += 1; + // Set timer for bitrate progress calculation: + options._bitrateTimer = new that._BitrateTimer(); + jqXHR = jqXHR || ( + ((aborted || that._trigger( + 'send', + $.Event('send', {delegatedEvent: e}), + options + ) === false) && + that._getXHRPromise(false, options.context, aborted)) || + that._chunkedUpload(options) || $.ajax(options) + ).done(function (result, textStatus, jqXHR) { + that._onDone(result, textStatus, jqXHR, options); + }).fail(function (jqXHR, textStatus, errorThrown) { + that._onFail(jqXHR, textStatus, errorThrown, options); + }).always(function (jqXHRorResult, textStatus, jqXHRorError) { + that._onAlways( + jqXHRorResult, + textStatus, + jqXHRorError, + options + ); + that._sending -= 1; + that._active -= 1; + if (options.limitConcurrentUploads && + options.limitConcurrentUploads > that._sending) { + // Start the next queued upload, + // that has not been aborted: + var nextSlot = that._slots.shift(); + while (nextSlot) { + if (that._getDeferredState(nextSlot) === 'pending') { + nextSlot.resolve(); + break; + } + nextSlot = that._slots.shift(); + } + } + if (that._active === 0) { + // The stop callback is triggered when all uploads have + // been completed, equivalent to the global ajaxStop event: + that._trigger('stop'); + } + }); + return jqXHR; + }; + this._beforeSend(e, options); + if (this.options.sequentialUploads || + (this.options.limitConcurrentUploads && + this.options.limitConcurrentUploads <= this._sending)) { + if (this.options.limitConcurrentUploads > 1) { + slot = $.Deferred(); + this._slots.push(slot); + pipe = slot.pipe(send); + } else { + this._sequence = this._sequence.pipe(send, send); + pipe = this._sequence; + } + // Return the piped Promise object, enhanced with an abort method, + // which is delegated to the jqXHR object of the current upload, + // and jqXHR callbacks mapped to the equivalent Promise methods: + pipe.abort = function () { + aborted = [undefined, 'abort', 'abort']; + if (!jqXHR) { + if (slot) { + slot.rejectWith(options.context, aborted); + } + return send(); + } + return jqXHR.abort(); + }; + return this._enhancePromise(pipe); + } + return send(); + }, + + _onAdd: function (e, data) { + var that = this, + result = true, + options = $.extend({}, this.options, data), + files = data.files, + filesLength = files.length, + limit = options.limitMultiFileUploads, + limitSize = options.limitMultiFileUploadSize, + overhead = options.limitMultiFileUploadSizeOverhead, + batchSize = 0, + paramName = this._getParamName(options), + paramNameSet, + paramNameSlice, + fileSet, + i, + j = 0; + + if ( options.limit_filesLength && filesLength > options.limit_filesLength) + { + filesLength = options.limit_filesLength; //사용자추가 + } + + if (limitSize && (!filesLength || files[0].size === undefined)) { + limitSize = undefined; + } + if (!(options.singleFileUploads || limit || limitSize) || + !this._isXHRUpload(options)) { + fileSet = [files]; + paramNameSet = [paramName]; + } else if (!(options.singleFileUploads || limitSize) && limit) { + fileSet = []; + paramNameSet = []; + for (i = 0; i < filesLength; i += limit) { + fileSet.push(files.slice(i, i + limit)); + paramNameSlice = paramName.slice(i, i + limit); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); + } + } else if (!options.singleFileUploads && limitSize) { + fileSet = []; + paramNameSet = []; + console.log( filesLength ); + for (i = 0; i < filesLength; i = i + 1) { + batchSize += files[i].size + overhead; + if (i + 1 === filesLength || + ((batchSize + files[i + 1].size + overhead) > limitSize) || + (limit && i + 1 - j >= limit)) { + fileSet.push(files.slice(j, i + 1)); + paramNameSlice = paramName.slice(j, i + 1); + if (!paramNameSlice.length) { + paramNameSlice = paramName; + } + paramNameSet.push(paramNameSlice); + j = i + 1; + batchSize = 0; + } + } + } else { + paramNameSet = paramName; + } + data.originalFiles = files; + $.each(fileSet || files, function (index, element) { + + if( filesLength <= index) return true; //사용자 추가 + var newData = $.extend({}, data); + newData.files = fileSet ? element : [element]; + newData.paramName = paramNameSet[index]; + that._initResponseObject(newData); + that._initProgressObject(newData); + that._addConvenienceMethods(e, newData); + result = that._trigger( + 'add', + $.Event('add', {delegatedEvent: e}), + newData + ); + return result; + }); + return result; + }, + + _replaceFileInput: function (input) { + var inputClone = input.clone(true); + $('
    ').append(inputClone)[0].reset(); + // Detaching allows to insert the fileInput on another form + // without loosing the file input value: + input.after(inputClone).detach(); + // Avoid memory leaks with the detached file input: + $.cleanData(input.unbind('remove')); + // Replace the original file input element in the fileInput + // elements set with the clone, which has been copied including + // event handlers: + this.options.fileInput = this.options.fileInput.map(function (i, el) { + if (el === input[0]) { + return inputClone[0]; + } + return el; + }); + // If the widget has been initialized on the file input itself, + // override this.element with the file input clone: + if (input[0] === this.element[0]) { + this.element = inputClone; + } + }, + + _handleFileTreeEntry: function (entry, path) { + var that = this, + dfd = $.Deferred(), + errorHandler = function (e) { + if (e && !e.entry) { + e.entry = entry; + } + // Since $.when returns immediately if one + // Deferred is rejected, we use resolve instead. + // This allows valid files and invalid items + // to be returned together in one set: + dfd.resolve([e]); + }, + dirReader; + path = path || ''; + if (entry.isFile) { + if (entry._file) { + // Workaround for Chrome bug #149735 + entry._file.relativePath = path; + dfd.resolve(entry._file); + } else { + entry.file(function (file) { + file.relativePath = path; + dfd.resolve(file); + }, errorHandler); + } + } else if (entry.isDirectory) { + dirReader = entry.createReader(); + dirReader.readEntries(function (entries) { + that._handleFileTreeEntries( + entries, + path + entry.name + '/' + ).done(function (files) { + dfd.resolve(files); + }).fail(errorHandler); + }, errorHandler); + } else { + // Return an empy list for file system items + // other than files or directories: + dfd.resolve([]); + } + return dfd.promise(); + }, + + _handleFileTreeEntries: function (entries, path) { + var that = this; + return $.when.apply( + $, + $.map(entries, function (entry) { + return that._handleFileTreeEntry(entry, path); + }) + ).pipe(function () { + return Array.prototype.concat.apply( + [], + arguments + ); + }); + }, + + _getDroppedFiles: function (dataTransfer) { + dataTransfer = dataTransfer || {}; + var items = dataTransfer.items; + if (items && items.length && (items[0].webkitGetAsEntry || + items[0].getAsEntry)) { + return this._handleFileTreeEntries( + $.map(items, function (item) { + var entry; + if (item.webkitGetAsEntry) { + entry = item.webkitGetAsEntry(); + if (entry) { + // Workaround for Chrome bug #149735: + entry._file = item.getAsFile(); + } + return entry; + } + return item.getAsEntry(); + }) + ); + } + return $.Deferred().resolve( + $.makeArray(dataTransfer.files) + ).promise(); + }, + + _getSingleFileInputFiles: function (fileInput) { + fileInput = $(fileInput); + var entries = fileInput.prop('webkitEntries') || + fileInput.prop('entries'), + files, + value; + if (entries && entries.length) { + return this._handleFileTreeEntries(entries); + } + files = $.makeArray(fileInput.prop('files')); + if (!files.length) { + value = fileInput.prop('value'); + if (!value) { + return $.Deferred().resolve([]).promise(); + } + // If the files property is not available, the browser does not + // support the File API and we add a pseudo File object with + // the input value as name with path information removed: + files = [{name: value.replace(/^.*\\/, '')}]; + } else if (files[0].name === undefined && files[0].fileName) { + // File normalization for Safari 4 and Firefox 3: + $.each(files, function (index, file) { + file.name = file.fileName; + file.size = file.fileSize; + }); + } + return $.Deferred().resolve(files).promise(); + }, + + _getFileInputFiles: function (fileInput) { + if (!(fileInput instanceof $) || fileInput.length === 1) { + return this._getSingleFileInputFiles(fileInput); + } + return $.when.apply( + $, + $.map(fileInput, this._getSingleFileInputFiles) + ).pipe(function () { + return Array.prototype.concat.apply( + [], + arguments + ); + }); + }, + + _onChange: function (e) { + var that = this, + data = { + fileInput: $(e.target), + form: $(e.target.form) + }; + this._getFileInputFiles(data.fileInput).always(function (files) { + data.files = files; + if (that.options.replaceFileInput) { + that._replaceFileInput(data.fileInput); + } + if (that._trigger( + 'change', + $.Event('change', {delegatedEvent: e}), + data + ) !== false) { + that._onAdd(e, data); + } + }); + }, + + _onPaste: function (e) { + var items = e.originalEvent && e.originalEvent.clipboardData && + e.originalEvent.clipboardData.items, + data = {files: []}; + if (items && items.length) { + $.each(items, function (index, item) { + var file = item.getAsFile && item.getAsFile(); + if (file) { + data.files.push(file); + } + }); + if (this._trigger( + 'paste', + $.Event('paste', {delegatedEvent: e}), + data + ) !== false) { + this._onAdd(e, data); + } + } + }, + + _onDrop: function (e) { + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var that = this, + dataTransfer = e.dataTransfer, + data = {}; + if (dataTransfer && dataTransfer.files && dataTransfer.files.length) { + e.preventDefault(); + this._getDroppedFiles(dataTransfer).always(function (files) { + data.files = files; + if (that._trigger( + 'drop', + $.Event('drop', {delegatedEvent: e}), + data + ) !== false) { + that._onAdd(e, data); + } + }); + } + }, + + _onDragOver: function (e) { + e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer; + var dataTransfer = e.dataTransfer; + if (dataTransfer && $.inArray('Files', dataTransfer.types) !== -1 && + this._trigger( + 'dragover', + $.Event('dragover', {delegatedEvent: e}) + ) !== false) { + e.preventDefault(); + dataTransfer.dropEffect = 'copy'; + } + }, + + _initEventHandlers: function () { + if (this._isXHRUpload(this.options)) { + this._on(this.options.dropZone, { + dragover: this._onDragOver, + drop: this._onDrop + }); + this._on(this.options.pasteZone, { + paste: this._onPaste + }); + } + if ($.support.fileInput) { + /* + this._on(this.options.fileInput, { + change: this._onChange + }); + */ + //var othis = this; + if( $.support.xhrFileUpload ) { + this._on(this.options.fileInput, { + change: this._onChange + }); + } else { //drag and drop을 지원 하지 않는 브라우저에는 swfupload를 사용 + var $swf_target = $(this.options.container_el); + $swf_target.swfupload({ + //upload_url: "upload.php", + upload_url: this.options.url, + file_post_name : "files", + file_size_limit : "10 MB", + file_upload_limit: 0, + file_queue_limit : this.options.limit_filesLength, + file_types : "*.jpeg; *.bmp; *.png; *.jpg; *.gif", + file_types_description : "Image Files (JPG, JPEG, PNG, BMP, GIF)", + flash_url : "./swfupload/swfupload.swf", + button_placeholder : this.options.fileInput[0], + button_width : "100%", + button_height : "100%", + button_window_mode : "transparent" + }); + } + } + }, + + _destroyEventHandlers: function () { + this._off(this.options.dropZone, 'dragover drop'); + this._off(this.options.pasteZone, 'paste'); + this._off(this.options.fileInput, 'change'); + }, + + _setOption: function (key, value) { + var reinit = $.inArray(key, this._specialOptions) !== -1; + if (reinit) { + this._destroyEventHandlers(); + } + this._super(key, value); + if (reinit) { + this._initSpecialOptions(); + this._initEventHandlers(); + } + }, + + _initSpecialOptions: function () { + var options = this.options; + if (options.fileInput === undefined) { + options.fileInput = this.element.is('input[type="file"]') ? + this.element : this.element.find('input[type="file"]'); + } else if (!(options.fileInput instanceof $)) { + options.fileInput = $(options.fileInput); + } + if (!(options.dropZone instanceof $)) { + options.dropZone = $(options.dropZone); + } + if (!(options.pasteZone instanceof $)) { + options.pasteZone = $(options.pasteZone); + } + }, + + _getRegExp: function (str) { + var parts = str.split('/'), + modifiers = parts.pop(); + parts.shift(); + return new RegExp(parts.join('/'), modifiers); + }, + + _isRegExpOption: function (key, value) { + return key !== 'url' && $.type(value) === 'string' && + /^\/.*\/[igm]{0,3}$/.test(value); + }, + + _initDataAttributes: function () { + var that = this, + options = this.options, + clone = $(this.element[0].cloneNode(false)); + // Initialize options set via HTML5 data-attributes: + $.each( + clone.data(), + function (key, value) { + var dataAttributeName = 'data-' + + // Convert camelCase to hyphen-ated key: + key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); + if (clone.attr(dataAttributeName)) { + if (that._isRegExpOption(key, value)) { + value = that._getRegExp(value); + } + options[key] = value; + } + } + ); + }, + + _create: function () { + this._initDataAttributes(); + this._initSpecialOptions(); + this._slots = []; + this._sequence = this._getXHRPromise(true); + this._sending = this._active = 0; + this._initProgressObject(this); + this._initEventHandlers(); + }, + + // This method is exposed to the widget API and allows to query + // the number of active uploads: + active: function () { + return this._active; + }, + + // This method is exposed to the widget API and allows to query + // the widget upload progress. + // It returns an object with loaded, total and bitrate properties + // for the running uploads: + progress: function () { + return this._progress; + }, + + // This method is exposed to the widget API and allows adding files + // using the fileupload API. The data parameter accepts an object which + // must have a files property and can contain additional options: + // .fileupload('add', {files: filesList}); + add: function (data) { + var that = this; + if (!data || this.options.disabled) { + return; + } + if (data.fileInput && !data.files) { + this._getFileInputFiles(data.fileInput).always(function (files) { + data.files = files; + that._onAdd(null, data); + }); + } else { + data.files = $.makeArray(data.files); + this._onAdd(null, data); + } + }, + + // This method is exposed to the widget API and allows sending files + // using the fileupload API. The data parameter accepts an object which + // must have a files or fileInput property and can contain additional options: + // .fileupload('send', {files: filesList}); + // The method returns a Promise object for the file upload call. + send: function (data) { + if (data && !this.options.disabled) { + if (data.fileInput && !data.files) { + var that = this, + dfd = $.Deferred(), + promise = dfd.promise(), + jqXHR, + aborted; + promise.abort = function () { + aborted = true; + if (jqXHR) { + return jqXHR.abort(); + } + dfd.reject(null, 'abort', 'abort'); + return promise; + }; + this._getFileInputFiles(data.fileInput).always( + function (files) { + if (aborted) { + return; + } + if (!files.length) { + dfd.reject(); + return; + } + data.files = files; + jqXHR = that._onSend(null, data).then( + function (result, textStatus, jqXHR) { + dfd.resolve(result, textStatus, jqXHR); + }, + function (jqXHR, textStatus, errorThrown) { + dfd.reject(jqXHR, textStatus, errorThrown); + } + ); + } + ); + return this._enhancePromise(promise); + } + data.files = $.makeArray(data.files); + if (data.files.length) { + return this._onSend(null, data); + } + } + return this._getXHRPromise(false, data && data.context); + } + + }); + +})); diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.iframe-transport.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.iframe-transport.js new file mode 100644 index 0000000..8d64b59 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.iframe-transport.js @@ -0,0 +1,214 @@ +/* + * jQuery Iframe Transport Plugin 1.8.2 + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * http://www.opensource.org/licenses/MIT + */ + +/* global define, window, document */ + +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + // Register as an anonymous AMD module: + define(['jquery'], factory); + } else { + // Browser globals: + factory(window.jQuery); + } +}(function ($) { + 'use strict'; + + // Helper variable to create unique names for the transport iframes: + var counter = 0; + + // The iframe transport accepts four additional options: + // options.fileInput: a jQuery collection of file input fields + // options.paramName: the parameter name for the file form data, + // overrides the name property of the file input field(s), + // can be a string or an array of strings. + // options.formData: an array of objects with name and value properties, + // equivalent to the return data of .serializeArray(), e.g.: + // [{name: 'a', value: 1}, {name: 'b', value: 2}] + // options.initialIframeSrc: the URL of the initial iframe src, + // by default set to "javascript:false;" + $.ajaxTransport('iframe', function (options) { + if (options.async) { + // javascript:false as initial iframe src + // prevents warning popups on HTTPS in IE6: + /*jshint scripturl: true */ + var initialIframeSrc = options.initialIframeSrc || 'javascript:false;', + /*jshint scripturl: false */ + form, + iframe, + addParamChar; + return { + send: function (_, completeCallback) { + form = $('
    '); + form.attr('accept-charset', options.formAcceptCharset); + addParamChar = /\?/.test(options.url) ? '&' : '?'; + // XDomainRequest only supports GET and POST: + if (options.type === 'DELETE') { + options.url = options.url + addParamChar + '_method=DELETE'; + options.type = 'POST'; + } else if (options.type === 'PUT') { + options.url = options.url + addParamChar + '_method=PUT'; + options.type = 'POST'; + } else if (options.type === 'PATCH') { + options.url = options.url + addParamChar + '_method=PATCH'; + options.type = 'POST'; + } + // IE versions below IE8 cannot set the name property of + // elements that have already been added to the DOM, + // so we set the name along with the iframe HTML markup: + counter += 1; + iframe = $( + '' + ).bind('load', function () { + var fileInputClones, + paramNames = $.isArray(options.paramName) ? + options.paramName : [options.paramName]; + iframe + .unbind('load') + .bind('load', function () { + var response; + // Wrap in a try/catch block to catch exceptions thrown + // when trying to access cross-domain iframe contents: + try { + response = iframe.contents(); + // Google Chrome and Firefox do not throw an + // exception when calling iframe.contents() on + // cross-domain requests, so we unify the response: + if (!response.length || !response[0].firstChild) { + throw new Error(); + } + } catch (e) { + response = undefined; + } + // The complete callback returns the + // iframe content document as response object: + completeCallback( + 200, + 'success', + {'iframe': response} + ); + // Fix for IE endless progress bar activity bug + // (happens on form submits to iframe targets): + $('') + .appendTo(form); + window.setTimeout(function () { + // Removing the form in a setTimeout call + // allows Chrome's developer tools to display + // the response result + form.remove(); + }, 0); + }); + form + .prop('target', iframe.prop('name')) + .prop('action', options.url) + .prop('method', options.type); + if (options.formData) { + $.each(options.formData, function (index, field) { + $('') + .prop('name', field.name) + .val(field.value) + .appendTo(form); + }); + } + if (options.fileInput && options.fileInput.length && + options.type === 'POST') { + fileInputClones = options.fileInput.clone(); + // Insert a clone for each file input field: + options.fileInput.after(function (index) { + return fileInputClones[index]; + }); + if (options.paramName) { + options.fileInput.each(function (index) { + $(this).prop( + 'name', + paramNames[index] || options.paramName + ); + }); + } + // Appending the file input fields to the hidden form + // removes them from their original location: + form + .append(options.fileInput) + .prop('enctype', 'multipart/form-data') + // enctype must be set as encoding for IE: + .prop('encoding', 'multipart/form-data'); + // Remove the HTML5 form attribute from the input(s): + options.fileInput.removeAttr('form'); + } + form.submit(); + // Insert the file input fields at their original location + // by replacing the clones with the originals: + if (fileInputClones && fileInputClones.length) { + options.fileInput.each(function (index, input) { + var clone = $(fileInputClones[index]); + // Restore the original name and form properties: + $(input) + .prop('name', clone.prop('name')) + .attr('form', clone.attr('form')); + clone.replaceWith(input); + }); + } + }); + form.append(iframe).appendTo(document.body); + }, + abort: function () { + if (iframe) { + // javascript:false as iframe src aborts the request + // and prevents warning popups on HTTPS in IE6. + // concat is used to avoid the "Script URL" JSLint error: + iframe + .unbind('load') + .prop('src', initialIframeSrc); + } + if (form) { + form.remove(); + } + } + }; + } + }); + + // The iframe transport returns the iframe content document as response. + // The following adds converters from iframe to text, json, html, xml + // and script. + // Please note that the Content-Type for JSON responses has to be text/plain + // or text/html, if the browser doesn't include application/json in the + // Accept header, else IE will show a download dialog. + // The Content-Type for XML responses on the other hand has to be always + // application/xml or text/xml, so IE properly parses the XML response. + // See also + // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation + $.ajaxSetup({ + converters: { + 'iframe text': function (iframe) { + return iframe && $(iframe[0].body).text(); + }, + 'iframe json': function (iframe) { + return iframe && $.parseJSON($(iframe[0].body).text()); + }, + 'iframe html': function (iframe) { + return iframe && $(iframe[0].body).html(); + }, + 'iframe xml': function (iframe) { + var xmlDoc = iframe && iframe[0]; + return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : + $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || + $(xmlDoc.body).html()); + }, + 'iframe script': function (iframe) { + return iframe && $.globalEval($(iframe[0].body).text()); + } + } + }); + +})); diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.ui.widget.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.ui.widget.js new file mode 100644 index 0000000..c430419 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/js/jquery.ui.widget.js @@ -0,0 +1,530 @@ +/*! + * jQuery UI Widget 1.10.4+amd + * https://github.com/blueimp/jQuery-File-Upload + * + * Copyright 2014 jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/jQuery.widget/ + */ + +(function (factory) { + if (typeof define === "function" && define.amd) { + // Register as an anonymous AMD module: + define(["jquery"], factory); + } else { + // Browser globals: + factory(jQuery); + } +}(function( $, undefined ) { + +var uuid = 0, + slice = Array.prototype.slice, + _cleanData = $.cleanData; +$.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); +}; + +$.widget = function( name, base, prototype ) { + var fullName, existingConstructor, constructor, basePrototype, + // proxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + proxiedPrototype = {}, + namespace = name.split( "." )[ 0 ]; + + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without "new" keyword + if ( !this._createWidget ) { + return new constructor( options, element ); + } + + // allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + // extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + // copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + // track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + }); + + basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( !$.isFunction( value ) ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = (function() { + var _super = function() { + return base.prototype[ prop ].apply( this, arguments ); + }, + _superApply = function( args ) { + return base.prototype[ prop ].apply( this, args ); + }; + return function() { + var __super = this._super, + __superApply = this._superApply, + returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + })(); + }); + constructor.prototype = $.widget.extend( basePrototype, { + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + }); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); + }); + // remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); +}; + +$.widget.extend = function( target ) { + var input = slice.call( arguments, 1 ), + inputIndex = 0, + inputLength = input.length, + key, + value; + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.widget.extend.apply( null, [ options ].concat(args) ) : + options; + + if ( isMethodCall ) { + this.each(function() { + var methodValue, + instance = $.data( this, fullName ); + if ( !instance ) { + return $.error( "cannot call methods on " + name + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + " widget instance" ); + } + methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + $.data( this, fullName, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
    ", + options: { + disabled: false, + + // callbacks + create: null + }, + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = uuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + }); + this.document = $( element.style ? + // element within the document + element.ownerDocument : + // element is window or document + element.document || element ); + this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); + } + + this._create(); + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + _getCreateOptions: $.noop, + _getCreateEventData: $.noop, + _create: $.noop, + _init: $.noop, + + destroy: function() { + this._destroy(); + // we can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .unbind( this.eventNamespace ) + // 1.9 BC for #7810 + // TODO remove dual storage + .removeData( this.widgetName ) + .removeData( this.widgetFullName ) + // support: jquery <1.6.3 + // http://bugs.jquery.com/ticket/9413 + .removeData( $.camelCase( this.widgetFullName ) ); + this.widget() + .unbind( this.eventNamespace ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetFullName + "-disabled " + + "ui-state-disabled" ); + + // clean up events and states + this.bindings.unbind( this.eventNamespace ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + }, + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key, + parts, + curOption, + i; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) + .attr( "aria-disabled", value ); + this.hoverable.removeClass( "ui-state-hover" ); + this.focusable.removeClass( "ui-state-focus" ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement, + instance = this; + + // no suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // no element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + // accept selectors, DOM elements + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + // allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^(\w+)\s*(.*)$/ ), + eventName = match[1] + instance.eventNamespace, + selector = match[2]; + if ( selector ) { + delegateElement.delegate( selector, eventName, handlerProxy ); + } else { + element.bind( eventName, handlerProxy ); + } + }); + }, + + _off: function( element, eventName ) { + eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; + element.unbind( eventName ).undelegate( eventName ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + $( event.currentTarget ).addClass( "ui-state-hover" ); + }, + mouseleave: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-hover" ); + } + }); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + $( event.currentTarget ).addClass( "ui-state-focus" ); + }, + focusout: function( event ) { + $( event.currentTarget ).removeClass( "ui-state-focus" ); + } + }); + }, + + _trigger: function( type, event, data ) { + var prop, orig, + callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + // the original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( $.isFunction( callback ) && + callback.apply( this.element[0], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + var hasOptions, + effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + if ( options.delay ) { + element.delay( options.delay ); + } + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue(function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + }); + } + }; +}); + +})); diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/JSON.php b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/JSON.php new file mode 100644 index 0000000..8dc8a6f --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/JSON.php @@ -0,0 +1,933 @@ + + * @author Matt Knapp + * @author Brett Stimmerman + * @copyright 2005 Michal Migurski + * @version CVS: $Id: JSON.php 305040 2010-11-02 23:19:03Z alan_k $ + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 + */ + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_SLICE', 1); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_STR', 2); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_ARR', 3); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_OBJ', 4); + +/** + * Marker constant for Services_JSON::decode(), used to flag stack state + */ +define('SERVICES_JSON_IN_CMT', 5); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_LOOSE_TYPE', 16); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_SUPPRESS_ERRORS', 32); + +/** + * Behavior switch for Services_JSON::decode() + */ +define('SERVICES_JSON_USE_TO_JSON', 64); + +/** + * Converts to and from JSON format. + * + * Brief example of use: + * + * + * // create a new instance of Services_JSON + * $json = new Services_JSON(); + * + * // convert a complexe value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); + * $output = $json->encode($value); + * + * print($output); + * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] + * + * // accept incoming POST data, assumed to be in JSON notation + * $input = file_get_contents('php://input', 1000000); + * $value = $json->decode($input); + * + */ +class Services_JSON +{ + /** + * constructs a new JSON instance + * + * @param int $use object behavior flags; combine with boolean-OR + * + * possible values: + * - SERVICES_JSON_LOOSE_TYPE: loose typing. + * "{...}" syntax creates associative arrays + * instead of objects in decode(). + * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. + * Values which can't be encoded (e.g. resources) + * appear as NULL instead of throwing errors. + * By default, a deeply-nested resource will + * bubble up with an error, so all return values + * from encode() should be checked with isError() + * - SERVICES_JSON_USE_TO_JSON: call toJSON when serializing objects + * It serializes the return value from the toJSON call rather + * than the object it'self, toJSON can return associative arrays, + * strings or numbers, if you return an object, make sure it does + * not have a toJSON method, otherwise an error will occur. + */ + function Services_JSON($use = 0) + { + $this->use = $use; + $this->_mb_strlen = function_exists('mb_strlen'); + $this->_mb_convert_encoding = function_exists('mb_convert_encoding'); + $this->_mb_substr = function_exists('mb_substr'); + } + // private - cache the mbstring lookup results.. + var $_mb_strlen = false; + var $_mb_substr = false; + var $_mb_convert_encoding = false; + + /** + * convert a string from one UTF-16 char to one UTF-8 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf16 UTF-16 character + * @return string UTF-8 character + * @access private + */ + function utf162utf8($utf16) + { + // oh please oh please oh please oh please oh please + if($this->_mb_convert_encoding) { + return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); + } + + $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); + + switch(true) { + case ((0x7F & $bytes) == $bytes): + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x7F & $bytes); + + case (0x07FF & $bytes) == $bytes: + // return a 2-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xC0 | (($bytes >> 6) & 0x1F)) + . chr(0x80 | ($bytes & 0x3F)); + + case (0xFFFF & $bytes) == $bytes: + // return a 3-byte UTF-8 character + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0xE0 | (($bytes >> 12) & 0x0F)) + . chr(0x80 | (($bytes >> 6) & 0x3F)) + . chr(0x80 | ($bytes & 0x3F)); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * convert a string from one UTF-8 char to one UTF-16 char + * + * Normally should be handled by mb_convert_encoding, but + * provides a slower PHP-only method for installations + * that lack the multibye string extension. + * + * @param string $utf8 UTF-8 character + * @return string UTF-16 character + * @access private + */ + function utf82utf16($utf8) + { + // oh please oh please oh please oh please oh please + if($this->_mb_convert_encoding) { + return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); + } + + switch($this->strlen8($utf8)) { + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; + + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) + . chr((0xC0 & (ord($utf8{0}) << 6)) + | (0x3F & ord($utf8{1}))); + + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) + | (0x0F & (ord($utf8{1}) >> 2))) + . chr((0xC0 & (ord($utf8{1}) << 6)) + | (0x7F & ord($utf8{2}))); + } + + // ignoring UTF-32 for now, sorry + return ''; + } + + /** + * encodes an arbitrary variable into JSON format (and sends JSON Header) + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encode($var) + { + header('Content-type: application/json'); + return $this->encodeUnsafe($var); + } + /** + * encodes an arbitrary variable into JSON format without JSON Header - warning - may allow XSS!!!!) + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function encodeUnsafe($var) + { + // see bug #16908 - regarding numeric locale printing + $lc = setlocale(LC_NUMERIC, 0); + setlocale(LC_NUMERIC, 'C'); + $ret = $this->_encode($var); + setlocale(LC_NUMERIC, $lc); + return $ret; + + } + /** + * PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format + * + * @param mixed $var any number, boolean, string, array, or object to be encoded. + * see argument 1 to Services_JSON() above for array-parsing behavior. + * if var is a strng, note that encode() always expects it + * to be in ASCII or UTF-8 format! + * + * @return mixed JSON string representation of input var or an error if a problem occurs + * @access public + */ + function _encode($var) + { + + switch (gettype($var)) { + case 'boolean': + return $var ? 'true' : 'false'; + + case 'NULL': + return 'null'; + + case 'integer': + return (int) $var; + + case 'double': + case 'float': + return (float) $var; + + case 'string': + // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT + $ascii = ''; + $strlen_var = $this->strlen8($var); + + /* + * Iterate over every character in the string, + * escaping with a slash or encoding to UTF-8 where necessary + */ + for ($c = 0; $c < $strlen_var; ++$c) { + + $ord_var_c = ord($var{$c}); + + switch (true) { + case $ord_var_c == 0x08: + $ascii .= '\b'; + break; + case $ord_var_c == 0x09: + $ascii .= '\t'; + break; + case $ord_var_c == 0x0A: + $ascii .= '\n'; + break; + case $ord_var_c == 0x0C: + $ascii .= '\f'; + break; + case $ord_var_c == 0x0D: + $ascii .= '\r'; + break; + + case $ord_var_c == 0x22: + case $ord_var_c == 0x2F: + case $ord_var_c == 0x5C: + // double quote, slash, slosh + $ascii .= '\\'.$var{$c}; + break; + + case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): + // characters U-00000000 - U-0000007F (same as ASCII) + $ascii .= $var{$c}; + break; + + case (($ord_var_c & 0xE0) == 0xC0): + // characters U-00000080 - U-000007FF, mask 110XXXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + if ($c+1 >= $strlen_var) { + $c += 1; + $ascii .= '?'; + break; + } + + $char = pack('C*', $ord_var_c, ord($var{$c + 1})); + $c += 1; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF0) == 0xE0): + if ($c+2 >= $strlen_var) { + $c += 2; + $ascii .= '?'; + break; + } + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + @ord($var{$c + 1}), + @ord($var{$c + 2})); + $c += 2; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xF8) == 0xF0): + if ($c+3 >= $strlen_var) { + $c += 3; + $ascii .= '?'; + break; + } + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3})); + $c += 3; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFC) == 0xF8): + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + if ($c+4 >= $strlen_var) { + $c += 4; + $ascii .= '?'; + break; + } + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4})); + $c += 4; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + + case (($ord_var_c & 0xFE) == 0xFC): + if ($c+5 >= $strlen_var) { + $c += 5; + $ascii .= '?'; + break; + } + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $char = pack('C*', $ord_var_c, + ord($var{$c + 1}), + ord($var{$c + 2}), + ord($var{$c + 3}), + ord($var{$c + 4}), + ord($var{$c + 5})); + $c += 5; + $utf16 = $this->utf82utf16($char); + $ascii .= sprintf('\u%04s', bin2hex($utf16)); + break; + } + } + return '"'.$ascii.'"'; + + case 'array': + /* + * As per JSON spec if any array key is not an integer + * we must treat the the whole array as an object. We + * also try to catch a sparsely populated associative + * array with numeric keys here because some JS engines + * will create an array with empty indexes up to + * max_index which can cause memory issues and because + * the keys, which may be relevant, will be remapped + * otherwise. + * + * As per the ECMA and JSON specification an object may + * have any string as a property. Unfortunately due to + * a hole in the ECMA specification if the key is a + * ECMA reserved word or starts with a digit the + * parameter is only accessible using ECMAScript's + * bracket notation. + */ + + // treat as a JSON object + if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { + $properties = array_map(array($this, 'name_value'), + array_keys($var), + array_values($var)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + } + + // treat it like a regular array + $elements = array_map(array($this, '_encode'), $var); + + foreach($elements as $element) { + if(Services_JSON::isError($element)) { + return $element; + } + } + + return '[' . join(',', $elements) . ']'; + + case 'object': + + // support toJSON methods. + if (($this->use & SERVICES_JSON_USE_TO_JSON) && method_exists($var, 'toJSON')) { + // this may end up allowing unlimited recursion + // so we check the return value to make sure it's not got the same method. + $recode = $var->toJSON(); + + if (method_exists($recode, 'toJSON')) { + + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(class_name($var). + " toJSON returned an object with a toJSON method."); + + } + + return $this->_encode( $recode ); + } + + $vars = get_object_vars($var); + + $properties = array_map(array($this, 'name_value'), + array_keys($vars), + array_values($vars)); + + foreach($properties as $property) { + if(Services_JSON::isError($property)) { + return $property; + } + } + + return '{' . join(',', $properties) . '}'; + + default: + return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) + ? 'null' + : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); + } + } + + /** + * array-walking function for use in generating JSON-formatted name-value pairs + * + * @param string $name name of key to use + * @param mixed $value reference to an array element to be encoded + * + * @return string JSON-formatted name-value pair, like '"name":value' + * @access private + */ + function name_value($name, $value) + { + $encoded_value = $this->_encode($value); + + if(Services_JSON::isError($encoded_value)) { + return $encoded_value; + } + + return $this->_encode(strval($name)) . ':' . $encoded_value; + } + + /** + * reduce a string by removing leading and trailing comments and whitespace + * + * @param $str string string value to strip of comments and whitespace + * + * @return string string value stripped of comments and whitespace + * @access private + */ + function reduce_string($str) + { + $str = preg_replace(array( + + // eliminate single line comments in '// ...' form + '#^\s*//(.+)$#m', + + // eliminate multi-line comments in '/* ... */' form, at start of string + '#^\s*/\*(.+)\*/#Us', + + // eliminate multi-line comments in '/* ... */' form, at end of string + '#/\*(.+)\*/\s*$#Us' + + ), '', $str); + + // eliminate extraneous space + return trim($str); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param string $str JSON-formatted string + * + * @return mixed number, boolean, string, array, or object + * corresponding to given JSON input string. + * See argument 1 to Services_JSON() above for object-output behavior. + * Note that decode() always returns strings + * in ASCII or UTF-8 format! + * @access public + */ + function decode($str) + { + $str = $this->reduce_string($str); + + switch (strtolower($str)) { + case 'true': + return true; + + case 'false': + return false; + + case 'null': + return null; + + default: + $m = array(); + + if (is_numeric($str)) { + // Lookie-loo, it's a number + + // This would work on its own, but I'm trying to be + // good about returning integers where appropriate: + // return (float)$str; + + // Return float or int, as appropriate + return ((float)$str == (integer)$str) + ? (integer)$str + : (float)$str; + + } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { + // STRINGS RETURNED IN UTF-8 FORMAT + $delim = $this->substr8($str, 0, 1); + $chrs = $this->substr8($str, 1, -1); + $utf8 = ''; + $strlen_chrs = $this->strlen8($chrs); + + for ($c = 0; $c < $strlen_chrs; ++$c) { + + $substr_chrs_c_2 = $this->substr8($chrs, $c, 2); + $ord_chrs_c = ord($chrs{$c}); + + switch (true) { + case $substr_chrs_c_2 == '\b': + $utf8 .= chr(0x08); + ++$c; + break; + case $substr_chrs_c_2 == '\t': + $utf8 .= chr(0x09); + ++$c; + break; + case $substr_chrs_c_2 == '\n': + $utf8 .= chr(0x0A); + ++$c; + break; + case $substr_chrs_c_2 == '\f': + $utf8 .= chr(0x0C); + ++$c; + break; + case $substr_chrs_c_2 == '\r': + $utf8 .= chr(0x0D); + ++$c; + break; + + case $substr_chrs_c_2 == '\\"': + case $substr_chrs_c_2 == '\\\'': + case $substr_chrs_c_2 == '\\\\': + case $substr_chrs_c_2 == '\\/': + if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || + ($delim == "'" && $substr_chrs_c_2 != '\\"')) { + $utf8 .= $chrs{++$c}; + } + break; + + case preg_match('/\\\u[0-9A-F]{4}/i', $this->substr8($chrs, $c, 6)): + // single, escaped unicode character + $utf16 = chr(hexdec($this->substr8($chrs, ($c + 2), 2))) + . chr(hexdec($this->substr8($chrs, ($c + 4), 2))); + $utf8 .= $this->utf162utf8($utf16); + $c += 5; + break; + + case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): + $utf8 .= $chrs{$c}; + break; + + case ($ord_chrs_c & 0xE0) == 0xC0: + // characters U-00000080 - U-000007FF, mask 110XXXXX + //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= $this->substr8($chrs, $c, 2); + ++$c; + break; + + case ($ord_chrs_c & 0xF0) == 0xE0: + // characters U-00000800 - U-0000FFFF, mask 1110XXXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= $this->substr8($chrs, $c, 3); + $c += 2; + break; + + case ($ord_chrs_c & 0xF8) == 0xF0: + // characters U-00010000 - U-001FFFFF, mask 11110XXX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= $this->substr8($chrs, $c, 4); + $c += 3; + break; + + case ($ord_chrs_c & 0xFC) == 0xF8: + // characters U-00200000 - U-03FFFFFF, mask 111110XX + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= $this->substr8($chrs, $c, 5); + $c += 4; + break; + + case ($ord_chrs_c & 0xFE) == 0xFC: + // characters U-04000000 - U-7FFFFFFF, mask 1111110X + // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + $utf8 .= $this->substr8($chrs, $c, 6); + $c += 5; + break; + + } + + } + + return $utf8; + + } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { + // array, or object notation + + if ($str{0} == '[') { + $stk = array(SERVICES_JSON_IN_ARR); + $arr = array(); + } else { + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = array(); + } else { + $stk = array(SERVICES_JSON_IN_OBJ); + $obj = new stdClass(); + } + } + + array_push($stk, array('what' => SERVICES_JSON_SLICE, + 'where' => 0, + 'delim' => false)); + + $chrs = $this->substr8($str, 1, -1); + $chrs = $this->reduce_string($chrs); + + if ($chrs == '') { + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } else { + return $obj; + + } + } + + //print("\nparsing {$chrs}\n"); + + $strlen_chrs = $this->strlen8($chrs); + + for ($c = 0; $c <= $strlen_chrs; ++$c) { + + $top = end($stk); + $substr_chrs_c_2 = $this->substr8($chrs, $c, 2); + + if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { + // found a comma that is not inside a string, array, etc., + // OR we've reached the end of the character list + $slice = $this->substr8($chrs, $top['where'], ($c - $top['where'])); + array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); + //print("Found split at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + // we are in an array, so just push an element onto the stack + array_push($arr, $this->decode($slice)); + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + // we are in an object, so figure + // out the property name and set an + // element in an associative array, + // for now + $parts = array(); + + if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:/Uis', $slice, $parts)) { + // "name":value pair + $key = $this->decode($parts[1]); + $val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B")); + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } elseif (preg_match('/^\s*(\w+)\s*:/Uis', $slice, $parts)) { + // name:value pair, where name is unquoted + $key = $parts[1]; + $val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B")); + + if ($this->use & SERVICES_JSON_LOOSE_TYPE) { + $obj[$key] = $val; + } else { + $obj->$key = $val; + } + } + + } + + } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { + // found a quote, and we are not inside a string + array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); + //print("Found start of string at {$c}\n"); + + } elseif (($chrs{$c} == $top['delim']) && + ($top['what'] == SERVICES_JSON_IN_STR) && + (($this->strlen8($this->substr8($chrs, 0, $c)) - $this->strlen8(rtrim($this->substr8($chrs, 0, $c), '\\'))) % 2 != 1)) { + // found a quote, we're in a string, and it's not escaped + // we know that it's not escaped becase there is _not_ an + // odd number of backslashes at the end of the string so far + array_pop($stk); + //print("Found end of string at {$c}: ".$this->substr8($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '[') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-bracket, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); + //print("Found start of array at {$c}\n"); + + } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { + // found a right-bracket, and we're in an array + array_pop($stk); + //print("Found end of array at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($chrs{$c} == '{') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a left-brace, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); + //print("Found start of object at {$c}\n"); + + } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { + // found a right-brace, and we're in an object + array_pop($stk); + //print("Found end of object at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } elseif (($substr_chrs_c_2 == '/*') && + in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { + // found a comment start, and we are in an array, object, or slice + array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); + $c++; + //print("Found start of comment at {$c}\n"); + + } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { + // found a comment end, and we're in one now + array_pop($stk); + $c++; + + for ($i = $top['where']; $i <= $c; ++$i) + $chrs = substr_replace($chrs, ' ', $i, 1); + + //print("Found end of comment at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n"); + + } + + } + + if (reset($stk) == SERVICES_JSON_IN_ARR) { + return $arr; + + } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { + return $obj; + + } + + } + } + } + + /** + * @todo Ultimately, this should just call PEAR::isError() + */ + function isError($data, $code = null) + { + if (class_exists('pear')) { + return PEAR::isError($data, $code); + } elseif (is_object($data) && (get_class($data) == 'services_json_error' || + is_subclass_of($data, 'services_json_error'))) { + return true; + } + + return false; + } + + /** + * Calculates length of string in bytes + * @param string + * @return integer length + */ + function strlen8( $str ) + { + if ( $this->_mb_strlen ) { + return mb_strlen( $str, "8bit" ); + } + return strlen( $str ); + } + + /** + * Returns part of a string, interpreting $start and $length as number of bytes. + * @param string + * @param integer start + * @param integer length + * @return integer length + */ + function substr8( $string, $start, $length=false ) + { + if ( $length === false ) { + $length = $this->strlen8( $string ) - $start; + } + if ( $this->_mb_substr ) { + return mb_substr( $string, $start, $length, "8bit" ); + } + return substr( $string, $start, $length ); + } + +} + +if (class_exists('PEAR_Error')) { + + class Services_JSON_Error extends PEAR_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + parent::PEAR_Error($message, $code, $mode, $options, $userinfo); + } + } + +} else { + + /** + * @todo Ultimately, this class shall be descended from PEAR_Error + */ + class Services_JSON_Error + { + function Services_JSON_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + + } + } + +} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php new file mode 100644 index 0000000..6ae2094 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/UploadHandler.php @@ -0,0 +1,1459 @@ + array("imagecreatefromgif", "imagegif"), + "image/jpg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/jpeg" => array("imagecreatefromjpeg", "imagejpeg"), + "image/png" => array("imagecreatefrompng", "imagepng"), + "image/bmp" => array("imagecreatefromwbmp", "imagewbmp") + ); + + public function __construct($options = null, $initialize = true, $error_messages = null) { + + $this->post_max_size = (defined('SMARTEDITOR_UPLOAD_SIZE_LIMIT') && SMARTEDITOR_UPLOAD_SIZE_LIMIT) ? SMARTEDITOR_UPLOAD_SIZE_LIMIT.'M' : ini_get('post_max_size'); + + // PHP File Upload error message codes: + // http://php.net/manual/en/features.file-upload.errors.php + $this->error_messages = array( + 1 => 'The uploaded file exceeds the upload_max_filesize', + 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form', + 3 => 'The uploaded file was only partially uploaded', + 4 => 'No file was uploaded', + 6 => 'Missing a temporary folder', + 7 => 'Failed to write file to disk', + 8 => 'A PHP extension stopped the file upload', + 'post_max_size' => 'The uploaded file exceeds the post_max_size', + 'max_file_size' => 'File is too big', + 'min_file_size' => 'File is too small', + 'accept_file_types' => 'Filetype not allowed', + 'max_number_of_files' => 'Maximum number of files exceeded', + 'max_width' => 'Image exceeds maximum width', + 'min_width' => 'Image requires a minimum width', + 'max_height' => 'Image exceeds maximum height', + 'min_height' => 'Image requires a minimum height', + 'abort' => 'File upload aborted', + 'image_resize' => 'Failed to resize image' + ); + + $this->options = array( + 'script_url' => $this->get_full_url().'/', + 'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/files/', + 'upload_url' => $this->get_full_url().'/files/', + 'user_dirs' => false, + 'mkdir_mode' => 0755, + 'param_name' => 'files', + // Set the following option to 'POST', if your server does not support + // DELETE requests. This is a parameter sent to the client: + 'delete_type' => 'DELETE', + 'access_control_allow_origin' => '*', + 'access_control_allow_credentials' => false, + 'access_control_allow_methods' => array( + 'OPTIONS', + 'HEAD', + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE' + ), + 'access_control_allow_headers' => array( + 'Content-Type', + 'Content-Range', + 'Content-Disposition' + ), + // Enable to provide file downloads via GET requests to the PHP script: + // 1. Set to 1 to download files via readfile method through PHP + // 2. Set to 2 to send a X-Sendfile header for lighttpd/Apache + // 3. Set to 3 to send a X-Accel-Redirect header for nginx + // If set to 2 or 3, adjust the upload_url option to the base path of + // the redirect parameter, e.g. '/files/'. + 'download_via_php' => false, + // Read files in chunks to avoid memory limits when download_via_php + // is enabled, set to 0 to disable chunked reading of files: + 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB + // Defines which files can be displayed inline when downloaded: + 'inline_file_types' => '/\.(gif|jpe?g|bmp|png)$/i', + // Defines which files (based on their names) are accepted for upload: + //'accept_file_types' => '/.+$/i', + 'accept_file_types' => '/\.(gif|jpe?g|bmp|png)$/i', + // The php.ini settings upload_max_filesize and post_max_size + // take precedence over the following max_file_size setting: + 'max_file_size' => null, + 'min_file_size' => 1, + // The maximum number of files for the upload directory: + 'max_number_of_files' => null, + // Defines which files are handled as image files: + 'image_file_types' => '/\.(gif|jpe?g|bmp|png)$/i', + 'is_resize' => (defined('SMARTEDITOR_UPLOAD_RESIZE') && SMARTEDITOR_UPLOAD_RESIZE) ? true : false, + 'resize_max_width' => (defined('SMARTEDITOR_UPLOAD_MAX_WIDTH') && SMARTEDITOR_UPLOAD_MAX_WIDTH) ? SMARTEDITOR_UPLOAD_MAX_WIDTH : 800, + 'resize_max_height' => (defined('SMARTEDITOR_UPLOAD_MAX_HEIGHT') && SMARTEDITOR_UPLOAD_MAX_HEIGHT) ? SMARTEDITOR_UPLOAD_MAX_HEIGHT : 800, + 'resize_jpeg_compress' => (defined('SMARTEDITOR_UPLOAD_IMAGE_QUALITY') && SMARTEDITOR_UPLOAD_IMAGE_QUALITY) ? SMARTEDITOR_UPLOAD_IMAGE_QUALITY : 800, + // Image resolution restrictions: + 'max_width' => null, + 'max_height' => null, + 'min_width' => 1, + 'min_height' => 1, + // Set the following option to false to enable resumable uploads: + 'discard_aborted_uploads' => true, + // Set to 0 to use the GD library to scale and orient images, + // set to 1 to use imagick (if installed, falls back to GD), + // set to 2 to use the ImageMagick convert binary directly: + 'image_library' => 1, + // Uncomment the following to define an array of resource limits + // for imagick: + /* + 'imagick_resource_limits' => array( + imagick::RESOURCETYPE_MAP => 32, + imagick::RESOURCETYPE_MEMORY => 32 + ), + */ + // Command or path for to the ImageMagick convert binary: + 'convert_bin' => 'convert', + // Uncomment the following to add parameters in front of each + // ImageMagick convert call (the limit constraints seem only + // to have an effect if put in front): + /* + 'convert_params' => '-limit memory 32MiB -limit map 32MiB', + */ + // Command or path for to the ImageMagick identify binary: + 'identify_bin' => 'identify', + 'image_versions' => array( + // The empty image version key defines options for the original image: + '' => array( + // Automatically rotate images based on EXIF meta data: + 'auto_orient' => true + ), + // Uncomment the following to create medium sized images: + /* + 'medium' => array( + 'max_width' => 800, + 'max_height' => 600 + ), + */ + 'thumbnail' => array( + // Uncomment the following to use a defined directory for the thumbnails + // instead of a subdirectory based on the version identifier. + // Make sure that this directory doesn't allow execution of files if you + // don't pose any restrictions on the type of uploaded files, e.g. by + // copying the .htaccess file from the files directory for Apache: + //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/', + //'upload_url' => $this->get_full_url().'/thumb/', + // Uncomment the following to force the max + // dimensions and e.g. create square thumbnails: + //'crop' => true, + 'max_width' => 80, + 'max_height' => 80 + ) + ) + ); + if ($options) { + $this->options = $options + $this->options; + } + if ($error_messages) { + $this->error_messages = $error_messages + $this->error_messages; + } + if ($initialize) { + $this->initialize(); + } + } + + protected function initialize() { + switch ($this->get_server_var('REQUEST_METHOD')) { + case 'OPTIONS': + case 'HEAD': + $this->head(); + break; + case 'GET': + if( $_GET['del'] ){ + $this->delete(); + } else { + $this->get(); + } + break; + case 'PATCH': + case 'PUT': + case 'POST': + $this->post(); + break; + case 'DELETE': + $this->delete(); + break; + default: + $this->header('HTTP/1.1 405 Method Not Allowed'); + } + } + + protected function get_full_url() { + $https = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'on') === 0; + return + ($https ? 'https://' : 'http://'). + (!empty($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). + (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. + ($https && $_SERVER['SERVER_PORT'] === 443 || + $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). + substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')); + } + + protected function get_user_id() { + @session_start(); + return session_id(); + } + + protected function get_user_path() { + if ($this->options['user_dirs']) { + return $this->get_user_id().'/'; + } + return ''; + } + + protected function get_upload_path($file_name = null, $version = null) { + $file_name = $file_name ? $file_name : ''; + if (empty($version)) { + $version_path = ''; + } else { + $version_dir = @$this->options['image_versions'][$version]['upload_dir']; + if ($version_dir) { + return $version_dir.$this->get_user_path().$file_name; + } + $version_path = $version.'/'; + } + return $this->options['upload_dir'].$this->get_user_path() + .$version_path.$file_name; + } + + protected function get_query_separator($url) { + return strpos($url, '?') === false ? '?' : '&'; + } + + protected function get_download_url($file_name, $version = null, $direct = false) { + if (!$direct && $this->options['download_via_php']) { + $url = $this->options['script_url'] + .$this->get_query_separator($this->options['script_url']) + .$this->get_singular_param_name() + .'='.rawurlencode($file_name); + if ($version) { + $url .= '&version='.rawurlencode($version); + } + return $url.'&download=1'; + } + if (empty($version)) { + $version_path = ''; + } else { + $version_url = @$this->options['image_versions'][$version]['upload_url']; + if ($version_url) { + return $version_url.$this->get_user_path().rawurlencode($file_name); + } + $version_path = rawurlencode($version).'/'; + } + return $this->options['upload_url'].$this->get_user_path() + .$version_path.rawurlencode($file_name); + } + + protected function set_additional_file_properties($file) { + $file->deleteUrl = $this->options['script_url'] + .$this->get_query_separator($this->options['script_url']) + .$this->get_singular_param_name() + .'='.rawurlencode($file->name); + $file->deleteType = $this->options['delete_type']; + if ($file->deleteType !== 'DELETE') { + $file->deleteUrl .= '&_method=DELETE'; + } + if ($this->options['access_control_allow_credentials']) { + $file->deleteWithCredentials = true; + } + } + + // Fix for overflowing signed 32 bit integers, + // works for sizes up to 2^32-1 bytes (4 GiB - 1): + protected function fix_integer_overflow($size) { + if ($size < 0) { + $size += 2.0 * (PHP_INT_MAX + 1); + } + return $size; + } + + protected function get_file_size($file_path, $clear_stat_cache = false) { + if ($clear_stat_cache) { + if (version_compare(PHP_VERSION, '5.3.0') >= 0) { + clearstatcache(true, $file_path); + } else { + clearstatcache(); + } + } + return $this->fix_integer_overflow(filesize($file_path)); + } + + protected function is_valid_file_object($file_name) { + $file_path = $this->get_upload_path($file_name); + if (is_file($file_path) && $file_name[0] !== '.') { + return true; + } + return false; + } + + protected function get_file_object($file_name) { + if ($this->is_valid_file_object($file_name)) { + $file = new \stdClass(); + $file->name = iconv('UTF-8', 'UTF-8//IGNORE', $file_name); + $file->size = $this->get_file_size( + $this->get_upload_path($file_name) + ); + $img_width_height = $this->get_image_size($this->get_upload_path($file_name)); + $file->width = $img_width_height[0]; + $file->height = $img_width_height[1]; + $file->url = $this->get_download_url($file->name); + foreach($this->options['image_versions'] as $version => $options) { + if (!empty($version)) { + if (is_file($this->get_upload_path($file_name, $version))) { + $file->{$version.'Url'} = $this->get_download_url( + $file->name, + $version + ); + } + } + } + $this->set_additional_file_properties($file); + return $file; + } + return null; + } + + protected function get_file_objects($iteration_method = 'get_file_object') { + $upload_dir = $this->get_upload_path(); + if (!is_dir($upload_dir)) { + return array(); + } + return array_values(array_filter(array_map( + array($this, $iteration_method), + scandir($upload_dir) + ))); + } + + protected function count_file_objects() { + return count($this->get_file_objects('is_valid_file_object')); + } + + protected function get_error_message($error) { + return array_key_exists($error, $this->error_messages) ? + $this->error_messages[$error] : $error; + } + + function get_config_bytes($val) { + $val = trim($val); + $last = strtolower($val[strlen($val)-1]); + switch($last) { + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + case 'k': + $val *= 1024; + } + return $this->fix_integer_overflow($val); + } + + protected function validate($uploaded_file, $file, $error, $index) { + if ($error) { + $file->error = $this->get_error_message($error); + return false; + } + $content_length = $this->fix_integer_overflow(intval( + $this->get_server_var('CONTENT_LENGTH') + )); + $post_max_size = $this->get_config_bytes($this->post_max_size); + + if ($post_max_size && ($content_length > $post_max_size)) { + $file->error = $this->get_error_message('post_max_size'); + return false; + } + if (!preg_match($this->options['accept_file_types'], $file->name)) { + $file->error = $this->get_error_message('accept_file_types'); + return false; + } + if ($uploaded_file && is_uploaded_file($uploaded_file)) { + $file_size = $this->get_file_size($uploaded_file); + } else { + $file_size = $content_length; + } + if ($this->options['max_file_size'] && ( + $file_size > $this->options['max_file_size'] || + $file->size > $this->options['max_file_size']) + ) { + $file->error = $this->get_error_message('max_file_size'); + return false; + } + if ($this->options['min_file_size'] && + $file_size < $this->options['min_file_size']) { + $file->error = $this->get_error_message('min_file_size'); + return false; + } + if (is_int($this->options['max_number_of_files']) && + ($this->count_file_objects() >= $this->options['max_number_of_files']) && + // Ignore additional chunks of existing files: + !is_file($this->get_upload_path($file->name))) { + $file->error = $this->get_error_message('max_number_of_files'); + return false; + } + $max_width = @$this->options['max_width']; + $max_height = @$this->options['max_height']; + $min_width = @$this->options['min_width']; + $min_height = @$this->options['min_height']; + if (($max_width || $max_height || $min_width || $min_height) + && preg_match($this->options['image_file_types'], $file->name)) { + list($img_width, $img_height) = $this->get_image_size($uploaded_file); + } + + if (!empty($img_width)) { + if ($max_width && $img_width > $max_width) { + $file->error = $this->get_error_message('max_width'); + return false; + } + if ($max_height && $img_height > $max_height) { + $file->error = $this->get_error_message('max_height'); + return false; + } + if ($min_width && $img_width < $min_width) { + $file->error = $this->get_error_message('min_width'); + return false; + } + if ($min_height && $img_height < $min_height) { + $file->error = $this->get_error_message('min_height'); + return false; + } + } + return true; + } + + protected function upcount_name_callback($matches) { + $index = isset($matches[1]) ? intval($matches[1]) + 1 : 1; + $ext = isset($matches[2]) ? $matches[2] : ''; + return ' ('.$index.')'.$ext; + } + + protected function upcount_name($name) { + return preg_replace_callback( + '/(?:(?: \(([\d]+)\))?(\.[^.]+))?$/', + array($this, 'upcount_name_callback'), + $name, + 1 + ); + } + + protected function get_unique_filename($file_path, $name, $size, $type, $error, + $index, $content_range) { + while(is_dir($this->get_upload_path($name))) { + $name = $this->upcount_name($name); + } + // Keep an existing filename if this is part of a chunked upload: + $uploaded_bytes = $this->fix_integer_overflow(intval($content_range[1])); + while(is_file($this->get_upload_path($name))) { + if ($uploaded_bytes === $this->get_file_size( + $this->get_upload_path($name))) { + break; + } + $name = $this->upcount_name($name); + } + return $name; + } + + protected function trim_file_name($file_path, $name, $size, $type, $error, + $index, $content_range) { + // Remove path information and dots around the filename, to prevent uploading + // into different directories or replacing hidden system files. + // Also remove control characters and spaces (\x00..\x20) around the filename: + $name = trim(basename(stripslashes($name)), ".\x00..\x20"); + // Use a timestamp for empty filenames: + if (!$name) { + $name = str_replace('.', '-', microtime(true)); + } + // Add missing file extension for known image types: + if (strpos($name, '.') === false && + preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { + $name .= '.'.$matches[1]; + } + if (function_exists('exif_imagetype')) { + switch(@exif_imagetype($file_path)){ + case IMAGETYPE_JPEG: + $extensions = array('jpg', 'jpeg'); + break; + case IMAGETYPE_PNG: + $extensions = array('png'); + break; + case IMAGETYPE_GIF: + $extensions = array('gif'); + break; + } + // Adjust incorrect image file extensions: + if (!empty($extensions)) { + $parts = explode('.', $name); + $extIndex = count($parts) - 1; + $ext = strtolower(@$parts[$extIndex]); + if (!in_array($ext, $extensions)) { + $parts[$extIndex] = $extensions[0]; + $name = implode('.', $parts); + } + } + } + return $name; + } + + protected function get_file_name($file_path, $name, $size, $type, $error, + $index, $content_range) { + return $this->get_unique_filename( + $file_path, + $this->trim_file_name($file_path, $name, $size, $type, $error, + $index, $content_range), + $size, + $type, + $error, + $index, + $content_range + ); + } + + protected function handle_form_data($file, $index) { + // Handle form data, e.g. $_REQUEST['description'][$index] + } + + protected function get_scaled_image_file_paths($file_name, $version) { + $file_path = $this->get_upload_path($file_name); + if (!empty($version)) { + $version_dir = $this->get_upload_path(null, $version); + if (!is_dir($version_dir)) { + mkdir($version_dir, $this->options['mkdir_mode'], true); + } + $new_file_path = $version_dir.'/'.$file_name; + } else { + $new_file_path = $file_path; + } + return array($file_path, $new_file_path); + } + + protected function gd_get_image_object($file_path, $func, $no_cache = false) { + if (empty($this->image_objects[$file_path]) || $no_cache) { + $this->gd_destroy_image_object($file_path); + $this->image_objects[$file_path] = $func($file_path); + } + return $this->image_objects[$file_path]; + } + + protected function gd_set_image_object($file_path, $image) { + $this->gd_destroy_image_object($file_path); + $this->image_objects[$file_path] = $image; + } + + protected function gd_destroy_image_object($file_path) { + $image = @$this->image_objects[$file_path]; + return $image && imagedestroy($image); + } + + protected function gd_imageflip($image, $mode) { + if (function_exists('imageflip')) { + return imageflip($image, $mode); + } + $new_width = $src_width = imagesx($image); + $new_height = $src_height = imagesy($image); + $new_img = imagecreatetruecolor($new_width, $new_height); + $src_x = 0; + $src_y = 0; + switch ($mode) { + case '1': // flip on the horizontal axis + $src_y = $new_height - 1; + $src_height = -$new_height; + break; + case '2': // flip on the vertical axis + $src_x = $new_width - 1; + $src_width = -$new_width; + break; + case '3': // flip on both axes + $src_y = $new_height - 1; + $src_height = -$new_height; + $src_x = $new_width - 1; + $src_width = -$new_width; + break; + default: + return $image; + } + imagecopyresampled( + $new_img, + $image, + 0, + 0, + $src_x, + $src_y, + $new_width, + $new_height, + $src_width, + $src_height + ); + return $new_img; + } + + protected function gd_orient_image($file_path, $src_img) { + if (!function_exists('exif_read_data')) { + return false; + } + $exif = @exif_read_data($file_path); + if ($exif === false) { + return false; + } + $orientation = intval(@$exif['Orientation']); + if ($orientation < 2 || $orientation > 8) { + return false; + } + switch ($orientation) { + case 2: + $new_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 + ); + break; + case 3: + $new_img = imagerotate($src_img, 180, 0); + break; + case 4: + $new_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 + ); + break; + case 5: + $tmp_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_HORIZONTAL') ? IMG_FLIP_HORIZONTAL : 1 + ); + $new_img = imagerotate($tmp_img, 270, 0); + imagedestroy($tmp_img); + break; + case 6: + $new_img = imagerotate($src_img, 270, 0); + break; + case 7: + $tmp_img = $this->gd_imageflip( + $src_img, + defined('IMG_FLIP_VERTICAL') ? IMG_FLIP_VERTICAL : 2 + ); + $new_img = imagerotate($tmp_img, 270, 0); + imagedestroy($tmp_img); + break; + case 8: + $new_img = imagerotate($src_img, 90, 0); + break; + default: + return false; + } + $this->gd_set_image_object($file_path, $new_img); + return true; + } + + protected function gd_create_scaled_image($file_name, $version, $options) { + if (!function_exists('imagecreatetruecolor')) { + error_log('Function not found: imagecreatetruecolor'); + return false; + } + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $type = strtolower(substr(strrchr($file_name, '.'), 1)); + switch ($type) { + case 'jpg': + case 'jpeg': + $src_func = 'imagecreatefromjpeg'; + $write_func = 'imagejpeg'; + $image_quality = isset($options['jpeg_quality']) ? + $options['jpeg_quality'] : 75; + break; + case 'gif': + $src_func = 'imagecreatefromgif'; + $write_func = 'imagegif'; + $image_quality = null; + break; + case 'png': + $src_func = 'imagecreatefrompng'; + $write_func = 'imagepng'; + $image_quality = isset($options['png_quality']) ? + $options['png_quality'] : 9; + break; + default: + return false; + } + $src_img = $this->gd_get_image_object( + $file_path, + $src_func, + !empty($options['no_cache']) + ); + $image_oriented = false; + if (!empty($options['auto_orient']) && $this->gd_orient_image( + $file_path, + $src_img + )) { + $image_oriented = true; + $src_img = $this->gd_get_image_object( + $file_path, + $src_func + ); + } + $max_width = $img_width = imagesx($src_img); + $max_height = $img_height = imagesy($src_img); + if (!empty($options['max_width'])) { + $max_width = $options['max_width']; + } + if (!empty($options['max_height'])) { + $max_height = $options['max_height']; + } + $scale = min( + $max_width / $img_width, + $max_height / $img_height + ); + if ($scale >= 1) { + if ($image_oriented) { + return $write_func($src_img, $new_file_path, $image_quality); + } + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + if (empty($options['crop'])) { + $new_width = $img_width * $scale; + $new_height = $img_height * $scale; + $dst_x = 0; + $dst_y = 0; + $new_img = imagecreatetruecolor($new_width, $new_height); + } else { + if (($img_width / $img_height) >= ($max_width / $max_height)) { + $new_width = $img_width / ($img_height / $max_height); + $new_height = $max_height; + } else { + $new_width = $max_width; + $new_height = $img_height / ($img_width / $max_width); + } + $dst_x = 0 - ($new_width - $max_width) / 2; + $dst_y = 0 - ($new_height - $max_height) / 2; + $new_img = imagecreatetruecolor($max_width, $max_height); + } + // Handle transparency in GIF and PNG images: + switch ($type) { + case 'gif': + case 'png': + imagecolortransparent($new_img, imagecolorallocate($new_img, 0, 0, 0)); + case 'png': + imagealphablending($new_img, false); + imagesavealpha($new_img, true); + break; + } + $success = imagecopyresampled( + $new_img, + $src_img, + $dst_x, + $dst_y, + 0, + 0, + $new_width, + $new_height, + $img_width, + $img_height + ) && $write_func($new_img, $new_file_path, $image_quality); + $this->gd_set_image_object($file_path, $new_img); + return $success; + } + + protected function imagick_get_image_object($file_path, $no_cache = false) { + if (empty($this->image_objects[$file_path]) || $no_cache) { + $this->imagick_destroy_image_object($file_path); + $image = new \Imagick(); + if (!empty($this->options['imagick_resource_limits'])) { + foreach ($this->options['imagick_resource_limits'] as $type => $limit) { + $image->setResourceLimit($type, $limit); + } + } + $image->readImage($file_path); + $this->image_objects[$file_path] = $image; + } + return $this->image_objects[$file_path]; + } + + protected function imagick_set_image_object($file_path, $image) { + $this->imagick_destroy_image_object($file_path); + $this->image_objects[$file_path] = $image; + } + + protected function imagick_destroy_image_object($file_path) { + $image = @$this->image_objects[$file_path]; + return $image && $image->destroy(); + } + + protected function imagick_orient_image($image) { + $orientation = $image->getImageOrientation(); + $background = new \ImagickPixel('none'); + switch ($orientation) { + case \imagick::ORIENTATION_TOPRIGHT: // 2 + $image->flopImage(); // horizontal flop around y-axis + break; + case \imagick::ORIENTATION_BOTTOMRIGHT: // 3 + $image->rotateImage($background, 180); + break; + case \imagick::ORIENTATION_BOTTOMLEFT: // 4 + $image->flipImage(); // vertical flip around x-axis + break; + case \imagick::ORIENTATION_LEFTTOP: // 5 + $image->flopImage(); // horizontal flop around y-axis + $image->rotateImage($background, 270); + break; + case \imagick::ORIENTATION_RIGHTTOP: // 6 + $image->rotateImage($background, 90); + break; + case \imagick::ORIENTATION_RIGHTBOTTOM: // 7 + $image->flipImage(); // vertical flip around x-axis + $image->rotateImage($background, 270); + break; + case \imagick::ORIENTATION_LEFTBOTTOM: // 8 + $image->rotateImage($background, 270); + break; + default: + return false; + } + $image->setImageOrientation(\imagick::ORIENTATION_TOPLEFT); // 1 + return true; + } + + protected function imagick_create_scaled_image($file_name, $version, $options) { + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $image = $this->imagick_get_image_object( + $file_path, + !empty($options['no_cache']) + ); + if ($image->getImageFormat() === 'GIF') { + // Handle animated GIFs: + $images = $image->coalesceImages(); + foreach ($images as $frame) { + $image = $frame; + $this->imagick_set_image_object($file_name, $image); + break; + } + } + $image_oriented = false; + if (!empty($options['auto_orient'])) { + $image_oriented = $this->imagick_orient_image($image); + } + $new_width = $max_width = $img_width = $image->getImageWidth(); + $new_height = $max_height = $img_height = $image->getImageHeight(); + if (!empty($options['max_width'])) { + $new_width = $max_width = $options['max_width']; + } + if (!empty($options['max_height'])) { + $new_height = $max_height = $options['max_height']; + } + if (!($image_oriented || $max_width < $img_width || $max_height < $img_height)) { + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + $crop = !empty($options['crop']); + if ($crop) { + $x = 0; + $y = 0; + if (($img_width / $img_height) >= ($max_width / $max_height)) { + $new_width = 0; // Enables proportional scaling based on max_height + $x = ($img_width / ($img_height / $max_height) - $max_width) / 2; + } else { + $new_height = 0; // Enables proportional scaling based on max_width + $y = ($img_height / ($img_width / $max_width) - $max_height) / 2; + } + } + $success = $image->resizeImage( + $new_width, + $new_height, + isset($options['filter']) ? $options['filter'] : \imagick::FILTER_LANCZOS, + isset($options['blur']) ? $options['blur'] : 1, + $new_width && $new_height // fit image into constraints if not to be cropped + ); + if ($success && $crop) { + $success = $image->cropImage( + $max_width, + $max_height, + $x, + $y + ); + if ($success) { + $success = $image->setImagePage($max_width, $max_height, 0, 0); + } + } + $type = strtolower(substr(strrchr($file_name, '.'), 1)); + switch ($type) { + case 'jpg': + case 'jpeg': + if (!empty($options['jpeg_quality'])) { + $image->setImageCompression(\imagick::COMPRESSION_JPEG); + $image->setImageCompressionQuality($options['jpeg_quality']); + } + break; + } + if (!empty($options['strip'])) { + $image->stripImage(); + } + return $success && $image->writeImage($new_file_path); + } + + protected function imagemagick_create_scaled_image($file_name, $version, $options) { + list($file_path, $new_file_path) = + $this->get_scaled_image_file_paths($file_name, $version); + $resize = @$options['max_width'] + .(empty($options['max_height']) ? '' : 'X'.$options['max_height']); + if (!$resize && empty($options['auto_orient'])) { + if ($file_path !== $new_file_path) { + return copy($file_path, $new_file_path); + } + return true; + } + $cmd = $this->options['convert_bin']; + if (!empty($this->options['convert_params'])) { + $cmd .= ' '.$this->options['convert_params']; + } + $cmd .= ' '.escapeshellarg($file_path); + if (!empty($options['auto_orient'])) { + $cmd .= ' -auto-orient'; + } + if ($resize) { + // Handle animated GIFs: + $cmd .= ' -coalesce'; + if (empty($options['crop'])) { + $cmd .= ' -resize '.escapeshellarg($resize.'>'); + } else { + $cmd .= ' -resize '.escapeshellarg($resize.'^'); + $cmd .= ' -gravity center'; + $cmd .= ' -crop '.escapeshellarg($resize.'+0+0'); + } + // Make sure the page dimensions are correct (fixes offsets of animated GIFs): + $cmd .= ' +repage'; + } + if (!empty($options['convert_params'])) { + $cmd .= ' '.$options['convert_params']; + } + $cmd .= ' '.escapeshellarg($new_file_path); + exec($cmd, $output, $error); + if ($error) { + error_log(implode('\n', $output)); + return false; + } + return true; + } + + protected function get_image_size($file_path) { + if ($this->options['image_library']) { + if (extension_loaded('imagick')) { + $image = new \Imagick(); + try { + if (@$image->pingImage($file_path)) { + $dimensions = array($image->getImageWidth(), $image->getImageHeight()); + $image->destroy(); + return $dimensions; + } + return false; + } catch (Exception $e) { + error_log($e->getMessage()); + } + } + if ($this->options['image_library'] === 2) { + $cmd = $this->options['identify_bin']; + $cmd .= ' -ping '.escapeshellarg($file_path); + exec($cmd, $output, $error); + if (!$error && !empty($output)) { + // image.jpg JPEG 1920x1080 1920x1080+0+0 8-bit sRGB 465KB 0.000u 0:00.000 + $infos = preg_split('/\s+/', $output[0]); + $dimensions = preg_split('/x/', $infos[2]); + return $dimensions; + } + return false; + } + } + if (!function_exists('getimagesize')) { + error_log('Function not found: getimagesize'); + return false; + } + return @getimagesize($file_path); + } + + protected function create_scaled_image($file_name, $version, $options) { + if ($this->options['image_library'] === 2) { + return $this->imagemagick_create_scaled_image($file_name, $version, $options); + } + if ($this->options['image_library'] && extension_loaded('imagick')) { + return $this->imagick_create_scaled_image($file_name, $version, $options); + } + return $this->gd_create_scaled_image($file_name, $version, $options); + } + + protected function destroy_image_object($file_path) { + if ($this->options['image_library'] && extension_loaded('imagick')) { + return $this->imagick_destroy_image_object($file_path); + } + } + + protected function is_valid_image_file($file_path) { + if (!preg_match($this->options['image_file_types'], $file_path)) { + return false; + } + if (function_exists('exif_imagetype')) { + return @exif_imagetype($file_path); + } + $image_info = $this->get_image_size($file_path); + return $image_info && $image_info[0] && $image_info[1]; + } + + protected function handle_image_file($file_path, $file) { + $failed_versions = array(); + foreach($this->options['image_versions'] as $version => $options) { + if ($this->create_scaled_image($file->name, $version, $options)) { + if (!empty($version)) { + $file->{$version.'Url'} = $this->get_download_url( + $file->name, + $version + ); + } else { + $file->size = $this->get_file_size($file_path, true); + } + } else { + $failed_versions[] = $version ? $version : 'original'; + } + } + if (count($failed_versions)) { + $file->error = $this->get_error_message('image_resize') + .' ('.implode($failed_versions,', ').')'; + } + // Free memory: + $this->destroy_image_object($file_path); + } + + protected function get_microtime(){ + list($usec, $sec) = explode(" ",microtime()); + return ((float)$usec + (float)$sec); + } + + protected function get_file_passname(){ + $tmp_name = $this->get_user_id().$_SERVER['REMOTE_ADDR']; + $tmp_name = md5(sha1($tmp_name)); + return $tmp_name; + } + + protected function reprocessImage($file_path, $callback) + { + // Extracting mime type using getimagesize + try { + $image_info = getimagesize($file_path); + if ($image_info === null) { + //throw new Exception("Invalid image type"); + return false; + } + + $mime_type = $image_info["mime"]; + + if (!array_key_exists($mime_type, self::$MIME_TYPES_PROCESSORS)) { + //throw new Exception("Invalid image MIME type"); + return false; + } + + $image_from_file = self::$MIME_TYPES_PROCESSORS[$mime_type][0]; + $image_to_file = self::$MIME_TYPES_PROCESSORS[$mime_type][1]; + + $reprocessed_image = @$image_from_file($file_path); + + if (!$reprocessed_image) { + //throw new Exception("Unable to create reprocessed image from file"); + return false; + } + + // Calling callback(if set) with path of image as a parameter + if ($callback !== null) { + $callback($reprocessed_image); + } + + // Freeing up memory + imagedestroy($reprocessed_image); + } catch (Exception $e) { + unlink($file_path); + return false; + } + + return true; + } + + protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, + $index = null, $content_range = null) { + $file = new \stdClass(); + $file->oriname = $this->get_file_name($uploaded_file, $name, $size, $type, $error, + $index, $content_range); + + $filename_ext = pathinfo($name, PATHINFO_EXTENSION); + $file->name = $this->get_file_passname().'_'.str_replace(".", "_", $this->get_microtime()).".".$filename_ext; + + //$file->name = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($file->name)); + $file->size = $this->fix_integer_overflow(intval($size)); + $file->type = $type; + + if ( SMARTEDITOR_UPLOAD_IMG_CHECK && ! $this->reprocessImage($uploaded_file, null) ){ + $file->error = $this->get_error_message('accept_file_types'); + return $file; + } + + if ($this->validate($uploaded_file, $file, $error, $index)) { + $this->handle_form_data($file, $index); + $upload_dir = $this->get_upload_path(); + if (!is_dir($upload_dir)) { + mkdir($upload_dir, $this->options['mkdir_mode'], true); + } + $file_path = $this->get_upload_path($file->name); + $append_file = $content_range && is_file($file_path) && + $file->size > $this->get_file_size($file_path); + if ($uploaded_file && is_uploaded_file($uploaded_file)) { + // multipart/formdata uploads (POST method uploads) + if ($append_file) { + file_put_contents( + $file_path, + fopen($uploaded_file, 'r'), + FILE_APPEND + ); + } else { + move_uploaded_file($uploaded_file, $file_path); + } + } else { + // Non-multipart uploads (PUT method support) + file_put_contents( + $file_path, + fopen('php://input', 'r'), + $append_file ? FILE_APPEND : 0 + ); + } + $file_size = $this->get_file_size($file_path, $append_file); + + try { + if(defined('G5_FILE_PERMISSION')) chmod($file_path, G5_FILE_PERMISSION); + } catch (Exception $e) { + } + + if ($file_size === $file->size) { + $file->url = $this->get_download_url($file->name); + if ($this->is_valid_image_file($file_path)) { + $this->handle_image_file($file_path, $file); + + $this->files[] = $file->name; + + if( $this->options['is_resize'] ){ + $resize_options = array( + 'max_width'=>$this->options['resize_max_width'], + 'max_height'=>$this->options['resize_max_height'], + 'jpeg_quality'=>$this->options['resize_jpeg_compress'], + 'auto_orient' => true, + ); + + if ($this->create_scaled_image($file->name, '', $resize_options)) { + $file->size = $this->get_file_size($file_path, true); + } + } + + $image_width_height = $this->get_image_size($file_path); + $file->width = $image_width_height[0]; + $file->height = $image_width_height[1]; + } else { //로빈아빠님이 알려주심, 이미지 업로드 체크 + unlink($file_path); + $file->error = $this->get_error_message('accept_file_types'); + } + } else { + $file->size = $file_size; + if (!$content_range && $this->options['discard_aborted_uploads']) { + unlink($file_path); + $file->error = $this->get_error_message('abort'); + } + } + $this->set_additional_file_properties($file); + } + + return $file; + } + + protected function readfile($file_path) { + $file_size = $this->get_file_size($file_path); + $chunk_size = $this->options['readfile_chunk_size']; + if ($chunk_size && $file_size > $chunk_size) { + $handle = fopen($file_path, 'rb'); + while (!feof($handle)) { + echo fread($handle, $chunk_size); + ob_flush(); + flush(); + } + fclose($handle); + return $file_size; + } + return readfile($file_path); + } + + protected function body($str) { + echo $str; + } + + protected function header($str) { + header($str); + } + + protected function get_server_var($id) { + return isset($_SERVER[$id]) ? $_SERVER[$id] : ''; + } + + protected function generate_response($content, $print_response = true) { + if ($print_response) { + $json = json_encode($content); + + $redirect = isset($_REQUEST['redirect']) ? + stripslashes($_REQUEST['redirect']) : null; + if ($redirect) { + $this->header('Location: '.sprintf($redirect, rawurlencode($json))); + return; + } + $this->head(); + if ($this->get_server_var('HTTP_CONTENT_RANGE')) { + $files = isset($content[$this->options['param_name']]) ? + $content[$this->options['param_name']] : null; + if ($files && is_array($files) && is_object($files[0]) && $files[0]->size) { + $this->header('Range: 0-'.( + $this->fix_integer_overflow(intval($files[0]->size)) - 1 + )); + } + } + $this->body($json); + } + return $content; + } + + protected function get_version_param() { + return isset($_GET['version']) ? basename(stripslashes($_GET['version'])) : null; + } + + protected function get_singular_param_name() { + return substr($this->options['param_name'], 0, -1); + } + + protected function get_file_name_param() { + $name = $this->get_singular_param_name(); + return isset($_GET[$name]) ? basename(stripslashes($_GET[$name])) : null; + } + + protected function get_file_names_params() { + $params = isset($_GET[$this->options['param_name']]) ? + $_GET[$this->options['param_name']] : array(); + foreach ($params as $key => $value) { + $params[$key] = basename(stripslashes($value)); + } + return $params; + } + + protected function get_file_type($file_path) { + switch (strtolower(pathinfo($file_path, PATHINFO_EXTENSION))) { + case 'jpeg': + case 'jpg': + return 'image/jpeg'; + case 'png': + return 'image/png'; + case 'gif': + return 'image/gif'; + default: + return ''; + } + } + + protected function download() { + switch ($this->options['download_via_php']) { + case 1: + $redirect_header = null; + break; + case 2: + $redirect_header = 'X-Sendfile'; + break; + case 3: + $redirect_header = 'X-Accel-Redirect'; + break; + default: + return $this->header('HTTP/1.1 403 Forbidden'); + } + $file_name = $this->get_file_name_param(); + if (!$this->is_valid_file_object($file_name)) { + return $this->header('HTTP/1.1 404 Not Found'); + } + if ($redirect_header) { + return $this->header( + $redirect_header.': '.$this->get_download_url( + $file_name, + $this->get_version_param(), + true + ) + ); + } + $file_path = $this->get_upload_path($file_name, $this->get_version_param()); + // Prevent browsers from MIME-sniffing the content-type: + $this->header('X-Content-Type-Options: nosniff'); + if (!preg_match($this->options['inline_file_types'], $file_name)) { + $this->header('Content-Type: application/octet-stream'); + $this->header('Content-Disposition: attachment; filename="'.$file_name.'"'); + } else { + $this->header('Content-Type: '.$this->get_file_type($file_path)); + $this->header('Content-Disposition: inline; filename="'.$file_name.'"'); + } + $this->header('Content-Length: '.$this->get_file_size($file_path)); + $this->header('Last-Modified: '.gmdate('D, d M Y H:i:s T', filemtime($file_path))); + $this->readfile($file_path); + } + + protected function send_content_type_header() { + $this->header('Vary: Accept'); + if (strpos($this->get_server_var('HTTP_ACCEPT'), 'application/json') !== false) { + $this->header('Content-type: application/json'); + } else { + $this->header('Content-type: text/plain'); + } + } + + protected function send_access_control_headers() { + $this->header('Access-Control-Allow-Origin: '.$this->options['access_control_allow_origin']); + $this->header('Access-Control-Allow-Credentials: ' + .($this->options['access_control_allow_credentials'] ? 'true' : 'false')); + $this->header('Access-Control-Allow-Methods: ' + .implode(', ', $this->options['access_control_allow_methods'])); + $this->header('Access-Control-Allow-Headers: ' + .implode(', ', $this->options['access_control_allow_headers'])); + } + + public function head() { + $this->header('Pragma: no-cache'); + $this->header('Cache-Control: no-store, no-cache, must-revalidate'); + $this->header('Content-Disposition: inline; filename="files.json"'); + // Prevent Internet Explorer from MIME-sniffing the content-type: + $this->header('X-Content-Type-Options: nosniff'); + if ($this->options['access_control_allow_origin']) { + $this->send_access_control_headers(); + } + $this->send_content_type_header(); + } + + public function get($print_response = true) { + //보안 이슈로 인해 사용하지 않습니다. + /* + if ($print_response && isset($_GET['download'])) { + return $this->download(); + } + $file_name = $this->get_file_name_param(); + if ($file_name) { + $response = array( + $this->get_singular_param_name() => $this->get_file_object($file_name) + ); + } else { + $response = array( + $this->options['param_name'] => $this->get_file_objects() + ); + } + return $this->generate_response($response, $print_response); + */ + } + + public function post($print_response = true) { + if (isset($_REQUEST['_method']) && $_REQUEST['_method'] === 'DELETE') { + return $this->delete($print_response); + } + $upload = isset($_FILES[$this->options['param_name']]) ? + $_FILES[$this->options['param_name']] : null; + // Parse the Content-Disposition header, if available: + $file_name = $this->get_server_var('HTTP_CONTENT_DISPOSITION') ? + rawurldecode(preg_replace( + '/(^[^"]+")|("$)/', + '', + $this->get_server_var('HTTP_CONTENT_DISPOSITION') + )) : null; + // Parse the Content-Range header, which has the following form: + // Content-Range: bytes 0-524287/2000000 + $content_range = $this->get_server_var('HTTP_CONTENT_RANGE') ? + preg_split('/[^0-9]+/', $this->get_server_var('HTTP_CONTENT_RANGE')) : null; + $size = $content_range ? $content_range[3] : null; + $files = array(); + if ($upload && is_array($upload['tmp_name'])) { + // param_name is an array identifier like "files[]", + // $_FILES is a multi-dimensional array: + foreach ($upload['tmp_name'] as $index => $value) { + $files[] = $this->handle_file_upload( + $upload['tmp_name'][$index], + $file_name ? $file_name : $upload['name'][$index], + $size ? $size : $upload['size'][$index], + $upload['type'][$index], + $upload['error'][$index], + $index, + $content_range + ); + } + } else { + // param_name is a single object identifier like "file", + // $_FILES is a one-dimensional array: + $files[] = $this->handle_file_upload( + isset($upload['tmp_name']) ? $upload['tmp_name'] : null, + $file_name ? $file_name : (isset($upload['name']) ? + $upload['name'] : null), + $size ? $size : (isset($upload['size']) ? + $upload['size'] : $this->get_server_var('CONTENT_LENGTH')), + isset($upload['type']) ? + $upload['type'] : $this->get_server_var('CONTENT_TYPE'), + isset($upload['error']) ? $upload['error'] : null, + null, + $content_range + ); + } + return $this->generate_response( + array($this->options['param_name'] => $files), + $print_response + ); + } + + public function delete($print_response = true) { + /* 보안 이슈 url을 참고 https://github.com/blueimp/jQuery-File-Upload/issues/2426 */ + $file_names = $this->get_file_names_params(); + if (empty($file_names)) { + $file_names = array($this->get_file_name_param()); + } + $response = array(); + foreach($file_names as $file_name) { + if( substr($file_name, 0 , 32) != $this->get_file_passname() ) continue; //session_id() 와 비교하여 틀리면 지우지 않음 + $file_path = $this->get_upload_path($file_name); + $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path); + if ($success) { + foreach($this->options['image_versions'] as $version => $options) { + if (!empty($version)) { + $file = $this->get_upload_path($file_name, $version); + if (is_file($file)) { + unlink($file); + } + } + } + } + $response[$file_name] = $success; + } + return $this->generate_response($response, $print_response); + } + +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/_common.php b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/_common.php new file mode 100644 index 0000000..e66fc93 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/index.php b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/index.php new file mode 100644 index 0000000..ddd6398 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/php/index.php @@ -0,0 +1,58 @@ +encode($data) ); + } +} + +@ini_set('gd.jpeg_ignore_warning', 1); + +$ym = date('ym', G5_SERVER_TIME); + +$data_dir = G5_DATA_PATH.'/editor/'.$ym.'/'; +$data_url = G5_DATA_URL.'/editor/'.$ym.'/'; + +@mkdir($data_dir, G5_DIR_PERMISSION); +@chmod($data_dir, G5_DIR_PERMISSION); + +if(!function_exists('ft_nonce_is_valid')){ + include_once('../../../editor.lib.php'); +} + +$is_editor_upload = false; + +if( isset($_GET['_nonce']) && ft_nonce_is_valid( $_GET['_nonce'] , 'smarteditor' ) ){ + $is_editor_upload = true; +} + +if( $is_editor_upload ) { + + require('UploadHandler.php'); + $options = array( + 'upload_dir' => $data_dir, + 'upload_url' => $data_url, + // This option will disable creating thumbnail images and will not create that extra folder. + // However, due to this, the images preview will not be displayed after upload + 'image_versions' => array() + ); + + $upload_handler = new UploadHandler($options); + +} else { + echo json_encode(array('files'=>array('0'=>array('error'=>'정상적인 업로드가 아닙니다.')))); + exit; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/XPButtonUploadText_61x22.png b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/XPButtonUploadText_61x22.png new file mode 100644 index 0000000000000000000000000000000000000000..df7aa6eab8cb94069d2bc5d640eba51bc9ce5fc4 GIT binary patch literal 1855 zcmV-F2f+A=P)?00007bV*G`2iOS* z76>od-3GY;000SaNLh0L01FZT01FZU(%pXi00004XF*Lt006O%3;baP000KgNkl4+2tEi3zEmZMMSKzj zse<%DBKYJ5gah8i}0n|dlOd0|w-qe(W#l`t$ z?~{|JD&r|gD+XETf+z4|zrVOYm;2(iPi>~L;&u_ElzOsP8|MX1eWG74CDMAu&44PA zZfR+Ug@qY@)PZ%Y_Hv9l&Wq0*Y4D%4KB)QmJ7t5E>ll|xb(Go6adtkdc4+fD(~2WY zk1!7^iYQ&v<;O~(4tDC$#yKvPT3bW^c4IRwWPYZ%m0z|w#kIDsgSolsGCSJb_HQ>f zi-k;gRwg_MT4K|E~ab4#2jCyg@7xrwW=^`RDaQ(k0r*&nHn zbmsCXEG|S#a^epg?12gik6)kRvJrXn(_xyqc?XW{-3$X;I>H{K|D-`I+Y>kE;rPfU z*w))6@_6X$AL+NhosYdR`0{go@cBDO2)_*#%1Qi@F9_X$tD)_6^YGe%$Dw_VT4T4- z#gdwYFMj$PX7jB;wjchOo;lVBt&4vFsc)~n_lSb#W?-)A2^c(jL8zhaiD|xr(QWTS zB==cAF!~|1CI2(jP$-K1%h1Z=2FjnIiJIdzaYt6n#hNtk)r!PZ%(S{Zq{CE0Wu8Jg zQI~Xg#j>*1P~<6z{ghXTFCs#5rH2IO9p8u+;csk6|07_Y$iNR(Me}n0{Ao2 zQB^}BkJ*fI&8t`q<<~TED%8U&#N_UkF zh8nt2JqxdPd=~Z)1ILN!x8YXf-~%-@_9#D6E-9imL`qD0VYWsRfBsPE5o5-<%R^=+k`Lrv*rNzB)6$c4l>BaS|| z5UV!kQOD}^h;Q+k^hDZ4@X{Uuc6s|3$8?X)^q zT6yjIkmIcS*XxyhUO>*AI!PbfwY#cs%#5IC-4C2U_s{CQIa!^gQAR;k!4E_|wUH;6 tgHbm^8RhQXg|NpIIAP?8d{?C~_&=p96%WXS@Jj#y002ovPDHLkV1n~|kk$YI literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/fileprogress.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/fileprogress.js new file mode 100644 index 0000000..9f21a28 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/fileprogress.js @@ -0,0 +1,203 @@ +/* + A simple class for displaying file information and progress + Note: This is a demonstration only and not part of SWFUpload. + Note: Some have had problems adapting this class in IE7. It may not be suitable for your application. +*/ + +// Constructor +// file is a SWFUpload file object +// targetID is the HTML element id attribute that the FileProgress HTML structure will be added to. +// Instantiating a new FileProgress object with an existing file will reuse/update the existing DOM elements +function FileProgress(file, targetID) { + this.fileProgressID = file.id; + + this.opacity = 100; + this.height = 0; + + + this.fileProgressWrapper = document.getElementById(this.fileProgressID); + if (!this.fileProgressWrapper) { + this.fileProgressWrapper = document.createElement("div"); + this.fileProgressWrapper.className = "progressWrapper"; + this.fileProgressWrapper.id = this.fileProgressID; + + this.fileProgressElement = document.createElement("div"); + this.fileProgressElement.className = "progressContainer"; + + var progressCancel = document.createElement("a"); + progressCancel.className = "progressCancel"; + progressCancel.href = "#"; + progressCancel.style.visibility = "hidden"; + progressCancel.appendChild(document.createTextNode(" ")); + + var progressText = document.createElement("div"); + progressText.className = "progressName"; + progressText.appendChild(document.createTextNode(file.name)); + + var progressBar = document.createElement("div"); + progressBar.className = "progressBarInProgress"; + + var progressStatus = document.createElement("div"); + progressStatus.className = "progressBarStatus"; + progressStatus.innerHTML = " "; + + this.fileProgressElement.appendChild(progressCancel); + this.fileProgressElement.appendChild(progressText); + this.fileProgressElement.appendChild(progressStatus); + this.fileProgressElement.appendChild(progressBar); + + this.fileProgressWrapper.appendChild(this.fileProgressElement); + + document.getElementById(targetID).appendChild(this.fileProgressWrapper); + } else { + this.fileProgressElement = this.fileProgressWrapper.firstChild; + this.reset(); + } + + this.height = this.fileProgressWrapper.offsetHeight; + this.setTimer(null); + + +} + +FileProgress.prototype.setTimer = function (timer) { + this.fileProgressElement["FP_TIMER"] = timer; +}; +FileProgress.prototype.getTimer = function (timer) { + return this.fileProgressElement["FP_TIMER"] || null; +}; + +FileProgress.prototype.reset = function () { + this.fileProgressElement.className = "progressContainer"; + + this.fileProgressElement.childNodes[2].innerHTML = " "; + this.fileProgressElement.childNodes[2].className = "progressBarStatus"; + + this.fileProgressElement.childNodes[3].className = "progressBarInProgress"; + this.fileProgressElement.childNodes[3].style.width = "0%"; + + this.appear(); +}; + +FileProgress.prototype.setProgress = function (percentage) { + this.fileProgressElement.className = "progressContainer green"; + this.fileProgressElement.childNodes[3].className = "progressBarInProgress"; + this.fileProgressElement.childNodes[3].style.width = percentage + "%"; + + this.appear(); +}; +FileProgress.prototype.setComplete = function () { + this.fileProgressElement.className = "progressContainer blue"; + this.fileProgressElement.childNodes[3].className = "progressBarComplete"; + this.fileProgressElement.childNodes[3].style.width = ""; + + var oSelf = this; + this.setTimer(setTimeout(function () { + oSelf.disappear(); + }, 10000)); +}; +FileProgress.prototype.setError = function () { + this.fileProgressElement.className = "progressContainer red"; + this.fileProgressElement.childNodes[3].className = "progressBarError"; + this.fileProgressElement.childNodes[3].style.width = ""; + + var oSelf = this; + this.setTimer(setTimeout(function () { + oSelf.disappear(); + }, 5000)); +}; +FileProgress.prototype.setCancelled = function () { + this.fileProgressElement.className = "progressContainer"; + this.fileProgressElement.childNodes[3].className = "progressBarError"; + this.fileProgressElement.childNodes[3].style.width = ""; + + var oSelf = this; + this.setTimer(setTimeout(function () { + oSelf.disappear(); + }, 2000)); +}; +FileProgress.prototype.setStatus = function (status) { + this.fileProgressElement.childNodes[2].innerHTML = status; +}; + +// Show/Hide the cancel button +FileProgress.prototype.toggleCancel = function (show, swfUploadInstance) { + this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden"; + if (swfUploadInstance) { + var fileID = this.fileProgressID; + this.fileProgressElement.childNodes[0].onclick = function () { + swfUploadInstance.cancelUpload(fileID); + return false; + }; + } +}; + +FileProgress.prototype.appear = function () { + if (this.getTimer() !== null) { + clearTimeout(this.getTimer()); + this.setTimer(null); + } + + if (this.fileProgressWrapper.filters) { + try { + this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100; + } catch (e) { + // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. + this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=100)"; + } + } else { + this.fileProgressWrapper.style.opacity = 1; + } + + this.fileProgressWrapper.style.height = ""; + + this.height = this.fileProgressWrapper.offsetHeight; + this.opacity = 100; + this.fileProgressWrapper.style.display = ""; + +}; + +// Fades out and clips away the FileProgress box. +FileProgress.prototype.disappear = function () { + + var reduceOpacityBy = 15; + var reduceHeightBy = 4; + var rate = 30; // 15 fps + + if (this.opacity > 0) { + this.opacity -= reduceOpacityBy; + if (this.opacity < 0) { + this.opacity = 0; + } + + if (this.fileProgressWrapper.filters) { + try { + this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity; + } catch (e) { + // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. + this.fileProgressWrapper.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=" + this.opacity + ")"; + } + } else { + this.fileProgressWrapper.style.opacity = this.opacity / 100; + } + } + + if (this.height > 0) { + this.height -= reduceHeightBy; + if (this.height < 0) { + this.height = 0; + } + + this.fileProgressWrapper.style.height = this.height + "px"; + } + + if (this.height > 0 || this.opacity > 0) { + var oSelf = this; + this.setTimer(setTimeout(function () { + oSelf.disappear(); + }, rate)); + } else { + this.fileProgressWrapper.style.display = "none"; + this.setTimer(null); + } +}; \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/handlers.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/handlers.js new file mode 100644 index 0000000..e652452 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/handlers.js @@ -0,0 +1,378 @@ +/* +@author romeojks (romeojks@gmail.com) +@version 0.1 +@brief 파일 업로드 관련 +*/ + +function swfUploadPreLoad() { + var self = this; + var loading = function () { + document.getElementById("divLoadingContent").style.display = ""; + + var longLoad = function () { + document.getElementById("divLoadingContent").style.display = "none"; + document.getElementById("divLongLoading").style.display = ""; + }; + this.customSettings.loadingTimeout = setTimeout(function () { + longLoad.call(self) + }, + 15 * 1000 + ); + }; + + this.customSettings.loadingTimeout = setTimeout(function () { + loading.call(self); + }, + 1*1000 + ); +} + +function swfUploadLoaded() { + var self = this; + clearTimeout(this.customSettings.loadingTimeout); + document.getElementById("divLoadingContent").style.display = "none"; + document.getElementById("divLongLoading").style.display = "none"; + document.getElementById("divAlternateContent").style.display = "none"; +} + +function swfUploadLoadFailed() { + clearTimeout(this.customSettings.loadingTimeout); + document.getElementById("divLoadingContent").style.display = "none"; + document.getElementById("divLongLoading").style.display = "none"; + document.getElementById("divAlternateContent").style.display = ""; +} + +function fileQueued(file) { + try { + var obj = document.getElementById(this.customSettings.fileListAreaID); + var filename = file.name; + + if (filename.length > 20) { + filename = filename.substr(0,20) + "..."; + }; + + var text = filename + " (대기중...)"; + var value = last_bf_no + file.index; + var opt_obj = new Option(text, value, true, true); + obj.options[obj.options.length] = opt_obj; + } catch (ex) { + this.debug(ex); + } +} + +function fileQueueError(file, errorCode, message) { + try { + switch (errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED : + alert(message == 0 ? "더이상 업로드 할 수 없습니다." : (message == file_upload_limit ? file_upload_limit + "개 까지만 업로드 할 수 있습니다." : file_upload_limit + "개 까지만 업로드 할 수 있습니다.\n\n" + "현재 " + message + "개 남았습니다.")); + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT : + alert("업로드 가능한 파일 용량(" + file_size_limit + ")을 초과했습니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE : + alert("파일 사이즈가 '0' 입니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE : + alert("파일 타입이 올바르지 않습니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + default : + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + getfilesize(file.size) + ", Message: " + message); + break; + }; + } catch (ex) { + this.debug(ex); + }; +} + +function fileDialogComplete(numFilesSelected, numFilesQueued) { + try { + this.startUpload(); + } catch (ex) { + this.debug(ex); + }; +} + +function uploadStart(file) { + try { + if ((sum_filesize + file.size) > getfilesize1(file_allsize_limit)) { + return false; + } else { + return true; + }; + } catch (ex) { + this.debug(ex); + }; +} + +function uploadProgress(file, bytesLoaded, bytesTotal) { + try { + var obj = document.getElementById(this.customSettings.fileListAreaID); + var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); + var filename = file.name; + + if (filename.length > 20) { + filename = filename.substr(0,20) + "..."; + }; + + var text = filename + " (" + percent + " %)"; + var bf_position = last_bf_no + file.index; + + obj.options[bf_position].text = text; + } catch (ex) { + this.debug(ex); + }; +} + +function uploadSuccess(file, serverData) { + try { + var obj = document.getElementById(this.customSettings.fileListAreaID); + var bf_position = last_bf_no + file.index; + var params = { + "bo_table" : bo_table, + "wr_id" : wr_id, + "w" : w, + "bf_position" : bf_position+1 + }; + + var url = swfupload_path + "/get_file_info.php"; + $.ajax({ + type: 'post', + url: url, + data: params, + success : after_upload_success = function(req) { + var file = eval('('+req+')'); + var file_size = (file.bf_filesize / 1024).toFixed(1); + var text = file.bf_source + " (" + getfilesize(file.bf_filesize) + ")"; + var value = file.bf_no + "|" + file.bf_source + "|" + file.bf_file + "|" + file.bf_filesize + "|" + file.bf_width + "|" + file.bf_type; + obj.options[bf_position].text = text; + obj.options[bf_position].value = value; + eval("preview(file.bf_file)"); + } + }); + + sum_filesize = sum_filesize + file.size; + document.getElementById("uploader_status").innerHTML = "문서첨부제한 : " + getfilesize(sum_filesize) + " / " + file_allsize_limit + "
    파일제한크기 : " + file_size_limit + " (허용확장자 : " + file_types_description + ")"; + } catch (ex) { + this.debug(ex); + }; +} + +function uploadError(file, errorCode, message) { + try { + switch (errorCode) { + case SWFUpload.UPLOAD_ERROR.HTTP_ERROR : + alert("네트워크 에러가 발생하였습니다. 관리자에게 문의하세요.\n\n" + "File name: " + file.name); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED : + alert("파일 업로드가 실패하였습니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + case SWFUpload.UPLOAD_ERROR.IO_ERROR : + alert("입출력 에러가 발생하였습니다.\n\n" + "다른 프로그램에서 이 파일(" + file.name + ")을 사용중인지 확인하세요."); + break; + case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR : + alert("보안 에러가 발생하였습니다. 관리자에게 문의하세요.\n\n" + "File name: " + file.name); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED : + alert("업로드 가능한 파일 용량(" + file_size_limit + ")을 초과했습니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED : + alert("업로드 가능한 총파일 용량(" + file_allsize_limit + ")을 초과했습니다.\n\n" + "File name: " + file.name + ", File size: " + getfilesize(file.size)); + break; + case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED : + // If there aren't any files left (they were all cancelled) disable the cancel button + if (this.getStats().files_queued === 0) { + document.getElementById(this.customSettings.cancelButtonId).disabled = true; + }; + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED : + break; + default : + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + getfilesize(file.size) + ", Message: " + message); + break; + } + } catch (ex) { + this.debug(ex); + }; +} + +function uploadComplete(file) { + /*if (this.getStats().files_queued === 0) { + document.getElementById(this.customSettings.cancelButtonId).disabled = true; + }*/ +} + +function getfilesize(size) { + if (!size) { + return "0 Byte"; + }; + if (size < 1024) { + return (size + " Byte"); + } else if (size > 1024 && size < 1024 *1024) { + return (size / 1024).toFixed(1) + " KB"; + } else { + return (size / (1024*1024)).toFixed(2) + " MB"; + }; +} + +function getfilesize1(size) { + var file_size = size.split(" "); + if (!file_size[0]) { + return 0; + }; + if (file_size[1] == "MB") { + return (file_size[0] * (1024*1024)); + } else if (file_size[1] == "KB") { + return (file_size[0] * 1024); + } else { + return (file_size[0]); + }; +} + +function delete_file() { + try { + var obj = document.getElementById("uploaded_file_list"); + var url = swfupload_path + "/file_delete.php"; + for (var i=0; i파일제한크기 : " + file_size_limit + " (허용확장자 : " + file_types_description + ")"; + }; + }; + } catch (ex) { + this.debug(ex); + }; +} + +function delete_file_complete() { + try { + var obj = document.getElementById("uploaded_file_list"); + for (var i=0; i"; + } else if (thumb && thumb_kind == "etc") { + document.getElementById("image_preview").innerHTML = ""; + } else { + document.getElementById("image_preview").innerHTML = "미리보기"; + }; + } catch (ex) { + this.debug(ex); + }; +} + +function file_to_editor() { + try { + var files_list = document.getElementById("uploaded_file_list"); + var html = ''; + + if (!files_list.value) { + alert('파일을 선택해주세요.'); + return false; + }; + + for (var i=0; i"; + } else { + alert("이미지만 삽입 할 수 있습니다."); + //path = "download.php?bo_table=" + bo_table + "&filename=" + file.bf_file + "&filesource=" + file.bf_source + ""; + //html += "" + file.bf_source + "
    \n"; + } + }; + }; + insert_editor(html2); + } catch (ex) { + this.debug(ex); + }; +} + +function insert_editor(html) { + try { + ed_wr_content.insertContents(html); + /* + if (typeof(ed_wr_content) != "undefined") + if (geditor_wr_content.get_mode() == "WYSIWYG") { + document.getElementById("geditor_wr_content_frame").contentWindow.document.body.focus(); + geditor_wr_content.get_range(); + html = html + "
    "; + } else if (geditor_wr_content.get_mode() == "TEXT") { + html = html + "\n"; + } else { + html = html + "
    "; + } + geditor_wr_content.insert_editor(html); + } else { + document.getElementById("wr_content").value += html + "\n"; + } + */ + } catch (ex) { + this.debug(ex); + }; + +} + +function get_file_info(val) { + try { + var arr = val.split('|'); + var ret = {"bf_no":arr[0], "bf_source":arr[1], "bf_file":arr[2], "bf_filesize":arr[3], "bf_width":arr[4], "bf_type":arr[5]}; + return ret; + } catch (ex) { + this.debug(ex); + }; +} diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/jquery.swfupload.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/jquery.swfupload.js new file mode 100644 index 0000000..e8f4d5f --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/jquery.swfupload.js @@ -0,0 +1,82 @@ +/* + * SWFUpload jQuery Plugin v1.0.0 + * + * Copyright (c) 2009 Adam Royle + * Licensed under the MIT license. + * + */ + +(function($){ + + var defaultHandlers = [ + 'swfupload_preload_handler', + 'swfupload_load_failed_handler', + 'swfupload_loaded_handler', + 'file_dialog_start_handler', + 'file_queued_handler', + 'file_queue_error_handler', + 'file_dialog_complete_handler', + 'upload_resize_start_handler', + 'upload_start_handler', + 'upload_progress_handler', + 'upload_error_handler', + 'upload_success_handler', + 'upload_complete_handler', + 'mouse_click_handler', + 'mouse_out_handler', + 'mouse_over_handler', + 'queue_complete_handler' + ]; + var additionalHandlers = []; + + $.fn.swfupload = function(){ + var args = $.makeArray(arguments); + return this.each(function(){ + var swfu; + if (args.length == 1 && typeof(args[0]) == 'object') { + swfu = $(this).data('__swfu'); + if (!swfu) { + var settings = args[0]; + var $magicUploadControl = $(this); + var handlers = []; + $.merge(handlers, defaultHandlers); + $.merge(handlers, additionalHandlers); + $.each(handlers, function(i, v){ + var eventName = v.replace(/_handler$/, '').replace(/_([a-z])/g, function(){ return arguments[1].toUpperCase(); }); + settings[v] = function() { + var event = $.Event(eventName); + $magicUploadControl.trigger(event, $.makeArray(arguments)); + return !event.isDefaultPrevented(); + }; + }); + $(this).data('__swfu', new SWFUpload(settings)); + } + } else if (args.length > 0 && typeof(args[0]) == 'string') { + var methodName = args.shift(); + swfu = $(this).data('__swfu'); + if (swfu && swfu[methodName]) { + swfu[methodName].apply(swfu, args); + } + } + }); + }; + + $.swfupload = { + additionalHandlers: function() { + if (arguments.length === 0) { + return additionalHandlers.slice(); + } else { + $(arguments).each(function(i, v){ + $.merge(additionalHandlers, $.makeArray(v)); + }); + } + }, + defaultHandlers: function() { + return defaultHandlers.slice(); + }, + getInstance: function(el) { + return $(el).data('__swfu'); + } + }; + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.js new file mode 100644 index 0000000..67bee4c --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.js @@ -0,0 +1,1002 @@ +/** + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + * + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz? and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ +var SWFUpload; + +if (SWFUpload == undefined) { + SWFUpload = function (settings) { + this.initSWFUpload(settings); + }; +} + +SWFUpload.prototype.initSWFUpload = function (settings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = settings; + this.eventQueue = []; + this.movieName = "SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.2.0 2009-03-25"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; + +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function(url) { + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//)) { + return url; + } + + var currentURL = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ":" + window.location.port : ""); + + var indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return /*currentURL +*/ path + url; + +}; + + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function () { + this.ensureDefault = function (settingName, defaultValue) { + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName]; + }; + + // Upload backend settings + this.ensureDefault("upload_url", ""); + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + + this.ensureDefault("debug_handler", this.debugMessage); + + this.ensureDefault("custom_settings", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + + if (!this.settings.preserve_relative_urls) { + //this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + + delete this.ensureDefault; +}; + +// Private: loadFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent, container; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + + // Append the container and load the flash + tempParent = document.createElement("div"); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + //targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + container = targetElement.parentNode; + + var containerStyle = tempParent.style; + + containerStyle.position = "absolute"; + + containerStyle.top = containerStyle.left = "0"; + containerStyle.width = targetElement.parentNode.offsetWidth+"px"; + containerStyle.height = targetElement.parentNode.offsetHeight+"px"; + containerStyle.overflow = "hidden"; + + if (this.getStyle(container, 'position') === 'static') { //ڵ߰ + container.style.position = 'relative'; + } + targetElement.parentNode.replaceChild(tempParent, targetElement); //ڵ߰ + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var paramString = this.buildParamString(); + var httpSuccessString = this.settings.http_success.join(","); + + // Build the parameter string + return ["movieName=", encodeURIComponent(this.movieName), + "&uploadURL=", encodeURIComponent(this.settings.upload_url), + "&useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&httpSuccess=", encodeURIComponent(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&params=", encodeURIComponent(paramString), + "&filePostName=", encodeURIComponent(this.settings.file_post_name), + "&fileTypes=", encodeURIComponent(this.settings.file_types), + "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&buttonWidth=", encodeURIComponent(this.settings.button_width), + "&buttonHeight=", encodeURIComponent(this.settings.button_height), + "&buttonText=", encodeURIComponent(this.settings.button_text), + "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&buttonAction=", encodeURIComponent(this.settings.button_action), + "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; + +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + + return this.movieElement; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&name=value" +SWFUpload.prototype.buildParamString = function () { + var postParams = this.settings.post_params; + var paramStringPairs = []; + + if (typeof(postParams) === "object") { + for (var name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen +SWFUpload.prototype.destroy = function () { + try { + // Make sure Flash is done before we try to remove it + this.cancelUpload(null, false); + + + // Remove the SWFUpload DOM nodes + var movieElement = null; + movieElement = this.getMovieElement(); + + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround) + for (var i in movieElement) { + try { + if (typeof(movieElement[i]) === "function") { + movieElement[i] = null; + } + } catch (ex1) {} + } + + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + + + return true; + } catch (ex2) { + return false; + } +}; + + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + argumentArray = argumentArray || []; + + var movieElement = this.getMovieElement(); + var returnValue, returnString; + + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } catch (ex) { + throw "Call to " + functionName + " failed"; + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; +}; + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + var self = this; + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i; + var unescapedPost = {}; + var uk; + + if (file != undefined) { + for (var k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + var match; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + + this.cleanUp(movieElement); + + this.queueEvent("swfupload_loaded_handler"); +}; + +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function (movieElement) { + // Pro-actively unhook all the Flash functions + try { + if (this.movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (var key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + +}; + + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + if (this.settings.debug) { + var exceptionMessage, exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (var key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "700px"; + console.style.height = "350px"; + console.style.margin = "5px"; + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; + +SWFUpload.prototype.getStyle = function (obj, name) { //߰ + if (obj.currentStyle) { + return obj.currentStyle[name]; + } else if (window.getComputedStyle) { + return window.getComputedStyle(obj, null)[name]; + } +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.queue.js b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.queue.js new file mode 100644 index 0000000..5d65c30 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.queue.js @@ -0,0 +1,99 @@ +/* + Queue Plug-in + + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + + */ + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.queueSettings = {}; + + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; + } else { + continueUpload = true; + } + + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + console.debug('ydfsdfgsdfgsdfg'); + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.swf b/AvocadoEdition/plugin/editor/smarteditor2/photo_uploader/popup/swfupload/swfupload.swf new file mode 100644 index 0000000000000000000000000000000000000000..e3f767031ca8243a5f0b89bc0f154cc5962e01e9 GIT binary patch literal 12787 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 밑줄 선택 글작성하다 취소선 선택하고 밑줄 선택을 취소한 경우 툴바에 반영되지 않는 문제 + - 굵게/밑줄/기울림/취소선이 있는 상태에서 엔터치고 폰트크기 수정하면 이전 폰트크기로 줄간격이 유지되는 문제 + - 외부프로그램 테이블 복사 붙여넣기 관련 오류 수정 + - IE8이하 > 글자크기 지정 후 엔터를 치면 커서위치가 위로 올라감 + - IE9이상 > 글꼴 효과를 미리 지정 한 후에 텍스트 입력 시, 색상 변경은 적용되나 굵게 기울임 밑줄 취소선 등의 효과는 적용안됨 + - [FF]밑줄 선택> 내용입력 후 엔터>밑줄 취소 후 내용 입력>마우스로 커서 클릭 후 내용 계속 입력 시 밑줄이 있는 글로 노출됨 + - [FF] 메모장에서 작성한 내용을 붙여넣기 후 엔터 > 내용입력 > 엔터 했을 때 줄바꿈이 되지 않는 현상 + - HTML5 > 글자를 선택하여 폰트크기 지정시 굵게/밑줄/기울림/취소선이 있으면 이전에 적용한 폰트크기 기준으로 줄간격이 유지되는 문제 + +2. 기능 개선 + - IE에서 자동으로 공백이 삽입되는 문제 + - MacOS > 사파리 > 외부프로그램 테이블 붙여넣기 개선 + +3. 보안 패치 + - 사진첨부 샘플의 null byte injection 취약점 보완 + +============================================================================================== +2.3.10 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 크롬 > 브라우저 확대축소시 폰트크기가 잘못 나오는 이슈 + - IE > 표삽입>임의로 두개 칸 선택하여 셀 병합>행삽입 클릭 시 JS 오류 발생 + - IE11 > 호환성 보기를 설정하지 않을 경우 글꼴목록이 선택되지 않는 문제 수정 + +2. 기능 개선 + - 외부프로그램 테이블 복사 붙여넣기 개선 + - 입력창 조절 안내 레이어를 주석처리하면 스크립트 오류 발생 + +============================================================================================== +2.3.9 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 파이어폭스에서 에디팅시 스타일깨짐 등 오작동 + - Chrome > 찾기/바꾸기 > 모두바꾸기 버튼 클릭시 찾을단어가 지워지지 않고 남아있음 + +2. 기능 개선 + - 링크 > 자동링크 설정/해제 옵션 추가 + - [IE11] WYSIWYG 모드와 HTML 모드를 오갈 때마다 문서의 마지막에 비정상적인
    이 첨가됩니다. + - [웹접근성] 빠져나가기 단축키 기능 개선 + +============================================================================================== +2.3.8 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 테이블 내부 영역을 Shift + 클릭으로 선택 후 정렬하고 HTML 로 전환하면 더미 P 태그가 생성되는 문제 수정 + - 테이블 내부 영역 선택 혹은 에디터 내용 전체 선택 후 정렬 시 동작안함 + - [IE10, IE11] 표의 셀을 드래그했을 때 블럭 지정이 되지 않는 현상 + - HTML 모드 변환시 태그 자동 정렬에 의한 버그 + +2. 기능 개선 + - [MacOS 대응] 폰트변경이슈 + +============================================================================================== +2.3.7 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 에디터에 표 생성 후 일부 셀 선택하여 배경색 설정> 배경색 설정된 셀 선택 후 셀 삽입 시 색상이 삽입되지 않습니다. + - [IE9특정] 글 작성 중 번호매기기 또는 글머리 적용 후 정렬방식을 변경하면 엔터키 누를 시 커서가 한줄 떨어져서 노출됩니다. + - [IE10] 표 생성 후 표 드래그 시 셀의 너비/높이가 늘어나는 현상 + +2. 기능 개선 + - IE11 대응 + - 특수기호 삽입시 커서 위치가 뒤쪽으로 나오도록 개선 + - 커서에 활성화된 글꼴 확인 로직 개선 + +============================================================================================== +2.3.6 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 글 작성 후 번호매기기 적용하고 엔터키 수행하는 경우 JS 오류가 발생하는 현상 수정 + +============================================================================================== +2.3.5 +---------------------------------------------------------------------------------------------- +1. 기능 개선 + - 줄간격 설정 시 값을 직접 입력하는 경우 줄간격의 최소값 적용 + +============================================================================================== +2.3.4 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - [IE9/10] pre 태그의 바로 다음에 \n이 존재하는 경우 개행이 되지 않는 이슈 해결 + - 입력창 크기 조절바 사용 여부 오류 해결 + - 사진 퀵 업로더 모듈 오타 수정 ($newPath -> $new_path) + +2. 기능 개선 + - 글꼴 목록에 글꼴 종류 추가하기 기능 (SmartEditor2.html 참조) + - 사진 퀵 업로더 모듈에 이미지 파일 확장자 체크 추가 + +============================================================================================== +2.3.3 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - IE9 에서 템플릿을 적용한 표 생성 후 일부의 셀을 드래그하는 경우 셀의 높이가 늘어나는 현상 수정 + +2. 기능 개선 + - MAC OS의 CMD 키로 Ctrl 단축키 기능 적용 확장 + - 기본 글꼴 종류 추가 (Courier New, 나눔고딕 코딩) + +============================================================================================== +2.3.1 +---------------------------------------------------------------------------------------------- +1. 기능 개선 + - [웹접근성] 글쓰기 영역의 iframe의 title속성에 단축키 설명 제공 + - [웹접근성] 제목 input영역에서 제목 입력 후 TAB하면 스마트에디터 편집 영역으로 포커스 이동하는 기능 추가 + - [웹접근성] 툴바 영역의 이전/다음 아이템 이동을 TAB, SHIFT+TAB으로 이동할 수 있도록 추가 + +============================================================================================== +2.3.0 +---------------------------------------------------------------------------------------------- +1. 기능 개선 + - [웹접근성] 키보드로만 메뉴를 이동할 수 있도록 단축키 적용 + - [웹접근성] 웹접근성 도움말 제공 + - 편집모드와 사이즈 조절바 사용 옵션 추가 + - 사진 첨부 팝업 데모 파일 구조 개선 + +============================================================================================== +2.2.1 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - 사진 퀵 업로더 추가 시, 가이드 대로 수행했을 때 사진 첨부가 2번 실행되는 문제 해결 + : loader-min.js 파일 내에 사진 퀵 업로더 소스가 포함되어 있던 부분 제거하여 소스 분리 + +2. 기능 개선 + - 툴바의 기능 제거/순서 변경이 쉽도록 마크업 구조 개선 + ※ 툴바의 기능 제거/순서 변경은 가이드 문서를 참고하세요. + + +3. 폴더/파일 변경 + - /js_src 폴더 제거 + - /js/smarteditor2.js 추가 + : /js_src 폴더를 /js/smarteditor2.js 로 대체했습니다. + : /js_src 폴더 구조에서 사용자가 소스를 검색하여 수정하기 어렵던 부분을 보완하기 위하여 + : /js_src 폴더 내의 플러그인 소스를 통합한 /js/smarteditor2.js 를 추가했습니다. + - /js/loader-min.js 제거 + - /js/smarteditor2.min.js 추가 + : /js/loader-min.js 파일을 /js/smarteditor2.min.js로 대체했습니다. + - /quick_photo_uploader 폴더 추가 + - /popup 폴더 이동 + : /popup 폴더 - 사진 퀵 업로더의 팝업과 관련된 소스 + : /plugin 폴더 - 사진 퀵 업로더의 사진첨부를 처리하는 플러그인 js 소스 + - /img/ko_KR 폴더 추가 + : 이후의 다국어 버전 지원을 위하여 이미지 폴더 내 디렉토리가 추가되었습니다. + : 언어 별 구분이 필요없는 이미지는 /img 바로 하위에 두었고, + : 언어 별로 구분되어야 하는 이미지는 /img/ko_KR 과 같이 언어 별 디렉토리로 구분했습니다. + : 버전 업그레이드를 하는 경우 이미지 경로가 변경된 점에 주의하시기 바랍니다. + - /js/SE2B_Configuration.js 제거 + - /js/SE2B_Configuration_Service.js 추가 + - /js/SE2B_Configuration_General.js 추가 + : /js/SE2B_Configuration_Service.js 와 /js/SE2B_Configuration_General.js로 파일 분리했습니다. + : /js/SE2B_Configuration_Service.js 는 적용을 할 때 사용자가 변경할 가능성이 높은 플러그인 설정을 갖고, + : /js/SE2B_Configuration_General.js 는 서비스에 적용할 때 변경할 가능성이 거의 없는 설정입니다. + +============================================================================================== +2.1.3 +---------------------------------------------------------------------------------------------- +1. 버그 수정 + - [Chrome] 보기 페이지에 글자색이 설정되어 있는 경우 글 작성 시 내용에 적용한 글자색으로 노출되지 않는 문제 해결 + - 엔터 처리가
    로 설정된 경우에도 텍스트 모드에서 모드변경 혹은 글 저장할 때 개행이

    로 표시되는 문제 해결 + - [IE9] 각주 삽입 시, 하단으로 떨어지는 이슈 해결 + - [Chrome] 인용구 밖에 글머리기호/번호매기기가 있을 때 인용구 안에서 글머리기호/번호매기기 시 내용이 인용구 밖으로 나가는 문제 해결 + - [IE] IE에서 특정 블로그 글을 복사하여 붙여넣기 했을 때 개행이 제거되는 문제 해결 + - 사진을 드래그해서 사이즈를 변경한 후 저장 혹은 HTML모드로 변경하면, 사진 사이즈가 원복되는 현상 해결 + - [Chrome/FF/Safari] 스크롤바가 생성되도록 문자입력 후 엔터 클릭하지 않은 상태에서 이미지 하나 삽입 시 이미지에 포커싱이 놓이지 않는 문제 해결 + - [IE9 표준] 사진을 스크롤로 일부 가린 상태에서 재편집하여 적용했을 때 계속 가려진 상태인 문제 해결 + - FF에서 사진을 여러장 첨부 시 스크롤이 가장 마지막 추가한 사진으로 내려가지 않음 해결 + - 호환 모드를 제거하고 사진 첨부 시 에디팅 영역의 커서 주위에 태그가 붙어서 글자가 매우 작게 되는 현상 해결 + - [IE9] 에디터에 각주 연속으로 입력 시 커서가 각주사이로 이동되는 현상 해결 + - 글꼴색/글꼴배경색 더보기에서 글꼴색 선택>다시 다른 색상 선택 후 처음 선택되었던 색상 선택 시 처음 선택색상이 원래 자리에서 삭제되지 않는 현상 해결 + - 제공하지 않는 기능인 이모티콘 플러그인 소스 제거 + - 플러그인 태그 코드 추가 시

  • 태그와 diff --git a/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea.html b/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea.html new file mode 100644 index 0000000..a3af8f6 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea.html @@ -0,0 +1,8 @@ + + + + +Smart Editor™ WYSIWYG Mode + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea_ie8.html b/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea_ie8.html new file mode 100644 index 0000000..c9771d1 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/smart_editor2_inputarea_ie8.html @@ -0,0 +1,9 @@ + + + + + +Smart Editor™ WYSIWYG Mode + + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/editor/smarteditor2/src_include.txt b/AvocadoEdition/plugin/editor/smarteditor2/src_include.txt new file mode 100644 index 0000000..7ffb352 --- /dev/null +++ b/AvocadoEdition/plugin/editor/smarteditor2/src_include.txt @@ -0,0 +1,7 @@ +자바스크립트 소스를 직접 수정하고자 할 경우는 SmartEditor2Skin.html 소스를 아래의 과정으로 수정한 후 자바스크립트 소스를 수정합니다. + +1) SmartEditor2Skin.html 소스에서 아래의 부분을 삭제합니다. + + +2) 다음의 라인을 복사하여 붙여넣습니다. + \ No newline at end of file diff --git a/AvocadoEdition/plugin/htmlpurifier/HTMLPurifier.standalone.php b/AvocadoEdition/plugin/htmlpurifier/HTMLPurifier.standalone.php new file mode 100644 index 0000000..467218a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/HTMLPurifier.standalone.php @@ -0,0 +1,22099 @@ +config = HTMLPurifier_Config::create($config); + $this->strategy = new HTMLPurifier_Strategy_Core(); + } + + /** + * Adds a filter to process the output. First come first serve + * + * @param HTMLPurifier_Filter $filter HTMLPurifier_Filter object + */ + public function addFilter($filter) + { + trigger_error( + 'HTMLPurifier->addFilter() is deprecated, use configuration directives' . + ' in the Filter namespace or Filter.Custom', + E_USER_WARNING + ); + $this->filters[] = $filter; + } + + /** + * Filters an HTML snippet/document to be XSS-free and standards-compliant. + * + * @param string $html String of HTML to purify + * @param HTMLPurifier_Config $config Config object for this operation, + * if omitted, defaults to the config object specified during this + * object's construction. The parameter can also be any type + * that HTMLPurifier_Config::create() supports. + * + * @return string Purified HTML + */ + public function purify($html, $config = null) + { + // :TODO: make the config merge in, instead of replace + $config = $config ? HTMLPurifier_Config::create($config) : $this->config; + + // implementation is partially environment dependant, partially + // configuration dependant + $lexer = HTMLPurifier_Lexer::create($config); + + $context = new HTMLPurifier_Context(); + + // setup HTML generator + $this->generator = new HTMLPurifier_Generator($config, $context); + $context->register('Generator', $this->generator); + + // set up global context variables + if ($config->get('Core.CollectErrors')) { + // may get moved out if other facilities use it + $language_factory = HTMLPurifier_LanguageFactory::instance(); + $language = $language_factory->create($config, $context); + $context->register('Locale', $language); + + $error_collector = new HTMLPurifier_ErrorCollector($context); + $context->register('ErrorCollector', $error_collector); + } + + // setup id_accumulator context, necessary due to the fact that + // AttrValidator can be called from many places + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + + $html = HTMLPurifier_Encoder::convertToUTF8($html, $config, $context); + + // setup filters + $filter_flags = $config->getBatch('Filter'); + $custom_filters = $filter_flags['Custom']; + unset($filter_flags['Custom']); + $filters = array(); + foreach ($filter_flags as $filter => $flag) { + if (!$flag) { + continue; + } + if (strpos($filter, '.') !== false) { + continue; + } + $class = "HTMLPurifier_Filter_$filter"; + $filters[] = new $class; + } + foreach ($custom_filters as $filter) { + // maybe "HTMLPurifier_Filter_$filter", but be consistent with AutoFormat + $filters[] = $filter; + } + $filters = array_merge($filters, $this->filters); + // maybe prepare(), but later + + for ($i = 0, $filter_size = count($filters); $i < $filter_size; $i++) { + $html = $filters[$i]->preFilter($html, $config, $context); + } + + // purified HTML + $html = + $this->generator->generateFromTokens( + // list of tokens + $this->strategy->execute( + // list of un-purified tokens + $lexer->tokenizeHTML( + // un-purified HTML + $html, + $config, + $context + ), + $config, + $context + ) + ); + + for ($i = $filter_size - 1; $i >= 0; $i--) { + $html = $filters[$i]->postFilter($html, $config, $context); + } + + $html = HTMLPurifier_Encoder::convertFromUTF8($html, $config, $context); + $this->context =& $context; + return $html; + } + + /** + * Filters an array of HTML snippets + * + * @param string[] $array_of_html Array of html snippets + * @param HTMLPurifier_Config $config Optional config object for this operation. + * See HTMLPurifier::purify() for more details. + * + * @return string[] Array of purified HTML + */ + public function purifyArray($array_of_html, $config = null) + { + $context_array = array(); + foreach ($array_of_html as $key => $html) { + $array_of_html[$key] = $this->purify($html, $config); + $context_array[$key] = $this->context; + } + $this->context = $context_array; + return $array_of_html; + } + + /** + * Singleton for enforcing just one HTML Purifier in your system + * + * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype + * HTMLPurifier instance to overload singleton with, + * or HTMLPurifier_Config instance to configure the + * generated version with. + * + * @return HTMLPurifier + */ + public static function instance($prototype = null) + { + if (!self::$instance || $prototype) { + if ($prototype instanceof HTMLPurifier) { + self::$instance = $prototype; + } elseif ($prototype) { + self::$instance = new HTMLPurifier($prototype); + } else { + self::$instance = new HTMLPurifier(); + } + } + return self::$instance; + } + + /** + * Singleton for enforcing just one HTML Purifier in your system + * + * @param HTMLPurifier|HTMLPurifier_Config $prototype Optional prototype + * HTMLPurifier instance to overload singleton with, + * or HTMLPurifier_Config instance to configure the + * generated version with. + * + * @return HTMLPurifier + * @note Backwards compatibility, see instance() + */ + public static function getInstance($prototype = null) + { + return HTMLPurifier::instance($prototype); + } +} + + + + + +/** + * Converts a stream of HTMLPurifier_Token into an HTMLPurifier_Node, + * and back again. + * + * @note This transformation is not an equivalence. We mutate the input + * token stream to make it so; see all [MUT] markers in code. + */ +class HTMLPurifier_Arborize +{ + public static function arborize($tokens, $config, $context) { + $definition = $config->getHTMLDefinition(); + $parent = new HTMLPurifier_Token_Start($definition->info_parent); + $stack = array($parent->toNode()); + foreach ($tokens as $token) { + $token->skip = null; // [MUT] + $token->carryover = null; // [MUT] + if ($token instanceof HTMLPurifier_Token_End) { + $token->start = null; // [MUT] + $r = array_pop($stack); + assert($r->name === $token->name); + assert(empty($token->attr)); + $r->endCol = $token->col; + $r->endLine = $token->line; + $r->endArmor = $token->armor; + continue; + } + $node = $token->toNode(); + $stack[count($stack)-1]->children[] = $node; + if ($token instanceof HTMLPurifier_Token_Start) { + $stack[] = $node; + } + } + assert(count($stack) == 1); + return $stack[0]; + } + + public static function flatten($node, $config, $context) { + $level = 0; + $nodes = array($level => new HTMLPurifier_Queue(array($node))); + $closingTokens = array(); + $tokens = array(); + do { + while (!$nodes[$level]->isEmpty()) { + $node = $nodes[$level]->shift(); // FIFO + list($start, $end) = $node->toTokenPair(); + if ($level > 0) { + $tokens[] = $start; + } + if ($end !== NULL) { + $closingTokens[$level][] = $end; + } + if ($node instanceof HTMLPurifier_Node_Element) { + $level++; + $nodes[$level] = new HTMLPurifier_Queue(); + foreach ($node->children as $childNode) { + $nodes[$level]->push($childNode); + } + } + } + $level--; + if ($level && isset($closingTokens[$level])) { + while ($token = array_pop($closingTokens[$level])) { + $tokens[] = $token; + } + } + } while ($level > 0); + return $tokens; + } +} + + + +/** + * Defines common attribute collections that modules reference + */ + +class HTMLPurifier_AttrCollections +{ + + /** + * Associative array of attribute collections, indexed by name. + * @type array + */ + public $info = array(); + + /** + * Performs all expansions on internal data for use by other inclusions + * It also collects all attribute collection extensions from + * modules + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + * @param HTMLPurifier_HTMLModule[] $modules Hash array of HTMLPurifier_HTMLModule members + */ + public function __construct($attr_types, $modules) + { + $this->doConstruct($attr_types, $modules); + } + + public function doConstruct($attr_types, $modules) + { + // load extensions from the modules + foreach ($modules as $module) { + foreach ($module->attr_collections as $coll_i => $coll) { + if (!isset($this->info[$coll_i])) { + $this->info[$coll_i] = array(); + } + foreach ($coll as $attr_i => $attr) { + if ($attr_i === 0 && isset($this->info[$coll_i][$attr_i])) { + // merge in includes + $this->info[$coll_i][$attr_i] = array_merge( + $this->info[$coll_i][$attr_i], + $attr + ); + continue; + } + $this->info[$coll_i][$attr_i] = $attr; + } + } + } + // perform internal expansions and inclusions + foreach ($this->info as $name => $attr) { + // merge attribute collections that include others + $this->performInclusions($this->info[$name]); + // replace string identifiers with actual attribute objects + $this->expandIdentifiers($this->info[$name], $attr_types); + } + } + + /** + * Takes a reference to an attribute associative array and performs + * all inclusions specified by the zero index. + * @param array &$attr Reference to attribute array + */ + public function performInclusions(&$attr) + { + if (!isset($attr[0])) { + return; + } + $merge = $attr[0]; + $seen = array(); // recursion guard + // loop through all the inclusions + for ($i = 0; isset($merge[$i]); $i++) { + if (isset($seen[$merge[$i]])) { + continue; + } + $seen[$merge[$i]] = true; + // foreach attribute of the inclusion, copy it over + if (!isset($this->info[$merge[$i]])) { + continue; + } + foreach ($this->info[$merge[$i]] as $key => $value) { + if (isset($attr[$key])) { + continue; + } // also catches more inclusions + $attr[$key] = $value; + } + if (isset($this->info[$merge[$i]][0])) { + // recursion + $merge = array_merge($merge, $this->info[$merge[$i]][0]); + } + } + unset($attr[0]); + } + + /** + * Expands all string identifiers in an attribute array by replacing + * them with the appropriate values inside HTMLPurifier_AttrTypes + * @param array &$attr Reference to attribute array + * @param HTMLPurifier_AttrTypes $attr_types HTMLPurifier_AttrTypes instance + */ + public function expandIdentifiers(&$attr, $attr_types) + { + // because foreach will process new elements we add, make sure we + // skip duplicates + $processed = array(); + + foreach ($attr as $def_i => $def) { + // skip inclusions + if ($def_i === 0) { + continue; + } + + if (isset($processed[$def_i])) { + continue; + } + + // determine whether or not attribute is required + if ($required = (strpos($def_i, '*') !== false)) { + // rename the definition + unset($attr[$def_i]); + $def_i = trim($def_i, '*'); + $attr[$def_i] = $def; + } + + $processed[$def_i] = true; + + // if we've already got a literal object, move on + if (is_object($def)) { + // preserve previous required + $attr[$def_i]->required = ($required || $attr[$def_i]->required); + continue; + } + + if ($def === false) { + unset($attr[$def_i]); + continue; + } + + if ($t = $attr_types->get($def)) { + $attr[$def_i] = $t; + $attr[$def_i]->required = $required; + } else { + unset($attr[$def_i]); + } + } + } +} + + + + + +/** + * Base class for all validating attribute definitions. + * + * This family of classes forms the core for not only HTML attribute validation, + * but also any sort of string that needs to be validated or cleaned (which + * means CSS properties and composite definitions are defined here too). + * Besides defining (through code) what precisely makes the string valid, + * subclasses are also responsible for cleaning the code if possible. + */ + +abstract class HTMLPurifier_AttrDef +{ + + /** + * Tells us whether or not an HTML attribute is minimized. + * Has no meaning in other contexts. + * @type bool + */ + public $minimized = false; + + /** + * Tells us whether or not an HTML attribute is required. + * Has no meaning in other contexts + * @type bool + */ + public $required = false; + + /** + * Validates and cleans passed string according to a definition. + * + * @param string $string String to be validated and cleaned. + * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. + * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object. + */ + abstract public function validate($string, $config, $context); + + /** + * Convenience method that parses a string as if it were CDATA. + * + * This method process a string in the manner specified at + * by removing + * leading and trailing whitespace, ignoring line feeds, and replacing + * carriage returns and tabs with spaces. While most useful for HTML + * attributes specified as CDATA, it can also be applied to most CSS + * values. + * + * @note This method is not entirely standards compliant, as trim() removes + * more types of whitespace than specified in the spec. In practice, + * this is rarely a problem, as those extra characters usually have + * already been removed by HTMLPurifier_Encoder. + * + * @warning This processing is inconsistent with XML's whitespace handling + * as specified by section 3.3.3 and referenced XHTML 1.0 section + * 4.7. However, note that we are NOT necessarily + * parsing XML, thus, this behavior may still be correct. We + * assume that newlines have been normalized. + */ + public function parseCDATA($string) + { + $string = trim($string); + $string = str_replace(array("\n", "\t", "\r"), ' ', $string); + return $string; + } + + /** + * Factory method for creating this class from a string. + * @param string $string String construction info + * @return HTMLPurifier_AttrDef Created AttrDef object corresponding to $string + */ + public function make($string) + { + // default implementation, return a flyweight of this object. + // If $string has an effect on the returned object (i.e. you + // need to overload this method), it is best + // to clone or instantiate new copies. (Instantiation is safer.) + return $this; + } + + /** + * Removes spaces from rgb(0, 0, 0) so that shorthand CSS properties work + * properly. THIS IS A HACK! + * @param string $string a CSS colour definition + * @return string + */ + protected function mungeRgb($string) + { + return preg_replace('/rgb\((\d+)\s*,\s*(\d+)\s*,\s*(\d+)\)/', 'rgb(\1,\2,\3)', $string); + } + + /** + * Parses a possibly escaped CSS string and returns the "pure" + * version of it. + */ + protected function expandCSSEscape($string) + { + // flexibly parse it + $ret = ''; + for ($i = 0, $c = strlen($string); $i < $c; $i++) { + if ($string[$i] === '\\') { + $i++; + if ($i >= $c) { + $ret .= '\\'; + break; + } + if (ctype_xdigit($string[$i])) { + $code = $string[$i]; + for ($a = 1, $i++; $i < $c && $a < 6; $i++, $a++) { + if (!ctype_xdigit($string[$i])) { + break; + } + $code .= $string[$i]; + } + // We have to be extremely careful when adding + // new characters, to make sure we're not breaking + // the encoding. + $char = HTMLPurifier_Encoder::unichr(hexdec($code)); + if (HTMLPurifier_Encoder::cleanUTF8($char) === '') { + continue; + } + $ret .= $char; + if ($i < $c && trim($string[$i]) !== '') { + $i--; + } + continue; + } + if ($string[$i] === "\n") { + continue; + } + } + $ret .= $string[$i]; + } + return $ret; + } +} + + + + + +/** + * Processes an entire attribute array for corrections needing multiple values. + * + * Occasionally, a certain attribute will need to be removed and popped onto + * another value. Instead of creating a complex return syntax for + * HTMLPurifier_AttrDef, we just pass the whole attribute array to a + * specialized object and have that do the special work. That is the + * family of HTMLPurifier_AttrTransform. + * + * An attribute transformation can be assigned to run before or after + * HTMLPurifier_AttrDef validation. See HTMLPurifier_HTMLDefinition for + * more details. + */ + +abstract class HTMLPurifier_AttrTransform +{ + + /** + * Abstract: makes changes to the attributes dependent on multiple values. + * + * @param array $attr Assoc array of attributes, usually from + * HTMLPurifier_Token_Tag::$attr + * @param HTMLPurifier_Config $config Mandatory HTMLPurifier_Config object. + * @param HTMLPurifier_Context $context Mandatory HTMLPurifier_Context object + * @return array Processed attribute array. + */ + abstract public function transform($attr, $config, $context); + + /** + * Prepends CSS properties to the style attribute, creating the + * attribute if it doesn't exist. + * @param array &$attr Attribute array to process (passed by reference) + * @param string $css CSS to prepend + */ + public function prependCSS(&$attr, $css) + { + $attr['style'] = isset($attr['style']) ? $attr['style'] : ''; + $attr['style'] = $css . $attr['style']; + } + + /** + * Retrieves and removes an attribute + * @param array &$attr Attribute array to process (passed by reference) + * @param mixed $key Key of attribute to confiscate + * @return mixed + */ + public function confiscateAttr(&$attr, $key) + { + if (!isset($attr[$key])) { + return null; + } + $value = $attr[$key]; + unset($attr[$key]); + return $value; + } +} + + + + + +/** + * Provides lookup array of attribute types to HTMLPurifier_AttrDef objects + */ +class HTMLPurifier_AttrTypes +{ + /** + * Lookup array of attribute string identifiers to concrete implementations. + * @type HTMLPurifier_AttrDef[] + */ + protected $info = array(); + + /** + * Constructs the info array, supplying default implementations for attribute + * types. + */ + public function __construct() + { + // XXX This is kind of poor, since we don't actually /clone/ + // instances; instead, we use the supplied make() attribute. So, + // the underlying class must know how to deal with arguments. + // With the old implementation of Enum, that ignored its + // arguments when handling a make dispatch, the IAlign + // definition wouldn't work. + + // pseudo-types, must be instantiated via shorthand + $this->info['Enum'] = new HTMLPurifier_AttrDef_Enum(); + $this->info['Bool'] = new HTMLPurifier_AttrDef_HTML_Bool(); + + $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ID'] = new HTMLPurifier_AttrDef_HTML_ID(); + $this->info['Length'] = new HTMLPurifier_AttrDef_HTML_Length(); + $this->info['MultiLength'] = new HTMLPurifier_AttrDef_HTML_MultiLength(); + $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_HTML_Nmtokens(); + $this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels(); + $this->info['Text'] = new HTMLPurifier_AttrDef_Text(); + $this->info['URI'] = new HTMLPurifier_AttrDef_URI(); + $this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang(); + $this->info['Color'] = new HTMLPurifier_AttrDef_HTML_Color(); + $this->info['IAlign'] = self::makeEnum('top,middle,bottom,left,right'); + $this->info['LAlign'] = self::makeEnum('top,bottom,left,right'); + $this->info['FrameTarget'] = new HTMLPurifier_AttrDef_HTML_FrameTarget(); + + // unimplemented aliases + $this->info['ContentType'] = new HTMLPurifier_AttrDef_Text(); + $this->info['ContentTypes'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Charsets'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Character'] = new HTMLPurifier_AttrDef_Text(); + + // "proprietary" types + $this->info['Class'] = new HTMLPurifier_AttrDef_HTML_Class(); + + // number is really a positive integer (one or more digits) + // FIXME: ^^ not always, see start and value of list items + $this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true); + } + + private static function makeEnum($in) + { + return new HTMLPurifier_AttrDef_Clone(new HTMLPurifier_AttrDef_Enum(explode(',', $in))); + } + + /** + * Retrieves a type + * @param string $type String type name + * @return HTMLPurifier_AttrDef Object AttrDef for type + */ + public function get($type) + { + // determine if there is any extra info tacked on + if (strpos($type, '#') !== false) { + list($type, $string) = explode('#', $type, 2); + } else { + $string = ''; + } + + if (!isset($this->info[$type])) { + trigger_error('Cannot retrieve undefined attribute type ' . $type, E_USER_ERROR); + return; + } + return $this->info[$type]->make($string); + } + + /** + * Sets a new implementation for a type + * @param string $type String type name + * @param HTMLPurifier_AttrDef $impl Object AttrDef for type + */ + public function set($type, $impl) + { + $this->info[$type] = $impl; + } +} + + + + + +/** + * Validates the attributes of a token. Doesn't manage required attributes + * very well. The only reason we factored this out was because RemoveForeignElements + * also needed it besides ValidateAttributes. + */ +class HTMLPurifier_AttrValidator +{ + + /** + * Validates the attributes of a token, mutating it as necessary. + * that has valid tokens + * @param HTMLPurifier_Token $token Token to validate. + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config + * @param HTMLPurifier_Context $context Instance of HTMLPurifier_Context + */ + public function validateToken($token, $config, $context) + { + $definition = $config->getHTMLDefinition(); + $e =& $context->get('ErrorCollector', true); + + // initialize IDAccumulator if necessary + $ok =& $context->get('IDAccumulator', true); + if (!$ok) { + $id_accumulator = HTMLPurifier_IDAccumulator::build($config, $context); + $context->register('IDAccumulator', $id_accumulator); + } + + // initialize CurrentToken if necessary + $current_token =& $context->get('CurrentToken', true); + if (!$current_token) { + $context->register('CurrentToken', $token); + } + + if (!$token instanceof HTMLPurifier_Token_Start && + !$token instanceof HTMLPurifier_Token_Empty + ) { + return; + } + + // create alias to global definition array, see also $defs + // DEFINITION CALL + $d_defs = $definition->info_global_attr; + + // don't update token until the very end, to ensure an atomic update + $attr = $token->attr; + + // do global transformations (pre) + // nothing currently utilizes this + foreach ($definition->info_attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // do local transformations only applicable to this element (pre) + // ex.

    to

    + foreach ($definition->info[$token->name]->attr_transform_pre as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // create alias to this element's attribute definition array, see + // also $d_defs (global attribute definition array) + // DEFINITION CALL + $defs = $definition->info[$token->name]->attr; + + $attr_key = false; + $context->register('CurrentAttr', $attr_key); + + // iterate through all the attribute keypairs + // Watch out for name collisions: $key has previously been used + foreach ($attr as $attr_key => $value) { + + // call the definition + if (isset($defs[$attr_key])) { + // there is a local definition defined + if ($defs[$attr_key] === false) { + // We've explicitly been told not to allow this element. + // This is usually when there's a global definition + // that must be overridden. + // Theoretically speaking, we could have a + // AttrDef_DenyAll, but this is faster! + $result = false; + } else { + // validate according to the element's definition + $result = $defs[$attr_key]->validate( + $value, + $config, + $context + ); + } + } elseif (isset($d_defs[$attr_key])) { + // there is a global definition defined, validate according + // to the global definition + $result = $d_defs[$attr_key]->validate( + $value, + $config, + $context + ); + } else { + // system never heard of the attribute? DELETE! + $result = false; + } + + // put the results into effect + if ($result === false || $result === null) { + // this is a generic error message that should replaced + // with more specific ones when possible + if ($e) { + $e->send(E_ERROR, 'AttrValidator: Attribute removed'); + } + + // remove the attribute + unset($attr[$attr_key]); + } elseif (is_string($result)) { + // generally, if a substitution is happening, there + // was some sort of implicit correction going on. We'll + // delegate it to the attribute classes to say exactly what. + + // simple substitution + $attr[$attr_key] = $result; + } else { + // nothing happens + } + + // we'd also want slightly more complicated substitution + // involving an array as the return value, + // although we're not sure how colliding attributes would + // resolve (certain ones would be completely overriden, + // others would prepend themselves). + } + + $context->destroy('CurrentAttr'); + + // post transforms + + // global (error reporting untested) + foreach ($definition->info_attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + // local (error reporting untested) + foreach ($definition->info[$token->name]->attr_transform_post as $transform) { + $attr = $transform->transform($o = $attr, $config, $context); + if ($e) { + if ($attr != $o) { + $e->send(E_NOTICE, 'AttrValidator: Attributes transformed', $o, $attr); + } + } + } + + $token->attr = $attr; + + // destroy CurrentToken if we made it ourselves + if (!$current_token) { + $context->destroy('CurrentToken'); + } + + } + + +} + + + + + +// constants are slow, so we use as few as possible +if (!defined('HTMLPURIFIER_PREFIX')) { + define('HTMLPURIFIER_PREFIX', dirname(__FILE__) . '/standalone'); + set_include_path(HTMLPURIFIER_PREFIX . PATH_SEPARATOR . get_include_path()); +} + +// accomodations for versions earlier than 5.0.2 +// borrowed from PHP_Compat, LGPL licensed, by Aidan Lister +if (!defined('PHP_EOL')) { + switch (strtoupper(substr(PHP_OS, 0, 3))) { + case 'WIN': + define('PHP_EOL', "\r\n"); + break; + case 'DAR': + define('PHP_EOL', "\r"); + break; + default: + define('PHP_EOL', "\n"); + } +} + +/** + * Bootstrap class that contains meta-functionality for HTML Purifier such as + * the autoload function. + * + * @note + * This class may be used without any other files from HTML Purifier. + */ +class HTMLPurifier_Bootstrap +{ + + /** + * Autoload function for HTML Purifier + * @param string $class Class to load + * @return bool + */ + public static function autoload($class) + { + $file = HTMLPurifier_Bootstrap::getPath($class); + if (!$file) { + return false; + } + // Technically speaking, it should be ok and more efficient to + // just do 'require', but Antonio Parraga reports that with + // Zend extensions such as Zend debugger and APC, this invariant + // may be broken. Since we have efficient alternatives, pay + // the cost here and avoid the bug. + require_once HTMLPURIFIER_PREFIX . '/' . $file; + return true; + } + + /** + * Returns the path for a specific class. + * @param string $class Class path to get + * @return string + */ + public static function getPath($class) + { + if (strncmp('HTMLPurifier', $class, 12) !== 0) { + return false; + } + // Custom implementations + if (strncmp('HTMLPurifier_Language_', $class, 22) === 0) { + $code = str_replace('_', '-', substr($class, 22)); + $file = 'HTMLPurifier/Language/classes/' . $code . '.php'; + } else { + $file = str_replace('_', '/', $class) . '.php'; + } + if (!file_exists(HTMLPURIFIER_PREFIX . '/' . $file)) { + return false; + } + return $file; + } + + /** + * "Pre-registers" our autoloader on the SPL stack. + */ + public static function registerAutoload() + { + $autoload = array('HTMLPurifier_Bootstrap', 'autoload'); + if (($funcs = spl_autoload_functions()) === false) { + spl_autoload_register($autoload); + } elseif (function_exists('spl_autoload_unregister')) { + if (version_compare(PHP_VERSION, '5.3.0', '>=')) { + // prepend flag exists, no need for shenanigans + spl_autoload_register($autoload, true, true); + } else { + $buggy = version_compare(PHP_VERSION, '5.2.11', '<'); + $compat = version_compare(PHP_VERSION, '5.1.2', '<=') && + version_compare(PHP_VERSION, '5.1.0', '>='); + foreach ($funcs as $func) { + if ($buggy && is_array($func)) { + // :TRICKY: There are some compatibility issues and some + // places where we need to error out + $reflector = new ReflectionMethod($func[0], $func[1]); + if (!$reflector->isStatic()) { + throw new Exception( + 'HTML Purifier autoloader registrar is not compatible + with non-static object methods due to PHP Bug #44144; + Please do not use HTMLPurifier.autoload.php (or any + file that includes this file); instead, place the code: + spl_autoload_register(array(\'HTMLPurifier_Bootstrap\', \'autoload\')) + after your own autoloaders.' + ); + } + // Suprisingly, spl_autoload_register supports the + // Class::staticMethod callback format, although call_user_func doesn't + if ($compat) { + $func = implode('::', $func); + } + } + spl_autoload_unregister($func); + } + spl_autoload_register($autoload); + foreach ($funcs as $func) { + spl_autoload_register($func); + } + } + } + } +} + + + + + +/** + * Super-class for definition datatype objects, implements serialization + * functions for the class. + */ +abstract class HTMLPurifier_Definition +{ + + /** + * Has setup() been called yet? + * @type bool + */ + public $setup = false; + + /** + * If true, write out the final definition object to the cache after + * setup. This will be true only if all invocations to get a raw + * definition object are also optimized. This does not cause file + * system thrashing because on subsequent calls the cached object + * is used and any writes to the raw definition object are short + * circuited. See enduser-customize.html for the high-level + * picture. + * @type bool + */ + public $optimized = null; + + /** + * What type of definition is it? + * @type string + */ + public $type; + + /** + * Sets up the definition object into the final form, something + * not done by the constructor + * @param HTMLPurifier_Config $config + */ + abstract protected function doSetup($config); + + /** + * Setup function that aborts if already setup + * @param HTMLPurifier_Config $config + */ + public function setup($config) + { + if ($this->setup) { + return; + } + $this->setup = true; + $this->doSetup($config); + } +} + + + + + +/** + * Defines allowed CSS attributes and what their values are. + * @see HTMLPurifier_HTMLDefinition + */ +class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition +{ + + public $type = 'CSS'; + + /** + * Assoc array of attribute name to definition object. + * @type HTMLPurifier_AttrDef[] + */ + public $info = array(); + + /** + * Constructs the info array. The meat of this class. + * @param HTMLPurifier_Config $config + */ + protected function doSetup($config) + { + $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum( + array('left', 'right', 'center', 'justify'), + false + ); + + $border_style = + $this->info['border-bottom-style'] = + $this->info['border-right-style'] = + $this->info['border-left-style'] = + $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum( + array( + 'none', + 'hidden', + 'dotted', + 'dashed', + 'solid', + 'double', + 'groove', + 'ridge', + 'inset', + 'outset' + ), + false + ); + + $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style); + + $this->info['clear'] = new HTMLPurifier_AttrDef_Enum( + array('none', 'left', 'right', 'both'), + false + ); + $this->info['float'] = new HTMLPurifier_AttrDef_Enum( + array('none', 'left', 'right'), + false + ); + $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum( + array('normal', 'italic', 'oblique'), + false + ); + $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum( + array('normal', 'small-caps'), + false + ); + + $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('none')), + new HTMLPurifier_AttrDef_CSS_URI() + ) + ); + + $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum( + array('inside', 'outside'), + false + ); + $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum( + array( + 'disc', + 'circle', + 'square', + 'decimal', + 'lower-roman', + 'upper-roman', + 'lower-alpha', + 'upper-alpha', + 'none' + ), + false + ); + $this->info['list-style-image'] = $uri_or_none; + + $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config); + + $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum( + array('capitalize', 'uppercase', 'lowercase', 'none'), + false + ); + $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + $this->info['background-image'] = $uri_or_none; + $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum( + array('repeat', 'repeat-x', 'repeat-y', 'no-repeat') + ); + $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum( + array('scroll', 'fixed') + ); + $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition(); + + $border_color = + $this->info['border-top-color'] = + $this->info['border-bottom-color'] = + $this->info['border-left-color'] = + $this->info['border-right-color'] = + $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('transparent')), + new HTMLPurifier_AttrDef_CSS_Color() + ) + ); + + $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config); + + $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color); + + $border_width = + $this->info['border-top-width'] = + $this->info['border-bottom-width'] = + $this->info['border-left-width'] = + $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')), + new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative + ) + ); + + $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width); + + $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum( + array( + 'xx-small', + 'x-small', + 'small', + 'medium', + 'large', + 'x-large', + 'xx-large', + 'larger', + 'smaller' + ) + ), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_CSS_Length() + ) + ); + + $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum(array('normal')), + new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ) + ); + + $margin = + $this->info['margin-top'] = + $this->info['margin-bottom'] = + $this->info['margin-left'] = + $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ); + + $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin); + + // non-negative + $padding = + $this->info['padding-top'] = + $this->info['padding-bottom'] = + $this->info['padding-left'] = + $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true) + ) + ); + + $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding); + + $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ) + ); + + $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0'), + new HTMLPurifier_AttrDef_CSS_Percentage(true), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ); + $max = $config->get('CSS.MaxImgLength'); + + $this->info['width'] = + $this->info['height'] = + $max === null ? + $trusted_wh : + new HTMLPurifier_AttrDef_Switch( + 'img', + // For img tags: + new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length('0', $max), + new HTMLPurifier_AttrDef_Enum(array('auto')) + ) + ), + // For everyone else: + $trusted_wh + ); + + $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration(); + + $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily(); + + // this could use specialized code + $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum( + array( + 'normal', + 'bold', + 'bolder', + 'lighter', + '100', + '200', + '300', + '400', + '500', + '600', + '700', + '800', + '900' + ), + false + ); + + // MUST be called after other font properties, as it references + // a CSSDefinition object + $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config); + + // same here + $this->info['border'] = + $this->info['border-bottom'] = + $this->info['border-top'] = + $this->info['border-left'] = + $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config); + + $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum( + array('collapse', 'separate') + ); + + $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum( + array('top', 'bottom') + ); + + $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum( + array('auto', 'fixed') + ); + + $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Enum( + array( + 'baseline', + 'sub', + 'super', + 'top', + 'text-top', + 'middle', + 'bottom', + 'text-bottom' + ) + ), + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage() + ) + ); + + $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2); + + // These CSS properties don't work on many browsers, but we live + // in THE FUTURE! + $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum( + array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line') + ); + + if ($config->get('CSS.Proprietary')) { + $this->doSetupProprietary($config); + } + + if ($config->get('CSS.AllowTricky')) { + $this->doSetupTricky($config); + } + + if ($config->get('CSS.Trusted')) { + $this->doSetupTrusted($config); + } + + $allow_important = $config->get('CSS.AllowImportant'); + // wrap all attr-defs with decorator that handles !important + foreach ($this->info as $k => $v) { + $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important); + } + + $this->setupConfigStuff($config); + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupProprietary($config) + { + // Internet Explorer only scrollbar colors + $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color(); + + // vendor specific prefixes of opacity + $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + + // only opacity, for now + $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter(); + + // more CSS3 + $this->info['page-break-after'] = + $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum( + array( + 'auto', + 'always', + 'avoid', + 'left', + 'right' + ) + ); + $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid')); + + $border_radius = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative + new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative + )); + + $this->info['border-top-left-radius'] = + $this->info['border-top-right-radius'] = + $this->info['border-bottom-right-radius'] = + $this->info['border-bottom-left-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 2); + // TODO: support SLASH syntax + $this->info['border-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 4); + + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTricky($config) + { + $this->info['display'] = new HTMLPurifier_AttrDef_Enum( + array( + 'inline', + 'block', + 'list-item', + 'run-in', + 'compact', + 'marker', + 'table', + 'inline-block', + 'inline-table', + 'table-row-group', + 'table-header-group', + 'table-footer-group', + 'table-row', + 'table-column-group', + 'table-column', + 'table-cell', + 'table-caption', + 'none' + ) + ); + $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum( + array('visible', 'hidden', 'collapse') + ); + $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll')); + $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue(); + } + + /** + * @param HTMLPurifier_Config $config + */ + protected function doSetupTrusted($config) + { + $this->info['position'] = new HTMLPurifier_AttrDef_Enum( + array('static', 'relative', 'absolute', 'fixed') + ); + $this->info['top'] = + $this->info['left'] = + $this->info['right'] = + $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_CSS_Length(), + new HTMLPurifier_AttrDef_CSS_Percentage(), + new HTMLPurifier_AttrDef_Enum(array('auto')), + ) + ); + $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite( + array( + new HTMLPurifier_AttrDef_Integer(), + new HTMLPurifier_AttrDef_Enum(array('auto')), + ) + ); + } + + /** + * Performs extra config-based processing. Based off of + * HTMLPurifier_HTMLDefinition. + * @param HTMLPurifier_Config $config + * @todo Refactor duplicate elements into common class (probably using + * composition, not inheritance). + */ + protected function setupConfigStuff($config) + { + // setup allowed elements + $support = "(for information on implementing this, see the " . + "support forums) "; + $allowed_properties = $config->get('CSS.AllowedProperties'); + if ($allowed_properties !== null) { + foreach ($this->info as $name => $d) { + if (!isset($allowed_properties[$name])) { + unset($this->info[$name]); + } + unset($allowed_properties[$name]); + } + // emit errors + foreach ($allowed_properties as $name => $d) { + // :TODO: Is this htmlspecialchars() call really necessary? + $name = htmlspecialchars($name); + trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING); + } + } + + $forbidden_properties = $config->get('CSS.ForbiddenProperties'); + if ($forbidden_properties !== null) { + foreach ($this->info as $name => $d) { + if (isset($forbidden_properties[$name])) { + unset($this->info[$name]); + } + } + } + } +} + + + + + +/** + * Defines allowed child nodes and validates nodes against it. + */ +abstract class HTMLPurifier_ChildDef +{ + /** + * Type of child definition, usually right-most part of class name lowercase. + * Used occasionally in terms of context. + * @type string + */ + public $type; + + /** + * Indicates whether or not an empty array of children is okay. + * + * This is necessary for redundant checking when changes affecting + * a child node may cause a parent node to now be disallowed. + * @type bool + */ + public $allow_empty; + + /** + * Lookup array of all elements that this definition could possibly allow. + * @type array + */ + public $elements = array(); + + /** + * Get lookup of tag names that should not close this element automatically. + * All other elements will do so. + * @param HTMLPurifier_Config $config HTMLPurifier_Config object + * @return array + */ + public function getAllowedElements($config) + { + return $this->elements; + } + + /** + * Validates nodes according to definition and returns modification. + * + * @param HTMLPurifier_Node[] $children Array of HTMLPurifier_Node + * @param HTMLPurifier_Config $config HTMLPurifier_Config object + * @param HTMLPurifier_Context $context HTMLPurifier_Context object + * @return bool|array true to leave nodes as is, false to remove parent node, array of replacement children + */ + abstract public function validateChildren($children, $config, $context); +} + + + + + +/** + * Configuration object that triggers customizable behavior. + * + * @warning This class is strongly defined: that means that the class + * will fail if an undefined directive is retrieved or set. + * + * @note Many classes that could (although many times don't) use the + * configuration object make it a mandatory parameter. This is + * because a configuration object should always be forwarded, + * otherwise, you run the risk of missing a parameter and then + * being stumped when a configuration directive doesn't work. + * + * @todo Reconsider some of the public member variables + */ +class HTMLPurifier_Config +{ + + /** + * HTML Purifier's version + * @type string + */ + public $version = '4.8.0'; + + /** + * Whether or not to automatically finalize + * the object if a read operation is done. + * @type bool + */ + public $autoFinalize = true; + + // protected member variables + + /** + * Namespace indexed array of serials for specific namespaces. + * @see getSerial() for more info. + * @type string[] + */ + protected $serials = array(); + + /** + * Serial for entire configuration object. + * @type string + */ + protected $serial; + + /** + * Parser for variables. + * @type HTMLPurifier_VarParser_Flexible + */ + protected $parser = null; + + /** + * Reference HTMLPurifier_ConfigSchema for value checking. + * @type HTMLPurifier_ConfigSchema + * @note This is public for introspective purposes. Please don't + * abuse! + */ + public $def; + + /** + * Indexed array of definitions. + * @type HTMLPurifier_Definition[] + */ + protected $definitions; + + /** + * Whether or not config is finalized. + * @type bool + */ + protected $finalized = false; + + /** + * Property list containing configuration directives. + * @type array + */ + protected $plist; + + /** + * Whether or not a set is taking place due to an alias lookup. + * @type bool + */ + private $aliasMode; + + /** + * Set to false if you do not want line and file numbers in errors. + * (useful when unit testing). This will also compress some errors + * and exceptions. + * @type bool + */ + public $chatty = true; + + /** + * Current lock; only gets to this namespace are allowed. + * @type string + */ + private $lock; + + /** + * Constructor + * @param HTMLPurifier_ConfigSchema $definition ConfigSchema that defines + * what directives are allowed. + * @param HTMLPurifier_PropertyList $parent + */ + public function __construct($definition, $parent = null) + { + $parent = $parent ? $parent : $definition->defaultPlist; + $this->plist = new HTMLPurifier_PropertyList($parent); + $this->def = $definition; // keep a copy around for checking + $this->parser = new HTMLPurifier_VarParser_Flexible(); + } + + /** + * Convenience constructor that creates a config object based on a mixed var + * @param mixed $config Variable that defines the state of the config + * object. Can be: a HTMLPurifier_Config() object, + * an array of directives based on loadArray(), + * or a string filename of an ini file. + * @param HTMLPurifier_ConfigSchema $schema Schema object + * @return HTMLPurifier_Config Configured object + */ + public static function create($config, $schema = null) + { + if ($config instanceof HTMLPurifier_Config) { + // pass-through + return $config; + } + if (!$schema) { + $ret = HTMLPurifier_Config::createDefault(); + } else { + $ret = new HTMLPurifier_Config($schema); + } + if (is_string($config)) { + $ret->loadIni($config); + } elseif (is_array($config)) $ret->loadArray($config); + return $ret; + } + + /** + * Creates a new config object that inherits from a previous one. + * @param HTMLPurifier_Config $config Configuration object to inherit from. + * @return HTMLPurifier_Config object with $config as its parent. + */ + public static function inherit(HTMLPurifier_Config $config) + { + return new HTMLPurifier_Config($config->def, $config->plist); + } + + /** + * Convenience constructor that creates a default configuration object. + * @return HTMLPurifier_Config default object. + */ + public static function createDefault() + { + $definition = HTMLPurifier_ConfigSchema::instance(); + $config = new HTMLPurifier_Config($definition); + return $config; + } + + /** + * Retrieves a value from the configuration. + * + * @param string $key String key + * @param mixed $a + * + * @return mixed + */ + public function get($key, $a = null) + { + if ($a !== null) { + $this->triggerError( + "Using deprecated API: use \$config->get('$key.$a') instead", + E_USER_WARNING + ); + $key = "$key.$a"; + } + if (!$this->finalized) { + $this->autoFinalize(); + } + if (!isset($this->def->info[$key])) { + // can't add % due to SimpleTest bug + $this->triggerError( + 'Cannot retrieve value of undefined directive ' . htmlspecialchars($key), + E_USER_WARNING + ); + return; + } + if (isset($this->def->info[$key]->isAlias)) { + $d = $this->def->info[$key]; + $this->triggerError( + 'Cannot get value from aliased directive, use real name ' . $d->key, + E_USER_ERROR + ); + return; + } + if ($this->lock) { + list($ns) = explode('.', $key); + if ($ns !== $this->lock) { + $this->triggerError( + 'Cannot get value of namespace ' . $ns . ' when lock for ' . + $this->lock . + ' is active, this probably indicates a Definition setup method ' . + 'is accessing directives that are not within its namespace', + E_USER_ERROR + ); + return; + } + } + return $this->plist->get($key); + } + + /** + * Retrieves an array of directives to values from a given namespace + * + * @param string $namespace String namespace + * + * @return array + */ + public function getBatch($namespace) + { + if (!$this->finalized) { + $this->autoFinalize(); + } + $full = $this->getAll(); + if (!isset($full[$namespace])) { + $this->triggerError( + 'Cannot retrieve undefined namespace ' . + htmlspecialchars($namespace), + E_USER_WARNING + ); + return; + } + return $full[$namespace]; + } + + /** + * Returns a SHA-1 signature of a segment of the configuration object + * that uniquely identifies that particular configuration + * + * @param string $namespace Namespace to get serial for + * + * @return string + * @note Revision is handled specially and is removed from the batch + * before processing! + */ + public function getBatchSerial($namespace) + { + if (empty($this->serials[$namespace])) { + $batch = $this->getBatch($namespace); + unset($batch['DefinitionRev']); + $this->serials[$namespace] = sha1(serialize($batch)); + } + return $this->serials[$namespace]; + } + + /** + * Returns a SHA-1 signature for the entire configuration object + * that uniquely identifies that particular configuration + * + * @return string + */ + public function getSerial() + { + if (empty($this->serial)) { + $this->serial = sha1(serialize($this->getAll())); + } + return $this->serial; + } + + /** + * Retrieves all directives, organized by namespace + * + * @warning This is a pretty inefficient function, avoid if you can + */ + public function getAll() + { + if (!$this->finalized) { + $this->autoFinalize(); + } + $ret = array(); + foreach ($this->plist->squash() as $name => $value) { + list($ns, $key) = explode('.', $name, 2); + $ret[$ns][$key] = $value; + } + return $ret; + } + + /** + * Sets a value to configuration. + * + * @param string $key key + * @param mixed $value value + * @param mixed $a + */ + public function set($key, $value, $a = null) + { + if (strpos($key, '.') === false) { + $namespace = $key; + $directive = $value; + $value = $a; + $key = "$key.$directive"; + $this->triggerError("Using deprecated API: use \$config->set('$key', ...) instead", E_USER_NOTICE); + } else { + list($namespace) = explode('.', $key); + } + if ($this->isFinalized('Cannot set directive after finalization')) { + return; + } + if (!isset($this->def->info[$key])) { + $this->triggerError( + 'Cannot set undefined directive ' . htmlspecialchars($key) . ' to value', + E_USER_WARNING + ); + return; + } + $def = $this->def->info[$key]; + + if (isset($def->isAlias)) { + if ($this->aliasMode) { + $this->triggerError( + 'Double-aliases not allowed, please fix '. + 'ConfigSchema bug with' . $key, + E_USER_ERROR + ); + return; + } + $this->aliasMode = true; + $this->set($def->key, $value); + $this->aliasMode = false; + $this->triggerError("$key is an alias, preferred directive name is {$def->key}", E_USER_NOTICE); + return; + } + + // Raw type might be negative when using the fully optimized form + // of stdclass, which indicates allow_null == true + $rtype = is_int($def) ? $def : $def->type; + if ($rtype < 0) { + $type = -$rtype; + $allow_null = true; + } else { + $type = $rtype; + $allow_null = isset($def->allow_null); + } + + try { + $value = $this->parser->parse($value, $type, $allow_null); + } catch (HTMLPurifier_VarParserException $e) { + $this->triggerError( + 'Value for ' . $key . ' is of invalid type, should be ' . + HTMLPurifier_VarParser::getTypeName($type), + E_USER_WARNING + ); + return; + } + if (is_string($value) && is_object($def)) { + // resolve value alias if defined + if (isset($def->aliases[$value])) { + $value = $def->aliases[$value]; + } + // check to see if the value is allowed + if (isset($def->allowed) && !isset($def->allowed[$value])) { + $this->triggerError( + 'Value not supported, valid values are: ' . + $this->_listify($def->allowed), + E_USER_WARNING + ); + return; + } + } + $this->plist->set($key, $value); + + // reset definitions if the directives they depend on changed + // this is a very costly process, so it's discouraged + // with finalization + if ($namespace == 'HTML' || $namespace == 'CSS' || $namespace == 'URI') { + $this->definitions[$namespace] = null; + } + + $this->serials[$namespace] = false; + } + + /** + * Convenience function for error reporting + * + * @param array $lookup + * + * @return string + */ + private function _listify($lookup) + { + $list = array(); + foreach ($lookup as $name => $b) { + $list[] = $name; + } + return implode(', ', $list); + } + + /** + * Retrieves object reference to the HTML definition. + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawHTMLDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_HTMLDefinition + */ + public function getHTMLDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('HTML', $raw, $optimized); + } + + /** + * Retrieves object reference to the CSS definition + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawCSSDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_CSSDefinition + */ + public function getCSSDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('CSS', $raw, $optimized); + } + + /** + * Retrieves object reference to the URI definition + * + * @param bool $raw Return a copy that has not been setup yet. Must be + * called before it's been setup, otherwise won't work. + * @param bool $optimized If true, this method may return null, to + * indicate that a cached version of the modified + * definition object is available and no further edits + * are necessary. Consider using + * maybeGetRawURIDefinition, which is more explicitly + * named, instead. + * + * @return HTMLPurifier_URIDefinition + */ + public function getURIDefinition($raw = false, $optimized = false) + { + return $this->getDefinition('URI', $raw, $optimized); + } + + /** + * Retrieves a definition + * + * @param string $type Type of definition: HTML, CSS, etc + * @param bool $raw Whether or not definition should be returned raw + * @param bool $optimized Only has an effect when $raw is true. Whether + * or not to return null if the result is already present in + * the cache. This is off by default for backwards + * compatibility reasons, but you need to do things this + * way in order to ensure that caching is done properly. + * Check out enduser-customize.html for more details. + * We probably won't ever change this default, as much as the + * maybe semantics is the "right thing to do." + * + * @throws HTMLPurifier_Exception + * @return HTMLPurifier_Definition + */ + public function getDefinition($type, $raw = false, $optimized = false) + { + if ($optimized && !$raw) { + throw new HTMLPurifier_Exception("Cannot set optimized = true when raw = false"); + } + if (!$this->finalized) { + $this->autoFinalize(); + } + // temporarily suspend locks, so we can handle recursive definition calls + $lock = $this->lock; + $this->lock = null; + $factory = HTMLPurifier_DefinitionCacheFactory::instance(); + $cache = $factory->create($type, $this); + $this->lock = $lock; + if (!$raw) { + // full definition + // --------------- + // check if definition is in memory + if (!empty($this->definitions[$type])) { + $def = $this->definitions[$type]; + // check if the definition is setup + if ($def->setup) { + return $def; + } else { + $def->setup($this); + if ($def->optimized) { + $cache->add($def, $this); + } + return $def; + } + } + // check if definition is in cache + $def = $cache->get($this); + if ($def) { + // definition in cache, save to memory and return it + $this->definitions[$type] = $def; + return $def; + } + // initialize it + $def = $this->initDefinition($type); + // set it up + $this->lock = $type; + $def->setup($this); + $this->lock = null; + // save in cache + $cache->add($def, $this); + // return it + return $def; + } else { + // raw definition + // -------------- + // check preconditions + $def = null; + if ($optimized) { + if (is_null($this->get($type . '.DefinitionID'))) { + // fatally error out if definition ID not set + throw new HTMLPurifier_Exception( + "Cannot retrieve raw version without specifying %$type.DefinitionID" + ); + } + } + if (!empty($this->definitions[$type])) { + $def = $this->definitions[$type]; + if ($def->setup && !$optimized) { + $extra = $this->chatty ? + " (try moving this code block earlier in your initialization)" : + ""; + throw new HTMLPurifier_Exception( + "Cannot retrieve raw definition after it has already been setup" . + $extra + ); + } + if ($def->optimized === null) { + $extra = $this->chatty ? " (try flushing your cache)" : ""; + throw new HTMLPurifier_Exception( + "Optimization status of definition is unknown" . $extra + ); + } + if ($def->optimized !== $optimized) { + $msg = $optimized ? "optimized" : "unoptimized"; + $extra = $this->chatty ? + " (this backtrace is for the first inconsistent call, which was for a $msg raw definition)" + : ""; + throw new HTMLPurifier_Exception( + "Inconsistent use of optimized and unoptimized raw definition retrievals" . $extra + ); + } + } + // check if definition was in memory + if ($def) { + if ($def->setup) { + // invariant: $optimized === true (checked above) + return null; + } else { + return $def; + } + } + // if optimized, check if definition was in cache + // (because we do the memory check first, this formulation + // is prone to cache slamming, but I think + // guaranteeing that either /all/ of the raw + // setup code or /none/ of it is run is more important.) + if ($optimized) { + // This code path only gets run once; once we put + // something in $definitions (which is guaranteed by the + // trailing code), we always short-circuit above. + $def = $cache->get($this); + if ($def) { + // save the full definition for later, but don't + // return it yet + $this->definitions[$type] = $def; + return null; + } + } + // check invariants for creation + if (!$optimized) { + if (!is_null($this->get($type . '.DefinitionID'))) { + if ($this->chatty) { + $this->triggerError( + 'Due to a documentation error in previous version of HTML Purifier, your ' . + 'definitions are not being cached. If this is OK, you can remove the ' . + '%$type.DefinitionRev and %$type.DefinitionID declaration. Otherwise, ' . + 'modify your code to use maybeGetRawDefinition, and test if the returned ' . + 'value is null before making any edits (if it is null, that means that a ' . + 'cached version is available, and no raw operations are necessary). See ' . + '' . + 'Customize for more details', + E_USER_WARNING + ); + } else { + $this->triggerError( + "Useless DefinitionID declaration", + E_USER_WARNING + ); + } + } + } + // initialize it + $def = $this->initDefinition($type); + $def->optimized = $optimized; + return $def; + } + throw new HTMLPurifier_Exception("The impossible happened!"); + } + + /** + * Initialise definition + * + * @param string $type What type of definition to create + * + * @return HTMLPurifier_CSSDefinition|HTMLPurifier_HTMLDefinition|HTMLPurifier_URIDefinition + * @throws HTMLPurifier_Exception + */ + private function initDefinition($type) + { + // quick checks failed, let's create the object + if ($type == 'HTML') { + $def = new HTMLPurifier_HTMLDefinition(); + } elseif ($type == 'CSS') { + $def = new HTMLPurifier_CSSDefinition(); + } elseif ($type == 'URI') { + $def = new HTMLPurifier_URIDefinition(); + } else { + throw new HTMLPurifier_Exception( + "Definition of $type type not supported" + ); + } + $this->definitions[$type] = $def; + return $def; + } + + public function maybeGetRawDefinition($name) + { + return $this->getDefinition($name, true, true); + } + + /** + * @return HTMLPurifier_HTMLDefinition + */ + public function maybeGetRawHTMLDefinition() + { + return $this->getDefinition('HTML', true, true); + } + + /** + * @return HTMLPurifier_CSSDefinition + */ + public function maybeGetRawCSSDefinition() + { + return $this->getDefinition('CSS', true, true); + } + + /** + * @return HTMLPurifier_URIDefinition + */ + public function maybeGetRawURIDefinition() + { + return $this->getDefinition('URI', true, true); + } + + /** + * Loads configuration values from an array with the following structure: + * Namespace.Directive => Value + * + * @param array $config_array Configuration associative array + */ + public function loadArray($config_array) + { + if ($this->isFinalized('Cannot load directives after finalization')) { + return; + } + foreach ($config_array as $key => $value) { + $key = str_replace('_', '.', $key); + if (strpos($key, '.') !== false) { + $this->set($key, $value); + } else { + $namespace = $key; + $namespace_values = $value; + foreach ($namespace_values as $directive => $value2) { + $this->set($namespace .'.'. $directive, $value2); + } + } + } + } + + /** + * Returns a list of array(namespace, directive) for all directives + * that are allowed in a web-form context as per an allowed + * namespaces/directives list. + * + * @param array $allowed List of allowed namespaces/directives + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return array + */ + public static function getAllowedDirectivesForForm($allowed, $schema = null) + { + if (!$schema) { + $schema = HTMLPurifier_ConfigSchema::instance(); + } + if ($allowed !== true) { + if (is_string($allowed)) { + $allowed = array($allowed); + } + $allowed_ns = array(); + $allowed_directives = array(); + $blacklisted_directives = array(); + foreach ($allowed as $ns_or_directive) { + if (strpos($ns_or_directive, '.') !== false) { + // directive + if ($ns_or_directive[0] == '-') { + $blacklisted_directives[substr($ns_or_directive, 1)] = true; + } else { + $allowed_directives[$ns_or_directive] = true; + } + } else { + // namespace + $allowed_ns[$ns_or_directive] = true; + } + } + } + $ret = array(); + foreach ($schema->info as $key => $def) { + list($ns, $directive) = explode('.', $key, 2); + if ($allowed !== true) { + if (isset($blacklisted_directives["$ns.$directive"])) { + continue; + } + if (!isset($allowed_directives["$ns.$directive"]) && !isset($allowed_ns[$ns])) { + continue; + } + } + if (isset($def->isAlias)) { + continue; + } + if ($directive == 'DefinitionID' || $directive == 'DefinitionRev') { + continue; + } + $ret[] = array($ns, $directive); + } + return $ret; + } + + /** + * Loads configuration values from $_GET/$_POST that were posted + * via ConfigForm + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return mixed + */ + public static function loadArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) + { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $schema); + $config = HTMLPurifier_Config::create($ret, $schema); + return $config; + } + + /** + * Merges in configuration values from $_GET/$_POST to object. NOT STATIC. + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + */ + public function mergeArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true) + { + $ret = HTMLPurifier_Config::prepareArrayFromForm($array, $index, $allowed, $mq_fix, $this->def); + $this->loadArray($ret); + } + + /** + * Prepares an array from a form into something usable for the more + * strict parts of HTMLPurifier_Config + * + * @param array $array $_GET or $_POST array to import + * @param string|bool $index Index/name that the config variables are in + * @param array|bool $allowed List of allowed namespaces/directives + * @param bool $mq_fix Boolean whether or not to enable magic quotes fix + * @param HTMLPurifier_ConfigSchema $schema Schema to use, if not global copy + * + * @return array + */ + public static function prepareArrayFromForm($array, $index = false, $allowed = true, $mq_fix = true, $schema = null) + { + if ($index !== false) { + $array = (isset($array[$index]) && is_array($array[$index])) ? $array[$index] : array(); + } + $mq = $mq_fix && function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc(); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $schema); + $ret = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $skey = "$ns.$directive"; + if (!empty($array["Null_$skey"])) { + $ret[$ns][$directive] = null; + continue; + } + if (!isset($array[$skey])) { + continue; + } + $value = $mq ? stripslashes($array[$skey]) : $array[$skey]; + $ret[$ns][$directive] = $value; + } + return $ret; + } + + /** + * Loads configuration values from an ini file + * + * @param string $filename Name of ini file + */ + public function loadIni($filename) + { + if ($this->isFinalized('Cannot load directives after finalization')) { + return; + } + $array = parse_ini_file($filename, true); + $this->loadArray($array); + } + + /** + * Checks whether or not the configuration object is finalized. + * + * @param string|bool $error String error message, or false for no error + * + * @return bool + */ + public function isFinalized($error = false) + { + if ($this->finalized && $error) { + $this->triggerError($error, E_USER_ERROR); + } + return $this->finalized; + } + + /** + * Finalizes configuration only if auto finalize is on and not + * already finalized + */ + public function autoFinalize() + { + if ($this->autoFinalize) { + $this->finalize(); + } else { + $this->plist->squash(true); + } + } + + /** + * Finalizes a configuration object, prohibiting further change + */ + public function finalize() + { + $this->finalized = true; + $this->parser = null; + } + + /** + * Produces a nicely formatted error message by supplying the + * stack frame information OUTSIDE of HTMLPurifier_Config. + * + * @param string $msg An error message + * @param int $no An error number + */ + protected function triggerError($msg, $no) + { + // determine previous stack frame + $extra = ''; + if ($this->chatty) { + $trace = debug_backtrace(); + // zip(tail(trace), trace) -- but PHP is not Haskell har har + for ($i = 0, $c = count($trace); $i < $c - 1; $i++) { + // XXX this is not correct on some versions of HTML Purifier + if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') { + continue; + } + $frame = $trace[$i]; + $extra = " invoked on line {$frame['line']} in file {$frame['file']}"; + break; + } + } + trigger_error($msg . $extra, $no); + } + + /** + * Returns a serialized form of the configuration object that can + * be reconstituted. + * + * @return string + */ + public function serialize() + { + $this->getDefinition('HTML'); + $this->getDefinition('CSS'); + $this->getDefinition('URI'); + return serialize($this); + } + +} + + + + + +/** + * Configuration definition, defines directives and their defaults. + */ +class HTMLPurifier_ConfigSchema +{ + /** + * Defaults of the directives and namespaces. + * @type array + * @note This shares the exact same structure as HTMLPurifier_Config::$conf + */ + public $defaults = array(); + + /** + * The default property list. Do not edit this property list. + * @type array + */ + public $defaultPlist; + + /** + * Definition of the directives. + * The structure of this is: + * + * array( + * 'Namespace' => array( + * 'Directive' => new stdclass(), + * ) + * ) + * + * The stdclass may have the following properties: + * + * - If isAlias isn't set: + * - type: Integer type of directive, see HTMLPurifier_VarParser for definitions + * - allow_null: If set, this directive allows null values + * - aliases: If set, an associative array of value aliases to real values + * - allowed: If set, a lookup array of allowed (string) values + * - If isAlias is set: + * - namespace: Namespace this directive aliases to + * - name: Directive name this directive aliases to + * + * In certain degenerate cases, stdclass will actually be an integer. In + * that case, the value is equivalent to an stdclass with the type + * property set to the integer. If the integer is negative, type is + * equal to the absolute value of integer, and allow_null is true. + * + * This class is friendly with HTMLPurifier_Config. If you need introspection + * about the schema, you're better of using the ConfigSchema_Interchange, + * which uses more memory but has much richer information. + * @type array + */ + public $info = array(); + + /** + * Application-wide singleton + * @type HTMLPurifier_ConfigSchema + */ + protected static $singleton; + + public function __construct() + { + $this->defaultPlist = new HTMLPurifier_PropertyList(); + } + + /** + * Unserializes the default ConfigSchema. + * @return HTMLPurifier_ConfigSchema + */ + public static function makeFromSerial() + { + $contents = file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema.ser'); + $r = unserialize($contents); + if (!$r) { + $hash = sha1($contents); + trigger_error("Unserialization of configuration schema failed, sha1 of file was $hash", E_USER_ERROR); + } + return $r; + } + + /** + * Retrieves an instance of the application-wide configuration definition. + * @param HTMLPurifier_ConfigSchema $prototype + * @return HTMLPurifier_ConfigSchema + */ + public static function instance($prototype = null) + { + if ($prototype !== null) { + HTMLPurifier_ConfigSchema::$singleton = $prototype; + } elseif (HTMLPurifier_ConfigSchema::$singleton === null || $prototype === true) { + HTMLPurifier_ConfigSchema::$singleton = HTMLPurifier_ConfigSchema::makeFromSerial(); + } + return HTMLPurifier_ConfigSchema::$singleton; + } + + /** + * Defines a directive for configuration + * @warning Will fail of directive's namespace is defined. + * @warning This method's signature is slightly different from the legacy + * define() static method! Beware! + * @param string $key Name of directive + * @param mixed $default Default value of directive + * @param string $type Allowed type of the directive. See + * HTMLPurifier_DirectiveDef::$type for allowed values + * @param bool $allow_null Whether or not to allow null values + */ + public function add($key, $default, $type, $allow_null) + { + $obj = new stdclass(); + $obj->type = is_int($type) ? $type : HTMLPurifier_VarParser::$types[$type]; + if ($allow_null) { + $obj->allow_null = true; + } + $this->info[$key] = $obj; + $this->defaults[$key] = $default; + $this->defaultPlist->set($key, $default); + } + + /** + * Defines a directive value alias. + * + * Directive value aliases are convenient for developers because it lets + * them set a directive to several values and get the same result. + * @param string $key Name of Directive + * @param array $aliases Hash of aliased values to the real alias + */ + public function addValueAliases($key, $aliases) + { + if (!isset($this->info[$key]->aliases)) { + $this->info[$key]->aliases = array(); + } + foreach ($aliases as $alias => $real) { + $this->info[$key]->aliases[$alias] = $real; + } + } + + /** + * Defines a set of allowed values for a directive. + * @warning This is slightly different from the corresponding static + * method definition. + * @param string $key Name of directive + * @param array $allowed Lookup array of allowed values + */ + public function addAllowedValues($key, $allowed) + { + $this->info[$key]->allowed = $allowed; + } + + /** + * Defines a directive alias for backwards compatibility + * @param string $key Directive that will be aliased + * @param string $new_key Directive that the alias will be to + */ + public function addAlias($key, $new_key) + { + $obj = new stdclass; + $obj->key = $new_key; + $obj->isAlias = true; + $this->info[$key] = $obj; + } + + /** + * Replaces any stdclass that only has the type property with type integer. + */ + public function postProcess() + { + foreach ($this->info as $key => $v) { + if (count((array) $v) == 1) { + $this->info[$key] = $v->type; + } elseif (count((array) $v) == 2 && isset($v->allow_null)) { + $this->info[$key] = -$v->type; + } + } + } +} + + + + + +/** + * @todo Unit test + */ +class HTMLPurifier_ContentSets +{ + + /** + * List of content set strings (pipe separators) indexed by name. + * @type array + */ + public $info = array(); + + /** + * List of content set lookups (element => true) indexed by name. + * @type array + * @note This is in HTMLPurifier_HTMLDefinition->info_content_sets + */ + public $lookup = array(); + + /** + * Synchronized list of defined content sets (keys of info). + * @type array + */ + protected $keys = array(); + /** + * Synchronized list of defined content values (values of info). + * @type array + */ + protected $values = array(); + + /** + * Merges in module's content sets, expands identifiers in the content + * sets and populates the keys, values and lookup member variables. + * @param HTMLPurifier_HTMLModule[] $modules List of HTMLPurifier_HTMLModule + */ + public function __construct($modules) + { + if (!is_array($modules)) { + $modules = array($modules); + } + // populate content_sets based on module hints + // sorry, no way of overloading + foreach ($modules as $module) { + foreach ($module->content_sets as $key => $value) { + $temp = $this->convertToLookup($value); + if (isset($this->lookup[$key])) { + // add it into the existing content set + $this->lookup[$key] = array_merge($this->lookup[$key], $temp); + } else { + $this->lookup[$key] = $temp; + } + } + } + $old_lookup = false; + while ($old_lookup !== $this->lookup) { + $old_lookup = $this->lookup; + foreach ($this->lookup as $i => $set) { + $add = array(); + foreach ($set as $element => $x) { + if (isset($this->lookup[$element])) { + $add += $this->lookup[$element]; + unset($this->lookup[$i][$element]); + } + } + $this->lookup[$i] += $add; + } + } + + foreach ($this->lookup as $key => $lookup) { + $this->info[$key] = implode(' | ', array_keys($lookup)); + } + $this->keys = array_keys($this->info); + $this->values = array_values($this->info); + } + + /** + * Accepts a definition; generates and assigns a ChildDef for it + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef reference + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef + */ + public function generateChildDef(&$def, $module) + { + if (!empty($def->child)) { // already done! + return; + } + $content_model = $def->content_model; + if (is_string($content_model)) { + // Assume that $this->keys is alphanumeric + $def->content_model = preg_replace_callback( + '/\b(' . implode('|', $this->keys) . ')\b/', + array($this, 'generateChildDefCallback'), + $content_model + ); + //$def->content_model = str_replace( + // $this->keys, $this->values, $content_model); + } + $def->child = $this->getChildDef($def, $module); + } + + public function generateChildDefCallback($matches) + { + return $this->info[$matches[0]]; + } + + /** + * Instantiates a ChildDef based on content_model and content_model_type + * member variables in HTMLPurifier_ElementDef + * @note This will also defer to modules for custom HTMLPurifier_ChildDef + * subclasses that need content set expansion + * @param HTMLPurifier_ElementDef $def HTMLPurifier_ElementDef to have ChildDef extracted + * @param HTMLPurifier_HTMLModule $module Module that defined the ElementDef + * @return HTMLPurifier_ChildDef corresponding to ElementDef + */ + public function getChildDef($def, $module) + { + $value = $def->content_model; + if (is_object($value)) { + trigger_error( + 'Literal object child definitions should be stored in '. + 'ElementDef->child not ElementDef->content_model', + E_USER_NOTICE + ); + return $value; + } + switch ($def->content_model_type) { + case 'required': + return new HTMLPurifier_ChildDef_Required($value); + case 'optional': + return new HTMLPurifier_ChildDef_Optional($value); + case 'empty': + return new HTMLPurifier_ChildDef_Empty(); + case 'custom': + return new HTMLPurifier_ChildDef_Custom($value); + } + // defer to its module + $return = false; + if ($module->defines_child_def) { // save a func call + $return = $module->getChildDef($def); + } + if ($return !== false) { + return $return; + } + // error-out + trigger_error( + 'Could not determine which ChildDef class to instantiate', + E_USER_ERROR + ); + return false; + } + + /** + * Converts a string list of elements separated by pipes into + * a lookup array. + * @param string $string List of elements + * @return array Lookup array of elements + */ + protected function convertToLookup($string) + { + $array = explode('|', str_replace(' ', '', $string)); + $ret = array(); + foreach ($array as $k) { + $ret[$k] = true; + } + return $ret; + } +} + + + + + +/** + * Registry object that contains information about the current context. + * @warning Is a bit buggy when variables are set to null: it thinks + * they don't exist! So use false instead, please. + * @note Since the variables Context deals with may not be objects, + * references are very important here! Do not remove! + */ +class HTMLPurifier_Context +{ + + /** + * Private array that stores the references. + * @type array + */ + private $_storage = array(); + + /** + * Registers a variable into the context. + * @param string $name String name + * @param mixed $ref Reference to variable to be registered + */ + public function register($name, &$ref) + { + if (array_key_exists($name, $this->_storage)) { + trigger_error( + "Name $name produces collision, cannot re-register", + E_USER_ERROR + ); + return; + } + $this->_storage[$name] =& $ref; + } + + /** + * Retrieves a variable reference from the context. + * @param string $name String name + * @param bool $ignore_error Boolean whether or not to ignore error + * @return mixed + */ + public function &get($name, $ignore_error = false) + { + if (!array_key_exists($name, $this->_storage)) { + if (!$ignore_error) { + trigger_error( + "Attempted to retrieve non-existent variable $name", + E_USER_ERROR + ); + } + $var = null; // so we can return by reference + return $var; + } + return $this->_storage[$name]; + } + + /** + * Destroys a variable in the context. + * @param string $name String name + */ + public function destroy($name) + { + if (!array_key_exists($name, $this->_storage)) { + trigger_error( + "Attempted to destroy non-existent variable $name", + E_USER_ERROR + ); + return; + } + unset($this->_storage[$name]); + } + + /** + * Checks whether or not the variable exists. + * @param string $name String name + * @return bool + */ + public function exists($name) + { + return array_key_exists($name, $this->_storage); + } + + /** + * Loads a series of variables from an associative array + * @param array $context_array Assoc array of variables to load + */ + public function loadArray($context_array) + { + foreach ($context_array as $key => $discard) { + $this->register($key, $context_array[$key]); + } + } +} + + + + + +/** + * Abstract class representing Definition cache managers that implements + * useful common methods and is a factory. + * @todo Create a separate maintenance file advanced users can use to + * cache their custom HTMLDefinition, which can be loaded + * via a configuration directive + * @todo Implement memcached + */ +abstract class HTMLPurifier_DefinitionCache +{ + /** + * @type string + */ + public $type; + + /** + * @param string $type Type of definition objects this instance of the + * cache will handle. + */ + public function __construct($type) + { + $this->type = $type; + } + + /** + * Generates a unique identifier for a particular configuration + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config + * @return string + */ + public function generateKey($config) + { + return $config->version . ',' . // possibly replace with function calls + $config->getBatchSerial($this->type) . ',' . + $config->get($this->type . '.DefinitionRev'); + } + + /** + * Tests whether or not a key is old with respect to the configuration's + * version and revision number. + * @param string $key Key to test + * @param HTMLPurifier_Config $config Instance of HTMLPurifier_Config to test against + * @return bool + */ + public function isOld($key, $config) + { + if (substr_count($key, ',') < 2) { + return true; + } + list($version, $hash, $revision) = explode(',', $key, 3); + $compare = version_compare($version, $config->version); + // version mismatch, is always old + if ($compare != 0) { + return true; + } + // versions match, ids match, check revision number + if ($hash == $config->getBatchSerial($this->type) && + $revision < $config->get($this->type . '.DefinitionRev')) { + return true; + } + return false; + } + + /** + * Checks if a definition's type jives with the cache's type + * @note Throws an error on failure + * @param HTMLPurifier_Definition $def Definition object to check + * @return bool true if good, false if not + */ + public function checkDefType($def) + { + if ($def->type !== $this->type) { + trigger_error("Cannot use definition of type {$def->type} in cache for {$this->type}"); + return false; + } + return true; + } + + /** + * Adds a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function add($def, $config); + + /** + * Unconditionally saves a definition object to the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function set($def, $config); + + /** + * Replace an object in the cache + * @param HTMLPurifier_Definition $def + * @param HTMLPurifier_Config $config + */ + abstract public function replace($def, $config); + + /** + * Retrieves a definition object from the cache + * @param HTMLPurifier_Config $config + */ + abstract public function get($config); + + /** + * Removes a definition object to the cache + * @param HTMLPurifier_Config $config + */ + abstract public function remove($config); + + /** + * Clears all objects from cache + * @param HTMLPurifier_Config $config + */ + abstract public function flush($config); + + /** + * Clears all expired (older version or revision) objects from cache + * @note Be careful implementing this method as flush. Flush must + * not interfere with other Definition types, and cleanup() + * should not be repeatedly called by userland code. + * @param HTMLPurifier_Config $config + */ + abstract public function cleanup($config); +} + + + + + +/** + * Responsible for creating definition caches. + */ +class HTMLPurifier_DefinitionCacheFactory +{ + /** + * @type array + */ + protected $caches = array('Serializer' => array()); + + /** + * @type array + */ + protected $implementations = array(); + + /** + * @type HTMLPurifier_DefinitionCache_Decorator[] + */ + protected $decorators = array(); + + /** + * Initialize default decorators + */ + public function setup() + { + $this->addDecorator('Cleanup'); + } + + /** + * Retrieves an instance of global definition cache factory. + * @param HTMLPurifier_DefinitionCacheFactory $prototype + * @return HTMLPurifier_DefinitionCacheFactory + */ + public static function instance($prototype = null) + { + static $instance; + if ($prototype !== null) { + $instance = $prototype; + } elseif ($instance === null || $prototype === true) { + $instance = new HTMLPurifier_DefinitionCacheFactory(); + $instance->setup(); + } + return $instance; + } + + /** + * Registers a new definition cache object + * @param string $short Short name of cache object, for reference + * @param string $long Full class name of cache object, for construction + */ + public function register($short, $long) + { + $this->implementations[$short] = $long; + } + + /** + * Factory method that creates a cache object based on configuration + * @param string $type Name of definitions handled by cache + * @param HTMLPurifier_Config $config Config instance + * @return mixed + */ + public function create($type, $config) + { + $method = $config->get('Cache.DefinitionImpl'); + if ($method === null) { + return new HTMLPurifier_DefinitionCache_Null($type); + } + if (!empty($this->caches[$method][$type])) { + return $this->caches[$method][$type]; + } + if (isset($this->implementations[$method]) && + class_exists($class = $this->implementations[$method], false)) { + $cache = new $class($type); + } else { + if ($method != 'Serializer') { + trigger_error("Unrecognized DefinitionCache $method, using Serializer instead", E_USER_WARNING); + } + $cache = new HTMLPurifier_DefinitionCache_Serializer($type); + } + foreach ($this->decorators as $decorator) { + $new_cache = $decorator->decorate($cache); + // prevent infinite recursion in PHP 4 + unset($cache); + $cache = $new_cache; + } + $this->caches[$method][$type] = $cache; + return $this->caches[$method][$type]; + } + + /** + * Registers a decorator to add to all new cache objects + * @param HTMLPurifier_DefinitionCache_Decorator|string $decorator An instance or the name of a decorator + */ + public function addDecorator($decorator) + { + if (is_string($decorator)) { + $class = "HTMLPurifier_DefinitionCache_Decorator_$decorator"; + $decorator = new $class; + } + $this->decorators[$decorator->name] = $decorator; + } +} + + + + + +/** + * Represents a document type, contains information on which modules + * need to be loaded. + * @note This class is inspected by Printer_HTMLDefinition->renderDoctype. + * If structure changes, please update that function. + */ +class HTMLPurifier_Doctype +{ + /** + * Full name of doctype + * @type string + */ + public $name; + + /** + * List of standard modules (string identifiers or literal objects) + * that this doctype uses + * @type array + */ + public $modules = array(); + + /** + * List of modules to use for tidying up code + * @type array + */ + public $tidyModules = array(); + + /** + * Is the language derived from XML (i.e. XHTML)? + * @type bool + */ + public $xml = true; + + /** + * List of aliases for this doctype + * @type array + */ + public $aliases = array(); + + /** + * Public DTD identifier + * @type string + */ + public $dtdPublic; + + /** + * System DTD identifier + * @type string + */ + public $dtdSystem; + + public function __construct( + $name = null, + $xml = true, + $modules = array(), + $tidyModules = array(), + $aliases = array(), + $dtd_public = null, + $dtd_system = null + ) { + $this->name = $name; + $this->xml = $xml; + $this->modules = $modules; + $this->tidyModules = $tidyModules; + $this->aliases = $aliases; + $this->dtdPublic = $dtd_public; + $this->dtdSystem = $dtd_system; + } +} + + + + + +class HTMLPurifier_DoctypeRegistry +{ + + /** + * Hash of doctype names to doctype objects. + * @type array + */ + protected $doctypes; + + /** + * Lookup table of aliases to real doctype names. + * @type array + */ + protected $aliases; + + /** + * Registers a doctype to the registry + * @note Accepts a fully-formed doctype object, or the + * parameters for constructing a doctype object + * @param string $doctype Name of doctype or literal doctype object + * @param bool $xml + * @param array $modules Modules doctype will load + * @param array $tidy_modules Modules doctype will load for certain modes + * @param array $aliases Alias names for doctype + * @param string $dtd_public + * @param string $dtd_system + * @return HTMLPurifier_Doctype Editable registered doctype + */ + public function register( + $doctype, + $xml = true, + $modules = array(), + $tidy_modules = array(), + $aliases = array(), + $dtd_public = null, + $dtd_system = null + ) { + if (!is_array($modules)) { + $modules = array($modules); + } + if (!is_array($tidy_modules)) { + $tidy_modules = array($tidy_modules); + } + if (!is_array($aliases)) { + $aliases = array($aliases); + } + if (!is_object($doctype)) { + $doctype = new HTMLPurifier_Doctype( + $doctype, + $xml, + $modules, + $tidy_modules, + $aliases, + $dtd_public, + $dtd_system + ); + } + $this->doctypes[$doctype->name] = $doctype; + $name = $doctype->name; + // hookup aliases + foreach ($doctype->aliases as $alias) { + if (isset($this->doctypes[$alias])) { + continue; + } + $this->aliases[$alias] = $name; + } + // remove old aliases + if (isset($this->aliases[$name])) { + unset($this->aliases[$name]); + } + return $doctype; + } + + /** + * Retrieves reference to a doctype of a certain name + * @note This function resolves aliases + * @note When possible, use the more fully-featured make() + * @param string $doctype Name of doctype + * @return HTMLPurifier_Doctype Editable doctype object + */ + public function get($doctype) + { + if (isset($this->aliases[$doctype])) { + $doctype = $this->aliases[$doctype]; + } + if (!isset($this->doctypes[$doctype])) { + trigger_error('Doctype ' . htmlspecialchars($doctype) . ' does not exist', E_USER_ERROR); + $anon = new HTMLPurifier_Doctype($doctype); + return $anon; + } + return $this->doctypes[$doctype]; + } + + /** + * Creates a doctype based on a configuration object, + * will perform initialization on the doctype + * @note Use this function to get a copy of doctype that config + * can hold on to (this is necessary in order to tell + * Generator whether or not the current document is XML + * based or not). + * @param HTMLPurifier_Config $config + * @return HTMLPurifier_Doctype + */ + public function make($config) + { + return clone $this->get($this->getDoctypeFromConfig($config)); + } + + /** + * Retrieves the doctype from the configuration object + * @param HTMLPurifier_Config $config + * @return string + */ + public function getDoctypeFromConfig($config) + { + // recommended test + $doctype = $config->get('HTML.Doctype'); + if (!empty($doctype)) { + return $doctype; + } + $doctype = $config->get('HTML.CustomDoctype'); + if (!empty($doctype)) { + return $doctype; + } + // backwards-compatibility + if ($config->get('HTML.XHTML')) { + $doctype = 'XHTML 1.0'; + } else { + $doctype = 'HTML 4.01'; + } + if ($config->get('HTML.Strict')) { + $doctype .= ' Strict'; + } else { + $doctype .= ' Transitional'; + } + return $doctype; + } +} + + + + + +/** + * Structure that stores an HTML element definition. Used by + * HTMLPurifier_HTMLDefinition and HTMLPurifier_HTMLModule. + * @note This class is inspected by HTMLPurifier_Printer_HTMLDefinition. + * Please update that class too. + * @warning If you add new properties to this class, you MUST update + * the mergeIn() method. + */ +class HTMLPurifier_ElementDef +{ + /** + * Does the definition work by itself, or is it created solely + * for the purpose of merging into another definition? + * @type bool + */ + public $standalone = true; + + /** + * Associative array of attribute name to HTMLPurifier_AttrDef. + * @type array + * @note Before being processed by HTMLPurifier_AttrCollections + * when modules are finalized during + * HTMLPurifier_HTMLDefinition->setup(), this array may also + * contain an array at index 0 that indicates which attribute + * collections to load into the full array. It may also + * contain string indentifiers in lieu of HTMLPurifier_AttrDef, + * see HTMLPurifier_AttrTypes on how they are expanded during + * HTMLPurifier_HTMLDefinition->setup() processing. + */ + public $attr = array(); + + // XXX: Design note: currently, it's not possible to override + // previously defined AttrTransforms without messing around with + // the final generated config. This is by design; a previous version + // used an associated list of attr_transform, but it was extremely + // easy to accidentally override other attribute transforms by + // forgetting to specify an index (and just using 0.) While we + // could check this by checking the index number and complaining, + // there is a second problem which is that it is not at all easy to + // tell when something is getting overridden. Combine this with a + // codebase where this isn't really being used, and it's perfect for + // nuking. + + /** + * List of tags HTMLPurifier_AttrTransform to be done before validation. + * @type array + */ + public $attr_transform_pre = array(); + + /** + * List of tags HTMLPurifier_AttrTransform to be done after validation. + * @type array + */ + public $attr_transform_post = array(); + + /** + * HTMLPurifier_ChildDef of this tag. + * @type HTMLPurifier_ChildDef + */ + public $child; + + /** + * Abstract string representation of internal ChildDef rules. + * @see HTMLPurifier_ContentSets for how this is parsed and then transformed + * into an HTMLPurifier_ChildDef. + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + * @type string + */ + public $content_model; + + /** + * Value of $child->type, used to determine which ChildDef to use, + * used in combination with $content_model. + * @warning This must be lowercase + * @warning This is a temporary variable that is not available after + * being processed by HTMLDefinition + * @type string + */ + public $content_model_type; + + /** + * Does the element have a content model (#PCDATA | Inline)*? This + * is important for chameleon ins and del processing in + * HTMLPurifier_ChildDef_Chameleon. Dynamically set: modules don't + * have to worry about this one. + * @type bool + */ + public $descendants_are_inline = false; + + /** + * List of the names of required attributes this element has. + * Dynamically populated by HTMLPurifier_HTMLDefinition::getElement() + * @type array + */ + public $required_attr = array(); + + /** + * Lookup table of tags excluded from all descendants of this tag. + * @type array + * @note SGML permits exclusions for all descendants, but this is + * not possible with DTDs or XML Schemas. W3C has elected to + * use complicated compositions of content_models to simulate + * exclusion for children, but we go the simpler, SGML-style + * route of flat-out exclusions, which correctly apply to + * all descendants and not just children. Note that the XHTML + * Modularization Abstract Modules are blithely unaware of such + * distinctions. + */ + public $excludes = array(); + + /** + * This tag is explicitly auto-closed by the following tags. + * @type array + */ + public $autoclose = array(); + + /** + * If a foreign element is found in this element, test if it is + * allowed by this sub-element; if it is, instead of closing the + * current element, place it inside this element. + * @type string + */ + public $wrap; + + /** + * Whether or not this is a formatting element affected by the + * "Active Formatting Elements" algorithm. + * @type bool + */ + public $formatting; + + /** + * Low-level factory constructor for creating new standalone element defs + */ + public static function create($content_model, $content_model_type, $attr) + { + $def = new HTMLPurifier_ElementDef(); + $def->content_model = $content_model; + $def->content_model_type = $content_model_type; + $def->attr = $attr; + return $def; + } + + /** + * Merges the values of another element definition into this one. + * Values from the new element def take precedence if a value is + * not mergeable. + * @param HTMLPurifier_ElementDef $def + */ + public function mergeIn($def) + { + // later keys takes precedence + foreach ($def->attr as $k => $v) { + if ($k === 0) { + // merge in the includes + // sorry, no way to override an include + foreach ($v as $v2) { + $this->attr[0][] = $v2; + } + continue; + } + if ($v === false) { + if (isset($this->attr[$k])) { + unset($this->attr[$k]); + } + continue; + } + $this->attr[$k] = $v; + } + $this->_mergeAssocArray($this->excludes, $def->excludes); + $this->attr_transform_pre = array_merge($this->attr_transform_pre, $def->attr_transform_pre); + $this->attr_transform_post = array_merge($this->attr_transform_post, $def->attr_transform_post); + + if (!empty($def->content_model)) { + $this->content_model = + str_replace("#SUPER", $this->content_model, $def->content_model); + $this->child = false; + } + if (!empty($def->content_model_type)) { + $this->content_model_type = $def->content_model_type; + $this->child = false; + } + if (!is_null($def->child)) { + $this->child = $def->child; + } + if (!is_null($def->formatting)) { + $this->formatting = $def->formatting; + } + if ($def->descendants_are_inline) { + $this->descendants_are_inline = $def->descendants_are_inline; + } + } + + /** + * Merges one array into another, removes values which equal false + * @param $a1 Array by reference that is merged into + * @param $a2 Array that merges into $a1 + */ + private function _mergeAssocArray(&$a1, $a2) + { + foreach ($a2 as $k => $v) { + if ($v === false) { + if (isset($a1[$k])) { + unset($a1[$k]); + } + continue; + } + $a1[$k] = $v; + } + } +} + + + + + +/** + * A UTF-8 specific character encoder that handles cleaning and transforming. + * @note All functions in this class should be static. + */ +class HTMLPurifier_Encoder +{ + + /** + * Constructor throws fatal error if you attempt to instantiate class + */ + private function __construct() + { + trigger_error('Cannot instantiate encoder, call methods statically', E_USER_ERROR); + } + + /** + * Error-handler that mutes errors, alternative to shut-up operator. + */ + public static function muteErrorHandler() + { + } + + /** + * iconv wrapper which mutes errors, but doesn't work around bugs. + * @param string $in Input encoding + * @param string $out Output encoding + * @param string $text The text to convert + * @return string + */ + public static function unsafeIconv($in, $out, $text) + { + set_error_handler(array('HTMLPurifier_Encoder', 'muteErrorHandler')); + $r = iconv($in, $out, $text); + restore_error_handler(); + return $r; + } + + /** + * iconv wrapper which mutes errors and works around bugs. + * @param string $in Input encoding + * @param string $out Output encoding + * @param string $text The text to convert + * @param int $max_chunk_size + * @return string + */ + public static function iconv($in, $out, $text, $max_chunk_size = 8000) + { + $code = self::testIconvTruncateBug(); + if ($code == self::ICONV_OK) { + return self::unsafeIconv($in, $out, $text); + } elseif ($code == self::ICONV_TRUNCATES) { + // we can only work around this if the input character set + // is utf-8 + if ($in == 'utf-8') { + if ($max_chunk_size < 4) { + trigger_error('max_chunk_size is too small', E_USER_WARNING); + return false; + } + // split into 8000 byte chunks, but be careful to handle + // multibyte boundaries properly + if (($c = strlen($text)) <= $max_chunk_size) { + return self::unsafeIconv($in, $out, $text); + } + $r = ''; + $i = 0; + while (true) { + if ($i + $max_chunk_size >= $c) { + $r .= self::unsafeIconv($in, $out, substr($text, $i)); + break; + } + // wibble the boundary + if (0x80 != (0xC0 & ord($text[$i + $max_chunk_size]))) { + $chunk_size = $max_chunk_size; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 1]))) { + $chunk_size = $max_chunk_size - 1; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 2]))) { + $chunk_size = $max_chunk_size - 2; + } elseif (0x80 != (0xC0 & ord($text[$i + $max_chunk_size - 3]))) { + $chunk_size = $max_chunk_size - 3; + } else { + return false; // rather confusing UTF-8... + } + $chunk = substr($text, $i, $chunk_size); // substr doesn't mind overlong lengths + $r .= self::unsafeIconv($in, $out, $chunk); + $i += $chunk_size; + } + return $r; + } else { + return false; + } + } else { + return false; + } + } + + /** + * Cleans a UTF-8 string for well-formedness and SGML validity + * + * It will parse according to UTF-8 and return a valid UTF8 string, with + * non-SGML codepoints excluded. + * + * @param string $str The string to clean + * @param bool $force_php + * @return string + * + * @note Just for reference, the non-SGML code points are 0 to 31 and + * 127 to 159, inclusive. However, we allow code points 9, 10 + * and 13, which are the tab, line feed and carriage return + * respectively. 128 and above the code points map to multibyte + * UTF-8 representations. + * + * @note Fallback code adapted from utf8ToUnicode by Henri Sivonen and + * hsivonen@iki.fi at under the + * LGPL license. Notes on what changed are inside, but in general, + * the original code transformed UTF-8 text into an array of integer + * Unicode codepoints. Understandably, transforming that back to + * a string would be somewhat expensive, so the function was modded to + * directly operate on the string. However, this discourages code + * reuse, and the logic enumerated here would be useful for any + * function that needs to be able to understand UTF-8 characters. + * As of right now, only smart lossless character encoding converters + * would need that, and I'm probably not going to implement them. + * Once again, PHP 6 should solve all our problems. + */ + public static function cleanUTF8($str, $force_php = false) + { + // UTF-8 validity is checked since PHP 4.3.5 + // This is an optimization: if the string is already valid UTF-8, no + // need to do PHP stuff. 99% of the time, this will be the case. + // The regexp matches the XML char production, as well as well as excluding + // non-SGML codepoints U+007F to U+009F + if (preg_match( + '/^[\x{9}\x{A}\x{D}\x{20}-\x{7E}\x{A0}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]*$/Du', + $str + )) { + return $str; + } + + $mState = 0; // cached expected number of octets after the current octet + // until the beginning of the next UTF8 character sequence + $mUcs4 = 0; // cached Unicode character + $mBytes = 1; // cached expected number of octets in the current sequence + + // original code involved an $out that was an array of Unicode + // codepoints. Instead of having to convert back into UTF-8, we've + // decided to directly append valid UTF-8 characters onto a string + // $out once they're done. $char accumulates raw bytes, while $mUcs4 + // turns into the Unicode code point, so there's some redundancy. + + $out = ''; + $char = ''; + + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $in = ord($str{$i}); + $char .= $str[$i]; // append byte to char + if (0 == $mState) { + // When mState is zero we expect either a US-ASCII character + // or a multi-octet sequence. + if (0 == (0x80 & ($in))) { + // US-ASCII, pass straight through. + if (($in <= 31 || $in == 127) && + !($in == 9 || $in == 13 || $in == 10) // save \r\t\n + ) { + // control characters, remove + } else { + $out .= $char; + } + // reset + $char = ''; + $mBytes = 1; + } elseif (0xC0 == (0xE0 & ($in))) { + // First octet of 2 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x1F) << 6; + $mState = 1; + $mBytes = 2; + } elseif (0xE0 == (0xF0 & ($in))) { + // First octet of 3 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x0F) << 12; + $mState = 2; + $mBytes = 3; + } elseif (0xF0 == (0xF8 & ($in))) { + // First octet of 4 octet sequence + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x07) << 18; + $mState = 3; + $mBytes = 4; + } elseif (0xF8 == (0xFC & ($in))) { + // First octet of 5 octet sequence. + // + // This is illegal because the encoded codepoint must be + // either: + // (a) not the shortest form or + // (b) outside the Unicode range of 0-0x10FFFF. + // Rather than trying to resynchronize, we will carry on + // until the end of the sequence and let the later error + // handling code catch it. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 0x03) << 24; + $mState = 4; + $mBytes = 5; + } elseif (0xFC == (0xFE & ($in))) { + // First octet of 6 octet sequence, see comments for 5 + // octet sequence. + $mUcs4 = ($in); + $mUcs4 = ($mUcs4 & 1) << 30; + $mState = 5; + $mBytes = 6; + } else { + // Current octet is neither in the US-ASCII range nor a + // legal first octet of a multi-octet sequence. + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // When mState is non-zero, we expect a continuation of the + // multi-octet sequence + if (0x80 == (0xC0 & ($in))) { + // Legal continuation. + $shift = ($mState - 1) * 6; + $tmp = $in; + $tmp = ($tmp & 0x0000003F) << $shift; + $mUcs4 |= $tmp; + + if (0 == --$mState) { + // End of the multi-octet sequence. mUcs4 now contains + // the final Unicode codepoint to be output + + // Check for illegal sequences and codepoints. + + // From Unicode 3.1, non-shortest form is illegal + if (((2 == $mBytes) && ($mUcs4 < 0x0080)) || + ((3 == $mBytes) && ($mUcs4 < 0x0800)) || + ((4 == $mBytes) && ($mUcs4 < 0x10000)) || + (4 < $mBytes) || + // From Unicode 3.2, surrogate characters = illegal + (($mUcs4 & 0xFFFFF800) == 0xD800) || + // Codepoints outside the Unicode range are illegal + ($mUcs4 > 0x10FFFF) + ) { + + } elseif (0xFEFF != $mUcs4 && // omit BOM + // check for valid Char unicode codepoints + ( + 0x9 == $mUcs4 || + 0xA == $mUcs4 || + 0xD == $mUcs4 || + (0x20 <= $mUcs4 && 0x7E >= $mUcs4) || + // 7F-9F is not strictly prohibited by XML, + // but it is non-SGML, and thus we don't allow it + (0xA0 <= $mUcs4 && 0xD7FF >= $mUcs4) || + (0x10000 <= $mUcs4 && 0x10FFFF >= $mUcs4) + ) + ) { + $out .= $char; + } + // initialize UTF8 cache (reset) + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char = ''; + } + } else { + // ((0xC0 & (*in) != 0x80) && (mState != 0)) + // Incomplete multi-octet sequence. + // used to result in complete fail, but we'll reset + $mState = 0; + $mUcs4 = 0; + $mBytes = 1; + $char =''; + } + } + } + return $out; + } + + /** + * Translates a Unicode codepoint into its corresponding UTF-8 character. + * @note Based on Feyd's function at + * , + * which is in public domain. + * @note While we're going to do code point parsing anyway, a good + * optimization would be to refuse to translate code points that + * are non-SGML characters. However, this could lead to duplication. + * @note This is very similar to the unichr function in + * maintenance/generate-entity-file.php (although this is superior, + * due to its sanity checks). + */ + + // +----------+----------+----------+----------+ + // | 33222222 | 22221111 | 111111 | | + // | 10987654 | 32109876 | 54321098 | 76543210 | bit + // +----------+----------+----------+----------+ + // | | | | 0xxxxxxx | 1 byte 0x00000000..0x0000007F + // | | | 110yyyyy | 10xxxxxx | 2 byte 0x00000080..0x000007FF + // | | 1110zzzz | 10yyyyyy | 10xxxxxx | 3 byte 0x00000800..0x0000FFFF + // | 11110www | 10wwzzzz | 10yyyyyy | 10xxxxxx | 4 byte 0x00010000..0x0010FFFF + // +----------+----------+----------+----------+ + // | 00000000 | 00011111 | 11111111 | 11111111 | Theoretical upper limit of legal scalars: 2097151 (0x001FFFFF) + // | 00000000 | 00010000 | 11111111 | 11111111 | Defined upper limit of legal scalar codes + // +----------+----------+----------+----------+ + + public static function unichr($code) + { + if ($code > 1114111 or $code < 0 or + ($code >= 55296 and $code <= 57343) ) { + // bits are set outside the "valid" range as defined + // by UNICODE 4.1.0 + return ''; + } + + $x = $y = $z = $w = 0; + if ($code < 128) { + // regular ASCII character + $x = $code; + } else { + // set up bits for UTF-8 + $x = ($code & 63) | 128; + if ($code < 2048) { + $y = (($code & 2047) >> 6) | 192; + } else { + $y = (($code & 4032) >> 6) | 128; + if ($code < 65536) { + $z = (($code >> 12) & 15) | 224; + } else { + $z = (($code >> 12) & 63) | 128; + $w = (($code >> 18) & 7) | 240; + } + } + } + // set up the actual character + $ret = ''; + if ($w) { + $ret .= chr($w); + } + if ($z) { + $ret .= chr($z); + } + if ($y) { + $ret .= chr($y); + } + $ret .= chr($x); + + return $ret; + } + + /** + * @return bool + */ + public static function iconvAvailable() + { + static $iconv = null; + if ($iconv === null) { + $iconv = function_exists('iconv') && self::testIconvTruncateBug() != self::ICONV_UNUSABLE; + } + return $iconv; + } + + /** + * Convert a string to UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public static function convertToUTF8($str, $config, $context) + { + $encoding = $config->get('Core.Encoding'); + if ($encoding === 'utf-8') { + return $str; + } + static $iconv = null; + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } + if ($iconv && !$config->get('Test.ForceNoIconv')) { + // unaffected by bugs, since UTF-8 support all characters + $str = self::unsafeIconv($encoding, 'utf-8//IGNORE', $str); + if ($str === false) { + // $encoding is not a valid encoding + trigger_error('Invalid encoding ' . $encoding, E_USER_ERROR); + return ''; + } + // If the string is bjorked by Shift_JIS or a similar encoding + // that doesn't support all of ASCII, convert the naughty + // characters to their true byte-wise ASCII/UTF-8 equivalents. + $str = strtr($str, self::testEncodingSupportsASCII($encoding)); + return $str; + } elseif ($encoding === 'iso-8859-1') { + $str = utf8_encode($str); + return $str; + } + $bug = HTMLPurifier_Encoder::testIconvTruncateBug(); + if ($bug == self::ICONV_OK) { + trigger_error('Encoding not supported, please install iconv', E_USER_ERROR); + } else { + trigger_error( + 'You have a buggy version of iconv, see https://bugs.php.net/bug.php?id=48147 ' . + 'and http://sourceware.org/bugzilla/show_bug.cgi?id=13541', + E_USER_ERROR + ); + } + } + + /** + * Converts a string from UTF-8 based on configuration. + * @param string $str The string to convert + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + * @note Currently, this is a lossy conversion, with unexpressable + * characters being omitted. + */ + public static function convertFromUTF8($str, $config, $context) + { + $encoding = $config->get('Core.Encoding'); + if ($escape = $config->get('Core.EscapeNonASCIICharacters')) { + $str = self::convertToASCIIDumbLossless($str); + } + if ($encoding === 'utf-8') { + return $str; + } + static $iconv = null; + if ($iconv === null) { + $iconv = self::iconvAvailable(); + } + if ($iconv && !$config->get('Test.ForceNoIconv')) { + // Undo our previous fix in convertToUTF8, otherwise iconv will barf + $ascii_fix = self::testEncodingSupportsASCII($encoding); + if (!$escape && !empty($ascii_fix)) { + $clear_fix = array(); + foreach ($ascii_fix as $utf8 => $native) { + $clear_fix[$utf8] = ''; + } + $str = strtr($str, $clear_fix); + } + $str = strtr($str, array_flip($ascii_fix)); + // Normal stuff + $str = self::iconv('utf-8', $encoding . '//IGNORE', $str); + return $str; + } elseif ($encoding === 'iso-8859-1') { + $str = utf8_decode($str); + return $str; + } + trigger_error('Encoding not supported', E_USER_ERROR); + // You might be tempted to assume that the ASCII representation + // might be OK, however, this is *not* universally true over all + // encodings. So we take the conservative route here, rather + // than forcibly turn on %Core.EscapeNonASCIICharacters + } + + /** + * Lossless (character-wise) conversion of HTML to ASCII + * @param string $str UTF-8 string to be converted to ASCII + * @return string ASCII encoded string with non-ASCII character entity-ized + * @warning Adapted from MediaWiki, claiming fair use: this is a common + * algorithm. If you disagree with this license fudgery, + * implement it yourself. + * @note Uses decimal numeric entities since they are best supported. + * @note This is a DUMB function: it has no concept of keeping + * character entities that the projected character encoding + * can allow. We could possibly implement a smart version + * but that would require it to also know which Unicode + * codepoints the charset supported (not an easy task). + * @note Sort of with cleanUTF8() but it assumes that $str is + * well-formed UTF-8 + */ + public static function convertToASCIIDumbLossless($str) + { + $bytesleft = 0; + $result = ''; + $working = 0; + $len = strlen($str); + for ($i = 0; $i < $len; $i++) { + $bytevalue = ord($str[$i]); + if ($bytevalue <= 0x7F) { //0xxx xxxx + $result .= chr($bytevalue); + $bytesleft = 0; + } elseif ($bytevalue <= 0xBF) { //10xx xxxx + $working = $working << 6; + $working += ($bytevalue & 0x3F); + $bytesleft--; + if ($bytesleft <= 0) { + $result .= "&#" . $working . ";"; + } + } elseif ($bytevalue <= 0xDF) { //110x xxxx + $working = $bytevalue & 0x1F; + $bytesleft = 1; + } elseif ($bytevalue <= 0xEF) { //1110 xxxx + $working = $bytevalue & 0x0F; + $bytesleft = 2; + } else { //1111 0xxx + $working = $bytevalue & 0x07; + $bytesleft = 3; + } + } + return $result; + } + + /** No bugs detected in iconv. */ + const ICONV_OK = 0; + + /** Iconv truncates output if converting from UTF-8 to another + * character set with //IGNORE, and a non-encodable character is found */ + const ICONV_TRUNCATES = 1; + + /** Iconv does not support //IGNORE, making it unusable for + * transcoding purposes */ + const ICONV_UNUSABLE = 2; + + /** + * glibc iconv has a known bug where it doesn't handle the magic + * //IGNORE stanza correctly. In particular, rather than ignore + * characters, it will return an EILSEQ after consuming some number + * of characters, and expect you to restart iconv as if it were + * an E2BIG. Old versions of PHP did not respect the errno, and + * returned the fragment, so as a result you would see iconv + * mysteriously truncating output. We can work around this by + * manually chopping our input into segments of about 8000 + * characters, as long as PHP ignores the error code. If PHP starts + * paying attention to the error code, iconv becomes unusable. + * + * @return int Error code indicating severity of bug. + */ + public static function testIconvTruncateBug() + { + static $code = null; + if ($code === null) { + // better not use iconv, otherwise infinite loop! + $r = self::unsafeIconv('utf-8', 'ascii//IGNORE', "\xCE\xB1" . str_repeat('a', 9000)); + if ($r === false) { + $code = self::ICONV_UNUSABLE; + } elseif (($c = strlen($r)) < 9000) { + $code = self::ICONV_TRUNCATES; + } elseif ($c > 9000) { + trigger_error( + 'Your copy of iconv is extremely buggy. Please notify HTML Purifier maintainers: ' . + 'include your iconv version as per phpversion()', + E_USER_ERROR + ); + } else { + $code = self::ICONV_OK; + } + } + return $code; + } + + /** + * This expensive function tests whether or not a given character + * encoding supports ASCII. 7/8-bit encodings like Shift_JIS will + * fail this test, and require special processing. Variable width + * encodings shouldn't ever fail. + * + * @param string $encoding Encoding name to test, as per iconv format + * @param bool $bypass Whether or not to bypass the precompiled arrays. + * @return Array of UTF-8 characters to their corresponding ASCII, + * which can be used to "undo" any overzealous iconv action. + */ + public static function testEncodingSupportsASCII($encoding, $bypass = false) + { + // All calls to iconv here are unsafe, proof by case analysis: + // If ICONV_OK, no difference. + // If ICONV_TRUNCATE, all calls involve one character inputs, + // so bug is not triggered. + // If ICONV_UNUSABLE, this call is irrelevant + static $encodings = array(); + if (!$bypass) { + if (isset($encodings[$encoding])) { + return $encodings[$encoding]; + } + $lenc = strtolower($encoding); + switch ($lenc) { + case 'shift_jis': + return array("\xC2\xA5" => '\\', "\xE2\x80\xBE" => '~'); + case 'johab': + return array("\xE2\x82\xA9" => '\\'); + } + if (strpos($lenc, 'iso-8859-') === 0) { + return array(); + } + } + $ret = array(); + if (self::unsafeIconv('UTF-8', $encoding, 'a') === false) { + return false; + } + for ($i = 0x20; $i <= 0x7E; $i++) { // all printable ASCII chars + $c = chr($i); // UTF-8 char + $r = self::unsafeIconv('UTF-8', "$encoding//IGNORE", $c); // initial conversion + if ($r === '' || + // This line is needed for iconv implementations that do not + // omit characters that do not exist in the target character set + ($r === $c && self::unsafeIconv($encoding, 'UTF-8//IGNORE', $r) !== $c) + ) { + // Reverse engineer: what's the UTF-8 equiv of this byte + // sequence? This assumes that there's no variable width + // encoding that doesn't support ASCII. + $ret[self::unsafeIconv($encoding, 'UTF-8//IGNORE', $c)] = $c; + } + } + $encodings[$encoding] = $ret; + return $ret; + } +} + + + + + +/** + * Object that provides entity lookup table from entity name to character + */ +class HTMLPurifier_EntityLookup +{ + /** + * Assoc array of entity name to character represented. + * @type array + */ + public $table; + + /** + * Sets up the entity lookup table from the serialized file contents. + * @param bool $file + * @note The serialized contents are versioned, but were generated + * using the maintenance script generate_entity_file.php + * @warning This is not in constructor to help enforce the Singleton + */ + public function setup($file = false) + { + if (!$file) { + $file = HTMLPURIFIER_PREFIX . '/HTMLPurifier/EntityLookup/entities.ser'; + } + $this->table = unserialize(file_get_contents($file)); + } + + /** + * Retrieves sole instance of the object. + * @param bool|HTMLPurifier_EntityLookup $prototype Optional prototype of custom lookup table to overload with. + * @return HTMLPurifier_EntityLookup + */ + public static function instance($prototype = false) + { + // no references, since PHP doesn't copy unless modified + static $instance = null; + if ($prototype) { + $instance = $prototype; + } elseif (!$instance) { + $instance = new HTMLPurifier_EntityLookup(); + $instance->setup(); + } + return $instance; + } +} + + + + + +// if want to implement error collecting here, we'll need to use some sort +// of global data (probably trigger_error) because it's impossible to pass +// $config or $context to the callback functions. + +/** + * Handles referencing and derefencing character entities + */ +class HTMLPurifier_EntityParser +{ + + /** + * Reference to entity lookup table. + * @type HTMLPurifier_EntityLookup + */ + protected $_entity_lookup; + + /** + * Callback regex string for parsing entities. + * @type string + */ + protected $_substituteEntitiesRegex = + '/&(?:[#]x([a-fA-F0-9]+)|[#]0*(\d+)|([A-Za-z_:][A-Za-z0-9.\-_:]*));?/'; + // 1. hex 2. dec 3. string (XML style) + + /** + * Decimal to parsed string conversion table for special entities. + * @type array + */ + protected $_special_dec2str = + array( + 34 => '"', + 38 => '&', + 39 => "'", + 60 => '<', + 62 => '>' + ); + + /** + * Stripped entity names to decimal conversion table for special entities. + * @type array + */ + protected $_special_ent2dec = + array( + 'quot' => 34, + 'amp' => 38, + 'lt' => 60, + 'gt' => 62 + ); + + /** + * Substitutes non-special entities with their parsed equivalents. Since + * running this whenever you have parsed character is t3h 5uck, we run + * it before everything else. + * + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. + */ + public function substituteNonSpecialEntities($string) + { + // it will try to detect missing semicolons, but don't rely on it + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'nonSpecialEntityCallback'), + $string + ); + } + + /** + * Callback function for substituteNonSpecialEntities() that does the work. + * + * @param array $matches PCRE matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @return string Replacement string. + */ + + protected function nonSpecialEntityCallback($matches) + { + // replaces all but big five + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $code = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + // abort for special characters + if (isset($this->_special_dec2str[$code])) { + return $entity; + } + return HTMLPurifier_Encoder::unichr($code); + } else { + if (isset($this->_special_ent2dec[$matches[3]])) { + return $entity; + } + if (!$this->_entity_lookup) { + $this->_entity_lookup = HTMLPurifier_EntityLookup::instance(); + } + if (isset($this->_entity_lookup->table[$matches[3]])) { + return $this->_entity_lookup->table[$matches[3]]; + } else { + return $entity; + } + } + } + + /** + * Substitutes only special entities with their parsed equivalents. + * + * @notice We try to avoid calling this function because otherwise, it + * would have to be called a lot (for every parsed section). + * + * @param string $string String to have non-special entities parsed. + * @return string Parsed string. + */ + public function substituteSpecialEntities($string) + { + return preg_replace_callback( + $this->_substituteEntitiesRegex, + array($this, 'specialEntityCallback'), + $string + ); + } + + /** + * Callback function for substituteSpecialEntities() that does the work. + * + * This callback has same syntax as nonSpecialEntityCallback(). + * + * @param array $matches PCRE-style matches array, with 0 the entire match, and + * either index 1, 2 or 3 set with a hex value, dec value, + * or string (respectively). + * @return string Replacement string. + */ + protected function specialEntityCallback($matches) + { + $entity = $matches[0]; + $is_num = (@$matches[0][1] === '#'); + if ($is_num) { + $is_hex = (@$entity[2] === 'x'); + $int = $is_hex ? hexdec($matches[1]) : (int) $matches[2]; + return isset($this->_special_dec2str[$int]) ? + $this->_special_dec2str[$int] : + $entity; + } else { + return isset($this->_special_ent2dec[$matches[3]]) ? + $this->_special_ent2dec[$matches[3]] : + $entity; + } + } +} + + + + + +/** + * Error collection class that enables HTML Purifier to report HTML + * problems back to the user + */ +class HTMLPurifier_ErrorCollector +{ + + /** + * Identifiers for the returned error array. These are purposely numeric + * so list() can be used. + */ + const LINENO = 0; + const SEVERITY = 1; + const MESSAGE = 2; + const CHILDREN = 3; + + /** + * @type array + */ + protected $errors; + + /** + * @type array + */ + protected $_current; + + /** + * @type array + */ + protected $_stacks = array(array()); + + /** + * @type HTMLPurifier_Language + */ + protected $locale; + + /** + * @type HTMLPurifier_Generator + */ + protected $generator; + + /** + * @type HTMLPurifier_Context + */ + protected $context; + + /** + * @type array + */ + protected $lines = array(); + + /** + * @param HTMLPurifier_Context $context + */ + public function __construct($context) + { + $this->locale =& $context->get('Locale'); + $this->context = $context; + $this->_current =& $this->_stacks[0]; + $this->errors =& $this->_stacks[0]; + } + + /** + * Sends an error message to the collector for later use + * @param int $severity Error severity, PHP error style (don't use E_USER_) + * @param string $msg Error message text + */ + public function send($severity, $msg) + { + $args = array(); + if (func_num_args() > 2) { + $args = func_get_args(); + array_shift($args); + unset($args[0]); + } + + $token = $this->context->get('CurrentToken', true); + $line = $token ? $token->line : $this->context->get('CurrentLine', true); + $col = $token ? $token->col : $this->context->get('CurrentCol', true); + $attr = $this->context->get('CurrentAttr', true); + + // perform special substitutions, also add custom parameters + $subst = array(); + if (!is_null($token)) { + $args['CurrentToken'] = $token; + } + if (!is_null($attr)) { + $subst['$CurrentAttr.Name'] = $attr; + if (isset($token->attr[$attr])) { + $subst['$CurrentAttr.Value'] = $token->attr[$attr]; + } + } + + if (empty($args)) { + $msg = $this->locale->getMessage($msg); + } else { + $msg = $this->locale->formatMessage($msg, $args); + } + + if (!empty($subst)) { + $msg = strtr($msg, $subst); + } + + // (numerically indexed) + $error = array( + self::LINENO => $line, + self::SEVERITY => $severity, + self::MESSAGE => $msg, + self::CHILDREN => array() + ); + $this->_current[] = $error; + + // NEW CODE BELOW ... + // Top-level errors are either: + // TOKEN type, if $value is set appropriately, or + // "syntax" type, if $value is null + $new_struct = new HTMLPurifier_ErrorStruct(); + $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN; + if ($token) { + $new_struct->value = clone $token; + } + if (is_int($line) && is_int($col)) { + if (isset($this->lines[$line][$col])) { + $struct = $this->lines[$line][$col]; + } else { + $struct = $this->lines[$line][$col] = $new_struct; + } + // These ksorts may present a performance problem + ksort($this->lines[$line], SORT_NUMERIC); + } else { + if (isset($this->lines[-1])) { + $struct = $this->lines[-1]; + } else { + $struct = $this->lines[-1] = $new_struct; + } + } + ksort($this->lines, SORT_NUMERIC); + + // Now, check if we need to operate on a lower structure + if (!empty($attr)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr); + if (!$struct->value) { + $struct->value = array($attr, 'PUT VALUE HERE'); + } + } + if (!empty($cssprop)) { + $struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop); + if (!$struct->value) { + // if we tokenize CSS this might be a little more difficult to do + $struct->value = array($cssprop, 'PUT VALUE HERE'); + } + } + + // Ok, structs are all setup, now time to register the error + $struct->addError($severity, $msg); + } + + /** + * Retrieves raw error data for custom formatter to use + */ + public function getRaw() + { + return $this->errors; + } + + /** + * Default HTML formatting implementation for error messages + * @param HTMLPurifier_Config $config Configuration, vital for HTML output nature + * @param array $errors Errors array to display; used for recursion. + * @return string + */ + public function getHTMLFormatted($config, $errors = null) + { + $ret = array(); + + $this->generator = new HTMLPurifier_Generator($config, $this->context); + if ($errors === null) { + $errors = $this->errors; + } + + // 'At line' message needs to be removed + + // generation code for new structure goes here. It needs to be recursive. + foreach ($this->lines as $line => $col_array) { + if ($line == -1) { + continue; + } + foreach ($col_array as $col => $struct) { + $this->_renderStruct($ret, $struct, $line, $col); + } + } + if (isset($this->lines[-1])) { + $this->_renderStruct($ret, $this->lines[-1]); + } + + if (empty($errors)) { + return '

    ' . $this->locale->getMessage('ErrorCollector: No errors') . '

    '; + } else { + return '
    • ' . implode('
    • ', $ret) . '
    '; + } + + } + + private function _renderStruct(&$ret, $struct, $line = null, $col = null) + { + $stack = array($struct); + $context_stack = array(array()); + while ($current = array_pop($stack)) { + $context = array_pop($context_stack); + foreach ($current->errors as $error) { + list($severity, $msg) = $error; + $string = ''; + $string .= '
    '; + // W3C uses an icon to indicate the severity of the error. + $error = $this->locale->getErrorName($severity); + $string .= "$error "; + if (!is_null($line) && !is_null($col)) { + $string .= "Line $line, Column $col: "; + } else { + $string .= 'End of Document: '; + } + $string .= '' . $this->generator->escape($msg) . ' '; + $string .= '
    '; + // Here, have a marker for the character on the column appropriate. + // Be sure to clip extremely long lines. + //$string .= '
    ';
    +                //$string .= '';
    +                //$string .= '
    '; + $ret[] = $string; + } + foreach ($current->children as $array) { + $context[] = $current; + $stack = array_merge($stack, array_reverse($array, true)); + for ($i = count($array); $i > 0; $i--) { + $context_stack[] = $context; + } + } + } + } +} + + + + + +/** + * Records errors for particular segments of an HTML document such as tokens, + * attributes or CSS properties. They can contain error structs (which apply + * to components of what they represent), but their main purpose is to hold + * errors applying to whatever struct is being used. + */ +class HTMLPurifier_ErrorStruct +{ + + /** + * Possible values for $children first-key. Note that top-level structures + * are automatically token-level. + */ + const TOKEN = 0; + const ATTR = 1; + const CSSPROP = 2; + + /** + * Type of this struct. + * @type string + */ + public $type; + + /** + * Value of the struct we are recording errors for. There are various + * values for this: + * - TOKEN: Instance of HTMLPurifier_Token + * - ATTR: array('attr-name', 'value') + * - CSSPROP: array('prop-name', 'value') + * @type mixed + */ + public $value; + + /** + * Errors registered for this structure. + * @type array + */ + public $errors = array(); + + /** + * Child ErrorStructs that are from this structure. For example, a TOKEN + * ErrorStruct would contain ATTR ErrorStructs. This is a multi-dimensional + * array in structure: [TYPE]['identifier'] + * @type array + */ + public $children = array(); + + /** + * @param string $type + * @param string $id + * @return mixed + */ + public function getChild($type, $id) + { + if (!isset($this->children[$type][$id])) { + $this->children[$type][$id] = new HTMLPurifier_ErrorStruct(); + $this->children[$type][$id]->type = $type; + } + return $this->children[$type][$id]; + } + + /** + * @param int $severity + * @param string $message + */ + public function addError($severity, $message) + { + $this->errors[] = array($severity, $message); + } +} + + + + + +/** + * Global exception class for HTML Purifier; any exceptions we throw + * are from here. + */ +class HTMLPurifier_Exception extends Exception +{ + +} + + + + + +/** + * Represents a pre or post processing filter on HTML Purifier's output + * + * Sometimes, a little ad-hoc fixing of HTML has to be done before + * it gets sent through HTML Purifier: you can use filters to acheive + * this effect. For instance, YouTube videos can be preserved using + * this manner. You could have used a decorator for this task, but + * PHP's support for them is not terribly robust, so we're going + * to just loop through the filters. + * + * Filters should be exited first in, last out. If there are three filters, + * named 1, 2 and 3, the order of execution should go 1->preFilter, + * 2->preFilter, 3->preFilter, purify, 3->postFilter, 2->postFilter, + * 1->postFilter. + * + * @note Methods are not declared abstract as it is perfectly legitimate + * for an implementation not to want anything to happen on a step + */ + +class HTMLPurifier_Filter +{ + + /** + * Name of the filter for identification purposes. + * @type string + */ + public $name; + + /** + * Pre-processor function, handles HTML before HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function preFilter($html, $config, $context) + { + return $html; + } + + /** + * Post-processor function, handles HTML after HTML Purifier + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function postFilter($html, $config, $context) + { + return $html; + } +} + + + + + +/** + * Generates HTML from tokens. + * @todo Refactor interface so that configuration/context is determined + * upon instantiation, no need for messy generateFromTokens() calls + * @todo Make some of the more internal functions protected, and have + * unit tests work around that + */ +class HTMLPurifier_Generator +{ + + /** + * Whether or not generator should produce XML output. + * @type bool + */ + private $_xhtml = true; + + /** + * :HACK: Whether or not generator should comment the insides of )#si', + array($this, 'scriptCallback'), + $html + ); + } + + $html = $this->normalize($html, $config, $context); + + $cursor = 0; // our location in the text + $inside_tag = false; // whether or not we're parsing the inside of a tag + $array = array(); // result array + + // This is also treated to mean maintain *column* numbers too + $maintain_line_numbers = $config->get('Core.MaintainLineNumbers'); + + if ($maintain_line_numbers === null) { + // automatically determine line numbering by checking + // if error collection is on + $maintain_line_numbers = $config->get('Core.CollectErrors'); + } + + if ($maintain_line_numbers) { + $current_line = 1; + $current_col = 0; + $length = strlen($html); + } else { + $current_line = false; + $current_col = false; + $length = false; + } + $context->register('CurrentLine', $current_line); + $context->register('CurrentCol', $current_col); + $nl = "\n"; + // how often to manually recalculate. This will ALWAYS be right, + // but it's pretty wasteful. Set to 0 to turn off + $synchronize_interval = $config->get('Core.DirectLexLineNumberSyncInterval'); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // for testing synchronization + $loops = 0; + + while (++$loops) { + // $cursor is either at the start of a token, or inside of + // a tag (i.e. there was a < immediately before it), as indicated + // by $inside_tag + + if ($maintain_line_numbers) { + // $rcursor, however, is always at the start of a token. + $rcursor = $cursor - (int)$inside_tag; + + // Column number is cheap, so we calculate it every round. + // We're interested at the *end* of the newline string, so + // we need to add strlen($nl) == 1 to $nl_pos before subtracting it + // from our "rcursor" position. + $nl_pos = strrpos($html, $nl, $rcursor - $length); + $current_col = $rcursor - (is_bool($nl_pos) ? 0 : $nl_pos + 1); + + // recalculate lines + if ($synchronize_interval && // synchronization is on + $cursor > 0 && // cursor is further than zero + $loops % $synchronize_interval === 0) { // time to synchronize! + $current_line = 1 + $this->substrCount($html, $nl, 0, $cursor); + } + } + + $position_next_lt = strpos($html, '<', $cursor); + $position_next_gt = strpos($html, '>', $cursor); + + // triggers on "asdf" but not "asdf " + // special case to set up context + if ($position_next_lt === $cursor) { + $inside_tag = true; + $cursor++; + } + + if (!$inside_tag && $position_next_lt !== false) { + // We are not inside tag and there still is another tag to parse + $token = new + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, + $cursor, + $position_next_lt - $cursor + ) + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_lt - $cursor); + } + $array[] = $token; + $cursor = $position_next_lt + 1; + $inside_tag = true; + continue; + } elseif (!$inside_tag) { + // We are not inside tag but there are no more tags + // If we're already at the end, break + if ($cursor === strlen($html)) { + break; + } + // Create Text of rest of string + $token = new + HTMLPurifier_Token_Text( + $this->parseData( + substr( + $html, + $cursor + ) + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } + $array[] = $token; + break; + } elseif ($inside_tag && $position_next_gt !== false) { + // We are in tag and it is well formed + // Grab the internals of the tag + $strlen_segment = $position_next_gt - $cursor; + + if ($strlen_segment < 1) { + // there's nothing to process! + $token = new HTMLPurifier_Token_Text('<'); + $cursor++; + continue; + } + + $segment = substr($html, $cursor, $strlen_segment); + + if ($segment === false) { + // somehow, we attempted to access beyond the end of + // the string, defense-in-depth, reported by Nate Abele + break; + } + + // Check if it's a comment + if (substr($segment, 0, 3) === '!--') { + // re-determine segment length, looking for --> + $position_comment_end = strpos($html, '-->', $cursor); + if ($position_comment_end === false) { + // uh oh, we have a comment that extends to + // infinity. Can't be helped: set comment + // end position to end of string + if ($e) { + $e->send(E_WARNING, 'Lexer: Unclosed comment'); + } + $position_comment_end = strlen($html); + $end = true; + } else { + $end = false; + } + $strlen_segment = $position_comment_end - $cursor; + $segment = substr($html, $cursor, $strlen_segment); + $token = new + HTMLPurifier_Token_Comment( + substr( + $segment, + 3, + $strlen_segment - 3 + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $strlen_segment); + } + $array[] = $token; + $cursor = $end ? $position_comment_end : $position_comment_end + 3; + $inside_tag = false; + continue; + } + + // Check if it's an end tag + $is_end_tag = (strpos($segment, '/') === 0); + if ($is_end_tag) { + $type = substr($segment, 1); + $token = new HTMLPurifier_Token_End($type); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Check leading character is alnum, if not, we may + // have accidently grabbed an emoticon. Translate into + // text and go our merry way + if (!ctype_alpha($segment[0])) { + // XML: $segment[0] !== '_' && $segment[0] !== ':' + if ($e) { + $e->send(E_NOTICE, 'Lexer: Unescaped lt'); + } + $token = new HTMLPurifier_Token_Text('<'); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + continue; + } + + // Check if it is explicitly self closing, if so, remove + // trailing slash. Remember, we could have a tag like
    , so + // any later token processing scripts must convert improperly + // classified EmptyTags from StartTags. + $is_self_closing = (strrpos($segment, '/') === $strlen_segment - 1); + if ($is_self_closing) { + $strlen_segment--; + $segment = substr($segment, 0, $strlen_segment); + } + + // Check if there are any attributes + $position_first_space = strcspn($segment, $this->_whitespace); + + if ($position_first_space >= $strlen_segment) { + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($segment); + } else { + $token = new HTMLPurifier_Token_Start($segment); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $inside_tag = false; + $cursor = $position_next_gt + 1; + continue; + } + + // Grab out all the data + $type = substr($segment, 0, $position_first_space); + $attribute_string = + trim( + substr( + $segment, + $position_first_space + ) + ); + if ($attribute_string) { + $attr = $this->parseAttributeString( + $attribute_string, + $config, + $context + ); + } else { + $attr = array(); + } + + if ($is_self_closing) { + $token = new HTMLPurifier_Token_Empty($type, $attr); + } else { + $token = new HTMLPurifier_Token_Start($type, $attr); + } + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + $current_line += $this->substrCount($html, $nl, $cursor, $position_next_gt - $cursor); + } + $array[] = $token; + $cursor = $position_next_gt + 1; + $inside_tag = false; + continue; + } else { + // inside tag, but there's no ending > sign + if ($e) { + $e->send(E_WARNING, 'Lexer: Missing gt'); + } + $token = new + HTMLPurifier_Token_Text( + '<' . + $this->parseData( + substr($html, $cursor) + ) + ); + if ($maintain_line_numbers) { + $token->rawPosition($current_line, $current_col); + } + // no cursor scroll? Hmm... + $array[] = $token; + break; + } + break; + } + + $context->destroy('CurrentLine'); + $context->destroy('CurrentCol'); + return $array; + } + + /** + * PHP 5.0.x compatible substr_count that implements offset and length + * @param string $haystack + * @param string $needle + * @param int $offset + * @param int $length + * @return int + */ + protected function substrCount($haystack, $needle, $offset, $length) + { + static $oldVersion; + if ($oldVersion === null) { + $oldVersion = version_compare(PHP_VERSION, '5.1', '<'); + } + if ($oldVersion) { + $haystack = substr($haystack, $offset, $length); + return substr_count($haystack, $needle); + } else { + return substr_count($haystack, $needle, $offset, $length); + } + } + + /** + * Takes the inside of an HTML tag and makes an assoc array of attributes. + * + * @param string $string Inside of tag excluding name. + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array Assoc array of attributes. + */ + public function parseAttributeString($string, $config, $context) + { + $string = (string)$string; // quick typecast + + if ($string == '') { + return array(); + } // no attributes + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + // let's see if we can abort as quickly as possible + // one equal sign, no spaces => one attribute + $num_equal = substr_count($string, '='); + $has_space = strpos($string, ' '); + if ($num_equal === 0 && !$has_space) { + // bool attribute + return array($string => $string); + } elseif ($num_equal === 1 && !$has_space) { + // only one attribute + list($key, $quoted_value) = explode('=', $string); + $quoted_value = trim($quoted_value); + if (!$key) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + return array(); + } + if (!$quoted_value) { + return array($key => ''); + } + $first_char = @$quoted_value[0]; + $last_char = @$quoted_value[strlen($quoted_value) - 1]; + + $same_quote = ($first_char == $last_char); + $open_quote = ($first_char == '"' || $first_char == "'"); + + if ($same_quote && $open_quote) { + // well behaved + $value = substr($quoted_value, 1, strlen($quoted_value) - 2); + } else { + // not well behaved + if ($open_quote) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing end quote'); + } + $value = substr($quoted_value, 1); + } else { + $value = $quoted_value; + } + } + if ($value === false) { + $value = ''; + } + return array($key => $this->parseData($value)); + } + + // setup loop environment + $array = array(); // return assoc array of attributes + $cursor = 0; // current position in string (moves forward) + $size = strlen($string); // size of the string (stays the same) + + // if we have unquoted attributes, the parser expects a terminating + // space, so let's guarantee that there's always a terminating space. + $string .= ' '; + + $old_cursor = -1; + while ($cursor < $size) { + if ($old_cursor >= $cursor) { + throw new Exception("Infinite loop detected"); + } + $old_cursor = $cursor; + + $cursor += ($value = strspn($string, $this->_whitespace, $cursor)); + // grab the key + + $key_begin = $cursor; //we're currently at the start of the key + + // scroll past all characters that are the key (not whitespace or =) + $cursor += strcspn($string, $this->_whitespace . '=', $cursor); + + $key_end = $cursor; // now at the end of the key + + $key = substr($string, $key_begin, $key_end - $key_begin); + + if (!$key) { + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + $cursor += 1 + strcspn($string, $this->_whitespace, $cursor + 1); // prevent infinite loop + continue; // empty key + } + + // scroll past all whitespace + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor >= $size) { + $array[$key] = $key; + break; + } + + // if the next character is an equal sign, we've got a regular + // pair, otherwise, it's a bool attribute + $first_char = @$string[$cursor]; + + if ($first_char == '=') { + // key="value" + + $cursor++; + $cursor += strspn($string, $this->_whitespace, $cursor); + + if ($cursor === false) { + $array[$key] = ''; + break; + } + + // we might be in front of a quote right now + + $char = @$string[$cursor]; + + if ($char == '"' || $char == "'") { + // it's quoted, end bound is $char + $cursor++; + $value_begin = $cursor; + $cursor = strpos($string, $char, $cursor); + $value_end = $cursor; + } else { + // it's not quoted, end bound is whitespace + $value_begin = $cursor; + $cursor += strcspn($string, $this->_whitespace, $cursor); + $value_end = $cursor; + } + + // we reached a premature end + if ($cursor === false) { + $cursor = $size; + $value_end = $cursor; + } + + $value = substr($string, $value_begin, $value_end - $value_begin); + if ($value === false) { + $value = ''; + } + $array[$key] = $this->parseData($value); + $cursor++; + } else { + // boolattr + if ($key !== '') { + $array[$key] = $key; + } else { + // purely theoretical + if ($e) { + $e->send(E_ERROR, 'Lexer: Missing attribute key'); + } + } + } + } + return $array; + } +} + + + + + +/** + * Concrete comment node class. + */ +class HTMLPurifier_Node_Comment extends HTMLPurifier_Node +{ + /** + * Character data within comment. + * @type string + */ + public $data; + + /** + * @type bool + */ + public $is_whitespace = true; + + /** + * Transparent constructor. + * + * @param string $data String comment data. + * @param int $line + * @param int $col + */ + public function __construct($data, $line = null, $col = null) + { + $this->data = $data; + $this->line = $line; + $this->col = $col; + } + + public function toTokenPair() { + return array(new HTMLPurifier_Token_Comment($this->data, $this->line, $this->col), null); + } +} + + + +/** + * Concrete element node class. + */ +class HTMLPurifier_Node_Element extends HTMLPurifier_Node +{ + /** + * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. + * + * @note Strictly speaking, XML tags are case sensitive, so we shouldn't + * be lower-casing them, but these tokens cater to HTML tags, which are + * insensitive. + * @type string + */ + public $name; + + /** + * Associative array of the node's attributes. + * @type array + */ + public $attr = array(); + + /** + * List of child elements. + * @type array + */ + public $children = array(); + + /** + * Does this use the form or the form, i.e. + * is it a pair of start/end tokens or an empty token. + * @bool + */ + public $empty = false; + + public $endCol = null, $endLine = null, $endArmor = array(); + + public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) { + $this->name = $name; + $this->attr = $attr; + $this->line = $line; + $this->col = $col; + $this->armor = $armor; + } + + public function toTokenPair() { + // XXX inefficiency here, normalization is not necessary + if ($this->empty) { + return array(new HTMLPurifier_Token_Empty($this->name, $this->attr, $this->line, $this->col, $this->armor), null); + } else { + $start = new HTMLPurifier_Token_Start($this->name, $this->attr, $this->line, $this->col, $this->armor); + $end = new HTMLPurifier_Token_End($this->name, array(), $this->endLine, $this->endCol, $this->endArmor); + //$end->start = $start; + return array($start, $end); + } + } +} + + + + +/** + * Concrete text token class. + * + * Text tokens comprise of regular parsed character data (PCDATA) and raw + * character data (from the CDATA sections). Internally, their + * data is parsed with all entities expanded. Surprisingly, the text token + * does have a "tag name" called #PCDATA, which is how the DTD represents it + * in permissible child nodes. + */ +class HTMLPurifier_Node_Text extends HTMLPurifier_Node +{ + + /** + * PCDATA tag name compatible with DTD, see + * HTMLPurifier_ChildDef_Custom for details. + * @type string + */ + public $name = '#PCDATA'; + + /** + * @type string + */ + public $data; + /**< Parsed character data of text. */ + + /** + * @type bool + */ + public $is_whitespace; + + /**< Bool indicating if node is whitespace. */ + + /** + * Constructor, accepts data and determines if it is whitespace. + * @param string $data String parsed character data. + * @param int $line + * @param int $col + */ + public function __construct($data, $is_whitespace, $line = null, $col = null) + { + $this->data = $data; + $this->is_whitespace = $is_whitespace; + $this->line = $line; + $this->col = $col; + } + + public function toTokenPair() { + return array(new HTMLPurifier_Token_Text($this->data, $this->line, $this->col), null); + } +} + + + + + +/** + * Composite strategy that runs multiple strategies on tokens. + */ +abstract class HTMLPurifier_Strategy_Composite extends HTMLPurifier_Strategy +{ + + /** + * List of strategies to run tokens through. + * @type HTMLPurifier_Strategy[] + */ + protected $strategies = array(); + + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { + foreach ($this->strategies as $strategy) { + $tokens = $strategy->execute($tokens, $config, $context); + } + return $tokens; + } +} + + + + + +/** + * Core strategy composed of the big four strategies. + */ +class HTMLPurifier_Strategy_Core extends HTMLPurifier_Strategy_Composite +{ + public function __construct() + { + $this->strategies[] = new HTMLPurifier_Strategy_RemoveForeignElements(); + $this->strategies[] = new HTMLPurifier_Strategy_MakeWellFormed(); + $this->strategies[] = new HTMLPurifier_Strategy_FixNesting(); + $this->strategies[] = new HTMLPurifier_Strategy_ValidateAttributes(); + } +} + + + + + +/** + * Takes a well formed list of tokens and fixes their nesting. + * + * HTML elements dictate which elements are allowed to be their children, + * for example, you can't have a p tag in a span tag. Other elements have + * much more rigorous definitions: tables, for instance, require a specific + * order for their elements. There are also constraints not expressible by + * document type definitions, such as the chameleon nature of ins/del + * tags and global child exclusions. + * + * The first major objective of this strategy is to iterate through all + * the nodes and determine whether or not their children conform to the + * element's definition. If they do not, the child definition may + * optionally supply an amended list of elements that is valid or + * require that the entire node be deleted (and the previous node + * rescanned). + * + * The second objective is to ensure that explicitly excluded elements of + * an element do not appear in its children. Code that accomplishes this + * task is pervasive through the strategy, though the two are distinct tasks + * and could, theoretically, be seperated (although it's not recommended). + * + * @note Whether or not unrecognized children are silently dropped or + * translated into text depends on the child definitions. + * + * @todo Enable nodes to be bubbled out of the structure. This is + * easier with our new algorithm. + */ + +class HTMLPurifier_Strategy_FixNesting extends HTMLPurifier_Strategy +{ + + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array|HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { + + //####################################################################// + // Pre-processing + + // O(n) pass to convert to a tree, so that we can efficiently + // refer to substrings + $top_node = HTMLPurifier_Arborize::arborize($tokens, $config, $context); + + // get a copy of the HTML definition + $definition = $config->getHTMLDefinition(); + + $excludes_enabled = !$config->get('Core.DisableExcludes'); + + // setup the context variable 'IsInline', for chameleon processing + // is 'false' when we are not inline, 'true' when it must always + // be inline, and an integer when it is inline for a certain + // branch of the document tree + $is_inline = $definition->info_parent_def->descendants_are_inline; + $context->register('IsInline', $is_inline); + + // setup error collector + $e =& $context->get('ErrorCollector', true); + + //####################################################################// + // Loop initialization + + // stack that contains all elements that are excluded + // it is organized by parent elements, similar to $stack, + // but it is only populated when an element with exclusions is + // processed, i.e. there won't be empty exclusions. + $exclude_stack = array($definition->info_parent_def->excludes); + + // variable that contains the start token while we are processing + // nodes. This enables error reporting to do its job + $node = $top_node; + // dummy token + list($token, $d) = $node->toTokenPair(); + $context->register('CurrentNode', $node); + $context->register('CurrentToken', $token); + + //####################################################################// + // Loop + + // We need to implement a post-order traversal iteratively, to + // avoid running into stack space limits. This is pretty tricky + // to reason about, so we just manually stack-ify the recursive + // variant: + // + // function f($node) { + // foreach ($node->children as $child) { + // f($child); + // } + // validate($node); + // } + // + // Thus, we will represent a stack frame as array($node, + // $is_inline, stack of children) + // e.g. array_reverse($node->children) - already processed + // children. + + $parent_def = $definition->info_parent_def; + $stack = array( + array($top_node, + $parent_def->descendants_are_inline, + $parent_def->excludes, // exclusions + 0) + ); + + while (!empty($stack)) { + list($node, $is_inline, $excludes, $ix) = array_pop($stack); + // recursive call + $go = false; + $def = empty($stack) ? $definition->info_parent_def : $definition->info[$node->name]; + while (isset($node->children[$ix])) { + $child = $node->children[$ix++]; + if ($child instanceof HTMLPurifier_Node_Element) { + $go = true; + $stack[] = array($node, $is_inline, $excludes, $ix); + $stack[] = array($child, + // ToDo: I don't think it matters if it's def or + // child_def, but double check this... + $is_inline || $def->descendants_are_inline, + empty($def->excludes) ? $excludes + : array_merge($excludes, $def->excludes), + 0); + break; + } + }; + if ($go) continue; + list($token, $d) = $node->toTokenPair(); + // base case + if ($excludes_enabled && isset($excludes[$node->name])) { + $node->dead = true; + if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node excluded'); + } else { + // XXX I suppose it would be slightly more efficient to + // avoid the allocation here and have children + // strategies handle it + $children = array(); + foreach ($node->children as $child) { + if (!$child->dead) $children[] = $child; + } + $result = $def->child->validateChildren($children, $config, $context); + if ($result === true) { + // nop + $node->children = $children; + } elseif ($result === false) { + $node->dead = true; + if ($e) $e->send(E_ERROR, 'Strategy_FixNesting: Node removed'); + } else { + $node->children = $result; + if ($e) { + // XXX This will miss mutations of internal nodes. Perhaps defer to the child validators + if (empty($result) && !empty($children)) { + $e->send(E_ERROR, 'Strategy_FixNesting: Node contents removed'); + } else if ($result != $children) { + $e->send(E_WARNING, 'Strategy_FixNesting: Node reorganized'); + } + } + } + } + } + + //####################################################################// + // Post-processing + + // remove context variables + $context->destroy('IsInline'); + $context->destroy('CurrentNode'); + $context->destroy('CurrentToken'); + + //####################################################################// + // Return + + return HTMLPurifier_Arborize::flatten($node, $config, $context); + } +} + + + + + +/** + * Takes tokens makes them well-formed (balance end tags, etc.) + * + * Specification of the armor attributes this strategy uses: + * + * - MakeWellFormed_TagClosedError: This armor field is used to + * suppress tag closed errors for certain tokens [TagClosedSuppress], + * in particular, if a tag was generated automatically by HTML + * Purifier, we may rely on our infrastructure to close it for us + * and shouldn't report an error to the user [TagClosedAuto]. + */ +class HTMLPurifier_Strategy_MakeWellFormed extends HTMLPurifier_Strategy +{ + + /** + * Array stream of tokens being processed. + * @type HTMLPurifier_Token[] + */ + protected $tokens; + + /** + * Current token. + * @type HTMLPurifier_Token + */ + protected $token; + + /** + * Zipper managing the true state. + * @type HTMLPurifier_Zipper + */ + protected $zipper; + + /** + * Current nesting of elements. + * @type array + */ + protected $stack; + + /** + * Injectors active in this stream processing. + * @type HTMLPurifier_Injector[] + */ + protected $injectors; + + /** + * Current instance of HTMLPurifier_Config. + * @type HTMLPurifier_Config + */ + protected $config; + + /** + * Current instance of HTMLPurifier_Context. + * @type HTMLPurifier_Context + */ + protected $context; + + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + * @throws HTMLPurifier_Exception + */ + public function execute($tokens, $config, $context) + { + $definition = $config->getHTMLDefinition(); + + // local variables + $generator = new HTMLPurifier_Generator($config, $context); + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + // used for autoclose early abortion + $global_parent_allowed_elements = $definition->info_parent_def->child->getAllowedElements($config); + $e = $context->get('ErrorCollector', true); + $i = false; // injector index + list($zipper, $token) = HTMLPurifier_Zipper::fromArray($tokens); + if ($token === NULL) { + return array(); + } + $reprocess = false; // whether or not to reprocess the same token + $stack = array(); + + // member variables + $this->stack =& $stack; + $this->tokens =& $tokens; + $this->token =& $token; + $this->zipper =& $zipper; + $this->config = $config; + $this->context = $context; + + // context variables + $context->register('CurrentNesting', $stack); + $context->register('InputZipper', $zipper); + $context->register('CurrentToken', $token); + + // -- begin INJECTOR -- + + $this->injectors = array(); + + $injectors = $config->getBatch('AutoFormat'); + $def_injectors = $definition->info_injector; + $custom_injectors = $injectors['Custom']; + unset($injectors['Custom']); // special case + foreach ($injectors as $injector => $b) { + // XXX: Fix with a legitimate lookup table of enabled filters + if (strpos($injector, '.') !== false) { + continue; + } + $injector = "HTMLPurifier_Injector_$injector"; + if (!$b) { + continue; + } + $this->injectors[] = new $injector; + } + foreach ($def_injectors as $injector) { + // assumed to be objects + $this->injectors[] = $injector; + } + foreach ($custom_injectors as $injector) { + if (!$injector) { + continue; + } + if (is_string($injector)) { + $injector = "HTMLPurifier_Injector_$injector"; + $injector = new $injector; + } + $this->injectors[] = $injector; + } + + // give the injectors references to the definition and context + // variables for performance reasons + foreach ($this->injectors as $ix => $injector) { + $error = $injector->prepare($config, $context); + if (!$error) { + continue; + } + array_splice($this->injectors, $ix, 1); // rm the injector + trigger_error("Cannot enable {$injector->name} injector because $error is not allowed", E_USER_WARNING); + } + + // -- end INJECTOR -- + + // a note on reprocessing: + // In order to reduce code duplication, whenever some code needs + // to make HTML changes in order to make things "correct", the + // new HTML gets sent through the purifier, regardless of its + // status. This means that if we add a start token, because it + // was totally necessary, we don't have to update nesting; we just + // punt ($reprocess = true; continue;) and it does that for us. + + // isset is in loop because $tokens size changes during loop exec + for (;; + // only increment if we don't need to reprocess + $reprocess ? $reprocess = false : $token = $zipper->next($token)) { + + // check for a rewind + if (is_int($i)) { + // possibility: disable rewinding if the current token has a + // rewind set on it already. This would offer protection from + // infinite loop, but might hinder some advanced rewinding. + $rewind_offset = $this->injectors[$i]->getRewindOffset(); + if (is_int($rewind_offset)) { + for ($j = 0; $j < $rewind_offset; $j++) { + if (empty($zipper->front)) break; + $token = $zipper->prev($token); + // indicate that other injectors should not process this token, + // but we need to reprocess it + unset($token->skip[$i]); + $token->rewind = $i; + if ($token instanceof HTMLPurifier_Token_Start) { + array_pop($this->stack); + } elseif ($token instanceof HTMLPurifier_Token_End) { + $this->stack[] = $token->start; + } + } + } + $i = false; + } + + // handle case of document end + if ($token === NULL) { + // kill processing if stack is empty + if (empty($this->stack)) { + break; + } + + // peek + $top_nesting = array_pop($this->stack); + $this->stack[] = $top_nesting; + + // send error [TagClosedSuppress] + if ($e && !isset($top_nesting->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by document end', $top_nesting); + } + + // append, don't splice, since this is the end + $token = new HTMLPurifier_Token_End($top_nesting->name); + + // punt! + $reprocess = true; + continue; + } + + //echo '
    '; printZipper($zipper, $token);//printTokens($this->stack); + //flush(); + + // quick-check: if it's not a tag, no need to process + if (empty($token->is_tag)) { + if ($token instanceof HTMLPurifier_Token_Text) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + // XXX fuckup + $r = $token; + $injector->handleText($r); + $token = $this->processToken($r, $i); + $reprocess = true; + break; + } + } + // another possibility is a comment + continue; + } + + if (isset($definition->info[$token->name])) { + $type = $definition->info[$token->name]->child->type; + } else { + $type = false; // Type is unknown, treat accordingly + } + + // quick tag checks: anything that's *not* an end tag + $ok = false; + if ($type === 'empty' && $token instanceof HTMLPurifier_Token_Start) { + // claims to be a start tag but is empty + $token = new HTMLPurifier_Token_Empty( + $token->name, + $token->attr, + $token->line, + $token->col, + $token->armor + ); + $ok = true; + } elseif ($type && $type !== 'empty' && $token instanceof HTMLPurifier_Token_Empty) { + // claims to be empty but really is a start tag + // NB: this assignment is required + $old_token = $token; + $token = new HTMLPurifier_Token_End($token->name); + $token = $this->insertBefore( + new HTMLPurifier_Token_Start($old_token->name, $old_token->attr, $old_token->line, $old_token->col, $old_token->armor) + ); + // punt (since we had to modify the input stream in a non-trivial way) + $reprocess = true; + continue; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // real empty token + $ok = true; + } elseif ($token instanceof HTMLPurifier_Token_Start) { + // start tag + + // ...unless they also have to close their parent + if (!empty($this->stack)) { + + // Performance note: you might think that it's rather + // inefficient, recalculating the autoclose information + // for every tag that a token closes (since when we + // do an autoclose, we push a new token into the + // stream and then /process/ that, before + // re-processing this token.) But this is + // necessary, because an injector can make an + // arbitrary transformations to the autoclosing + // tokens we introduce, so things may have changed + // in the meantime. Also, doing the inefficient thing is + // "easy" to reason about (for certain perverse definitions + // of "easy") + + $parent = array_pop($this->stack); + $this->stack[] = $parent; + + $parent_def = null; + $parent_elements = null; + $autoclose = false; + if (isset($definition->info[$parent->name])) { + $parent_def = $definition->info[$parent->name]; + $parent_elements = $parent_def->child->getAllowedElements($config); + $autoclose = !isset($parent_elements[$token->name]); + } + + if ($autoclose && $definition->info[$token->name]->wrap) { + // Check if an element can be wrapped by another + // element to make it valid in a context (for + // example,
        needs a
      • in between) + $wrapname = $definition->info[$token->name]->wrap; + $wrapdef = $definition->info[$wrapname]; + $elements = $wrapdef->child->getAllowedElements($config); + if (isset($elements[$token->name]) && isset($parent_elements[$wrapname])) { + $newtoken = new HTMLPurifier_Token_Start($wrapname); + $token = $this->insertBefore($newtoken); + $reprocess = true; + continue; + } + } + + $carryover = false; + if ($autoclose && $parent_def->formatting) { + $carryover = true; + } + + if ($autoclose) { + // check if this autoclose is doomed to fail + // (this rechecks $parent, which his harmless) + $autoclose_ok = isset($global_parent_allowed_elements[$token->name]); + if (!$autoclose_ok) { + foreach ($this->stack as $ancestor) { + $elements = $definition->info[$ancestor->name]->child->getAllowedElements($config); + if (isset($elements[$token->name])) { + $autoclose_ok = true; + break; + } + if ($definition->info[$token->name]->wrap) { + $wrapname = $definition->info[$token->name]->wrap; + $wrapdef = $definition->info[$wrapname]; + $wrap_elements = $wrapdef->child->getAllowedElements($config); + if (isset($wrap_elements[$token->name]) && isset($elements[$wrapname])) { + $autoclose_ok = true; + break; + } + } + } + } + if ($autoclose_ok) { + // errors need to be updated + $new_token = new HTMLPurifier_Token_End($parent->name); + $new_token->start = $parent; + // [TagClosedSuppress] + if ($e && !isset($parent->armor['MakeWellFormed_TagClosedError'])) { + if (!$carryover) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag auto closed', $parent); + } else { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag carryover', $parent); + } + } + if ($carryover) { + $element = clone $parent; + // [TagClosedAuto] + $element->armor['MakeWellFormed_TagClosedError'] = true; + $element->carryover = true; + $token = $this->processToken(array($new_token, $token, $element)); + } else { + $token = $this->insertBefore($new_token); + } + } else { + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + } + $ok = true; + } + + if ($ok) { + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + $r = $token; + $injector->handleElement($r); + $token = $this->processToken($r, $i); + $reprocess = true; + break; + } + if (!$reprocess) { + // ah, nothing interesting happened; do normal processing + if ($token instanceof HTMLPurifier_Token_Start) { + $this->stack[] = $token; + } elseif ($token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception( + 'Improper handling of end tag in start code; possible error in MakeWellFormed' + ); + } + } + continue; + } + + // sanity check: we should be dealing with a closing tag + if (!$token instanceof HTMLPurifier_Token_End) { + throw new HTMLPurifier_Exception('Unaccounted for tag token in input stream, bug in HTML Purifier'); + } + + // make sure that we have something open + if (empty($this->stack)) { + if ($escape_invalid_tags) { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag to text'); + } + $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); + } else { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Unnecessary end tag removed'); + } + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + // first, check for the simplest case: everything closes neatly. + // Eventually, everything passes through here; if there are problems + // we modify the input stream accordingly and then punt, so that + // the tokens get processed again. + $current_parent = array_pop($this->stack); + if ($current_parent->name == $token->name) { + $token->start = $current_parent; + foreach ($this->injectors as $i => $injector) { + if (isset($token->skip[$i])) { + continue; + } + if ($token->rewind !== null && $token->rewind !== $i) { + continue; + } + $r = $token; + $injector->handleEnd($r); + $token = $this->processToken($r, $i); + $this->stack[] = $current_parent; + $reprocess = true; + break; + } + continue; + } + + // okay, so we're trying to close the wrong tag + + // undo the pop previous pop + $this->stack[] = $current_parent; + + // scroll back the entire nest, trying to find our tag. + // (feature could be to specify how far you'd like to go) + $size = count($this->stack); + // -2 because -1 is the last element, but we already checked that + $skipped_tags = false; + for ($j = $size - 2; $j >= 0; $j--) { + if ($this->stack[$j]->name == $token->name) { + $skipped_tags = array_slice($this->stack, $j); + break; + } + } + + // we didn't find the tag, so remove + if ($skipped_tags === false) { + if ($escape_invalid_tags) { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag to text'); + } + $token = new HTMLPurifier_Token_Text($generator->generateFromToken($token)); + } else { + if ($e) { + $e->send(E_WARNING, 'Strategy_MakeWellFormed: Stray end tag removed'); + } + $token = $this->remove(); + } + $reprocess = true; + continue; + } + + // do errors, in REVERSE $j order: a,b,c with + $c = count($skipped_tags); + if ($e) { + for ($j = $c - 1; $j > 0; $j--) { + // notice we exclude $j == 0, i.e. the current ending tag, from + // the errors... [TagClosedSuppress] + if (!isset($skipped_tags[$j]->armor['MakeWellFormed_TagClosedError'])) { + $e->send(E_NOTICE, 'Strategy_MakeWellFormed: Tag closed by element end', $skipped_tags[$j]); + } + } + } + + // insert tags, in FORWARD $j order: c,b,a with + $replace = array($token); + for ($j = 1; $j < $c; $j++) { + // ...as well as from the insertions + $new_token = new HTMLPurifier_Token_End($skipped_tags[$j]->name); + $new_token->start = $skipped_tags[$j]; + array_unshift($replace, $new_token); + if (isset($definition->info[$new_token->name]) && $definition->info[$new_token->name]->formatting) { + // [TagClosedAuto] + $element = clone $skipped_tags[$j]; + $element->carryover = true; + $element->armor['MakeWellFormed_TagClosedError'] = true; + $replace[] = $element; + } + } + $token = $this->processToken($replace); + $reprocess = true; + continue; + } + + $context->destroy('CurrentToken'); + $context->destroy('CurrentNesting'); + $context->destroy('InputZipper'); + + unset($this->injectors, $this->stack, $this->tokens); + return $zipper->toArray($token); + } + + /** + * Processes arbitrary token values for complicated substitution patterns. + * In general: + * + * If $token is an array, it is a list of tokens to substitute for the + * current token. These tokens then get individually processed. If there + * is a leading integer in the list, that integer determines how many + * tokens from the stream should be removed. + * + * If $token is a regular token, it is swapped with the current token. + * + * If $token is false, the current token is deleted. + * + * If $token is an integer, that number of tokens (with the first token + * being the current one) will be deleted. + * + * @param HTMLPurifier_Token|array|int|bool $token Token substitution value + * @param HTMLPurifier_Injector|int $injector Injector that performed the substitution; default is if + * this is not an injector related operation. + * @throws HTMLPurifier_Exception + */ + protected function processToken($token, $injector = -1) + { + // normalize forms of token + if (is_object($token)) { + $token = array(1, $token); + } + if (is_int($token)) { + $token = array($token); + } + if ($token === false) { + $token = array(1); + } + if (!is_array($token)) { + throw new HTMLPurifier_Exception('Invalid token type from injector'); + } + if (!is_int($token[0])) { + array_unshift($token, 1); + } + if ($token[0] === 0) { + throw new HTMLPurifier_Exception('Deleting zero tokens is not valid'); + } + + // $token is now an array with the following form: + // array(number nodes to delete, new node 1, new node 2, ...) + + $delete = array_shift($token); + list($old, $r) = $this->zipper->splice($this->token, $delete, $token); + + if ($injector > -1) { + // determine appropriate skips + $oldskip = isset($old[0]) ? $old[0]->skip : array(); + foreach ($token as $object) { + $object->skip = $oldskip; + $object->skip[$injector] = true; + } + } + + return $r; + + } + + /** + * Inserts a token before the current token. Cursor now points to + * this token. You must reprocess after this. + * @param HTMLPurifier_Token $token + */ + private function insertBefore($token) + { + // NB not $this->zipper->insertBefore(), due to positioning + // differences + $splice = $this->zipper->splice($this->token, 0, array($token)); + + return $splice[1]; + } + + /** + * Removes current token. Cursor now points to new token occupying previously + * occupied space. You must reprocess after this. + */ + private function remove() + { + return $this->zipper->delete(); + } +} + + + + + +/** + * Removes all unrecognized tags from the list of tokens. + * + * This strategy iterates through all the tokens and removes unrecognized + * tokens. If a token is not recognized but a TagTransform is defined for + * that element, the element will be transformed accordingly. + */ + +class HTMLPurifier_Strategy_RemoveForeignElements extends HTMLPurifier_Strategy +{ + + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return array|HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { + $definition = $config->getHTMLDefinition(); + $generator = new HTMLPurifier_Generator($config, $context); + $result = array(); + + $escape_invalid_tags = $config->get('Core.EscapeInvalidTags'); + $remove_invalid_img = $config->get('Core.RemoveInvalidImg'); + + // currently only used to determine if comments should be kept + $trusted = $config->get('HTML.Trusted'); + $comment_lookup = $config->get('HTML.AllowedComments'); + $comment_regexp = $config->get('HTML.AllowedCommentsRegexp'); + $check_comments = $comment_lookup !== array() || $comment_regexp !== null; + + $remove_script_contents = $config->get('Core.RemoveScriptContents'); + $hidden_elements = $config->get('Core.HiddenElements'); + + // remove script contents compatibility + if ($remove_script_contents === true) { + $hidden_elements['script'] = true; + } elseif ($remove_script_contents === false && isset($hidden_elements['script'])) { + unset($hidden_elements['script']); + } + + $attr_validator = new HTMLPurifier_AttrValidator(); + + // removes tokens until it reaches a closing tag with its value + $remove_until = false; + + // converts comments into text tokens when this is equal to a tag name + $textify_comments = false; + + $token = false; + $context->register('CurrentToken', $token); + + $e = false; + if ($config->get('Core.CollectErrors')) { + $e =& $context->get('ErrorCollector'); + } + + foreach ($tokens as $token) { + if ($remove_until) { + if (empty($token->is_tag) || $token->name !== $remove_until) { + continue; + } + } + if (!empty($token->is_tag)) { + // DEFINITION CALL + + // before any processing, try to transform the element + if (isset($definition->info_tag_transform[$token->name])) { + $original_name = $token->name; + // there is a transformation for this tag + // DEFINITION CALL + $token = $definition-> + info_tag_transform[$token->name]->transform($token, $config, $context); + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Tag transform', $original_name); + } + } + + if (isset($definition->info[$token->name])) { + // mostly everything's good, but + // we need to make sure required attributes are in order + if (($token instanceof HTMLPurifier_Token_Start || $token instanceof HTMLPurifier_Token_Empty) && + $definition->info[$token->name]->required_attr && + ($token->name != 'img' || $remove_invalid_img) // ensure config option still works + ) { + $attr_validator->validateToken($token, $config, $context); + $ok = true; + foreach ($definition->info[$token->name]->required_attr as $name) { + if (!isset($token->attr[$name])) { + $ok = false; + break; + } + } + if (!$ok) { + if ($e) { + $e->send( + E_ERROR, + 'Strategy_RemoveForeignElements: Missing required attribute', + $name + ); + } + continue; + } + $token->armor['ValidateAttributes'] = true; + } + + if (isset($hidden_elements[$token->name]) && $token instanceof HTMLPurifier_Token_Start) { + $textify_comments = $token->name; + } elseif ($token->name === $textify_comments && $token instanceof HTMLPurifier_Token_End) { + $textify_comments = false; + } + + } elseif ($escape_invalid_tags) { + // invalid tag, generate HTML representation and insert in + if ($e) { + $e->send(E_WARNING, 'Strategy_RemoveForeignElements: Foreign element to text'); + } + $token = new HTMLPurifier_Token_Text( + $generator->generateFromToken($token) + ); + } else { + // check if we need to destroy all of the tag's children + // CAN BE GENERICIZED + if (isset($hidden_elements[$token->name])) { + if ($token instanceof HTMLPurifier_Token_Start) { + $remove_until = $token->name; + } elseif ($token instanceof HTMLPurifier_Token_Empty) { + // do nothing: we're still looking + } else { + $remove_until = false; + } + if ($e) { + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign meta element removed'); + } + } else { + if ($e) { + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Foreign element removed'); + } + } + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Comment) { + // textify comments in script tags when they are allowed + if ($textify_comments !== false) { + $data = $token->data; + $token = new HTMLPurifier_Token_Text($data); + } elseif ($trusted || $check_comments) { + // always cleanup comments + $trailing_hyphen = false; + if ($e) { + // perform check whether or not there's a trailing hyphen + if (substr($token->data, -1) == '-') { + $trailing_hyphen = true; + } + } + $token->data = rtrim($token->data, '-'); + $found_double_hyphen = false; + while (strpos($token->data, '--') !== false) { + $found_double_hyphen = true; + $token->data = str_replace('--', '-', $token->data); + } + if ($trusted || !empty($comment_lookup[trim($token->data)]) || + ($comment_regexp !== null && preg_match($comment_regexp, trim($token->data)))) { + // OK good + if ($e) { + if ($trailing_hyphen) { + $e->send( + E_NOTICE, + 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' + ); + } + if ($found_double_hyphen) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Hyphens in comment collapsed'); + } + } + } else { + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); + } + continue; + } + } else { + // strip comments + if ($e) { + $e->send(E_NOTICE, 'Strategy_RemoveForeignElements: Comment removed'); + } + continue; + } + } elseif ($token instanceof HTMLPurifier_Token_Text) { + } else { + continue; + } + $result[] = $token; + } + if ($remove_until && $e) { + // we removed tokens until the end, throw error + $e->send(E_ERROR, 'Strategy_RemoveForeignElements: Token removed to end', $remove_until); + } + $context->destroy('CurrentToken'); + return $result; + } +} + + + + + +/** + * Validate all attributes in the tokens. + */ + +class HTMLPurifier_Strategy_ValidateAttributes extends HTMLPurifier_Strategy +{ + + /** + * @param HTMLPurifier_Token[] $tokens + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token[] + */ + public function execute($tokens, $config, $context) + { + // setup validator + $validator = new HTMLPurifier_AttrValidator(); + + $token = false; + $context->register('CurrentToken', $token); + + foreach ($tokens as $key => $token) { + + // only process tokens that have attributes, + // namely start and empty tags + if (!$token instanceof HTMLPurifier_Token_Start && !$token instanceof HTMLPurifier_Token_Empty) { + continue; + } + + // skip tokens that are armored + if (!empty($token->armor['ValidateAttributes'])) { + continue; + } + + // note that we have no facilities here for removing tokens + $validator->validateToken($token, $config, $context); + } + $context->destroy('CurrentToken'); + return $tokens; + } +} + + + + + +/** + * Transforms FONT tags to the proper form (SPAN with CSS styling) + * + * This transformation takes the three proprietary attributes of FONT and + * transforms them into their corresponding CSS attributes. These are color, + * face, and size. + * + * @note Size is an interesting case because it doesn't map cleanly to CSS. + * Thanks to + * http://style.cleverchimp.com/font_size_intervals/altintervals.html + * for reasonable mappings. + * @warning This doesn't work completely correctly; specifically, this + * TagTransform operates before well-formedness is enforced, so + * the "active formatting elements" algorithm doesn't get applied. + */ +class HTMLPurifier_TagTransform_Font extends HTMLPurifier_TagTransform +{ + /** + * @type string + */ + public $transform_to = 'span'; + + /** + * @type array + */ + protected $_size_lookup = array( + '0' => 'xx-small', + '1' => 'xx-small', + '2' => 'small', + '3' => 'medium', + '4' => 'large', + '5' => 'x-large', + '6' => 'xx-large', + '7' => '300%', + '-1' => 'smaller', + '-2' => '60%', + '+1' => 'larger', + '+2' => '150%', + '+3' => '200%', + '+4' => '300%' + ); + + /** + * @param HTMLPurifier_Token_Tag $tag + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return HTMLPurifier_Token_End|string + */ + public function transform($tag, $config, $context) + { + if ($tag instanceof HTMLPurifier_Token_End) { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + return $new_tag; + } + + $attr = $tag->attr; + $prepend_style = ''; + + // handle color transform + if (isset($attr['color'])) { + $prepend_style .= 'color:' . $attr['color'] . ';'; + unset($attr['color']); + } + + // handle face transform + if (isset($attr['face'])) { + $prepend_style .= 'font-family:' . $attr['face'] . ';'; + unset($attr['face']); + } + + // handle size transform + if (isset($attr['size'])) { + // normalize large numbers + if ($attr['size'] !== '') { + if ($attr['size']{0} == '+' || $attr['size']{0} == '-') { + $size = (int)$attr['size']; + if ($size < -2) { + $attr['size'] = '-2'; + } + if ($size > 4) { + $attr['size'] = '+4'; + } + } else { + $size = (int)$attr['size']; + if ($size > 7) { + $attr['size'] = '7'; + } + } + } + if (isset($this->_size_lookup[$attr['size']])) { + $prepend_style .= 'font-size:' . + $this->_size_lookup[$attr['size']] . ';'; + } + unset($attr['size']); + } + + if ($prepend_style) { + $attr['style'] = isset($attr['style']) ? + $prepend_style . $attr['style'] : + $prepend_style; + } + + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + $new_tag->attr = $attr; + + return $new_tag; + } +} + + + + + +/** + * Simple transformation, just change tag name to something else, + * and possibly add some styling. This will cover most of the deprecated + * tag cases. + */ +class HTMLPurifier_TagTransform_Simple extends HTMLPurifier_TagTransform +{ + /** + * @type string + */ + protected $style; + + /** + * @param string $transform_to Tag name to transform to. + * @param string $style CSS style to add to the tag + */ + public function __construct($transform_to, $style = null) + { + $this->transform_to = $transform_to; + $this->style = $style; + } + + /** + * @param HTMLPurifier_Token_Tag $tag + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function transform($tag, $config, $context) + { + $new_tag = clone $tag; + $new_tag->name = $this->transform_to; + if (!is_null($this->style) && + ($new_tag instanceof HTMLPurifier_Token_Start || $new_tag instanceof HTMLPurifier_Token_Empty) + ) { + $this->prependCSS($new_tag->attr, $this->style); + } + return $new_tag; + } +} + + + + + +/** + * Concrete comment token class. Generally will be ignored. + */ +class HTMLPurifier_Token_Comment extends HTMLPurifier_Token +{ + /** + * Character data within comment. + * @type string + */ + public $data; + + /** + * @type bool + */ + public $is_whitespace = true; + + /** + * Transparent constructor. + * + * @param string $data String comment data. + * @param int $line + * @param int $col + */ + public function __construct($data, $line = null, $col = null) + { + $this->data = $data; + $this->line = $line; + $this->col = $col; + } + + public function toNode() { + return new HTMLPurifier_Node_Comment($this->data, $this->line, $this->col); + } +} + + + + + +/** + * Abstract class of a tag token (start, end or empty), and its behavior. + */ +abstract class HTMLPurifier_Token_Tag extends HTMLPurifier_Token +{ + /** + * Static bool marker that indicates the class is a tag. + * + * This allows us to check objects with !empty($obj->is_tag) + * without having to use a function call is_a(). + * @type bool + */ + public $is_tag = true; + + /** + * The lower-case name of the tag, like 'a', 'b' or 'blockquote'. + * + * @note Strictly speaking, XML tags are case sensitive, so we shouldn't + * be lower-casing them, but these tokens cater to HTML tags, which are + * insensitive. + * @type string + */ + public $name; + + /** + * Associative array of the tag's attributes. + * @type array + */ + public $attr = array(); + + /** + * Non-overloaded constructor, which lower-cases passed tag name. + * + * @param string $name String name. + * @param array $attr Associative array of attributes. + * @param int $line + * @param int $col + * @param array $armor + */ + public function __construct($name, $attr = array(), $line = null, $col = null, $armor = array()) + { + $this->name = ctype_lower($name) ? $name : strtolower($name); + foreach ($attr as $key => $value) { + // normalization only necessary when key is not lowercase + if (!ctype_lower($key)) { + $new_key = strtolower($key); + if (!isset($attr[$new_key])) { + $attr[$new_key] = $attr[$key]; + } + if ($new_key !== $key) { + unset($attr[$key]); + } + } + } + $this->attr = $attr; + $this->line = $line; + $this->col = $col; + $this->armor = $armor; + } + + public function toNode() { + return new HTMLPurifier_Node_Element($this->name, $this->attr, $this->line, $this->col, $this->armor); + } +} + + + + + +/** + * Concrete empty token class. + */ +class HTMLPurifier_Token_Empty extends HTMLPurifier_Token_Tag +{ + public function toNode() { + $n = parent::toNode(); + $n->empty = true; + return $n; + } +} + + + + + +/** + * Concrete end token class. + * + * @warning This class accepts attributes even though end tags cannot. This + * is for optimization reasons, as under normal circumstances, the Lexers + * do not pass attributes. + */ +class HTMLPurifier_Token_End extends HTMLPurifier_Token_Tag +{ + /** + * Token that started this node. + * Added by MakeWellFormed. Please do not edit this! + * @type HTMLPurifier_Token + */ + public $start; + + public function toNode() { + throw new Exception("HTMLPurifier_Token_End->toNode not supported!"); + } +} + + + + + +/** + * Concrete start token class. + */ +class HTMLPurifier_Token_Start extends HTMLPurifier_Token_Tag +{ +} + + + + + +/** + * Concrete text token class. + * + * Text tokens comprise of regular parsed character data (PCDATA) and raw + * character data (from the CDATA sections). Internally, their + * data is parsed with all entities expanded. Surprisingly, the text token + * does have a "tag name" called #PCDATA, which is how the DTD represents it + * in permissible child nodes. + */ +class HTMLPurifier_Token_Text extends HTMLPurifier_Token +{ + + /** + * @type string + */ + public $name = '#PCDATA'; + /**< PCDATA tag name compatible with DTD. */ + + /** + * @type string + */ + public $data; + /**< Parsed character data of text. */ + + /** + * @type bool + */ + public $is_whitespace; + + /**< Bool indicating if node is whitespace. */ + + /** + * Constructor, accepts data and determines if it is whitespace. + * @param string $data String parsed character data. + * @param int $line + * @param int $col + */ + public function __construct($data, $line = null, $col = null) + { + $this->data = $data; + $this->is_whitespace = ctype_space($data); + $this->line = $line; + $this->col = $col; + } + + public function toNode() { + return new HTMLPurifier_Node_Text($this->data, $this->is_whitespace, $this->line, $this->col); + } +} + + + + + +class HTMLPurifier_URIFilter_DisableExternal extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'DisableExternal'; + + /** + * @type array + */ + protected $ourHostParts = false; + + /** + * @param HTMLPurifier_Config $config + * @return void + */ + public function prepare($config) + { + $our_host = $config->getDefinition('URI')->host; + if ($our_host !== null) { + $this->ourHostParts = array_reverse(explode('.', $our_host)); + } + } + + /** + * @param HTMLPurifier_URI $uri Reference + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if (is_null($uri->host)) { + return true; + } + if ($this->ourHostParts === false) { + return false; + } + $host_parts = array_reverse(explode('.', $uri->host)); + foreach ($this->ourHostParts as $i => $x) { + if (!isset($host_parts[$i])) { + return false; + } + if ($host_parts[$i] != $this->ourHostParts[$i]) { + return false; + } + } + return true; + } +} + + + + + +class HTMLPurifier_URIFilter_DisableExternalResources extends HTMLPurifier_URIFilter_DisableExternal +{ + /** + * @type string + */ + public $name = 'DisableExternalResources'; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if (!$context->get('EmbeddedURI', true)) { + return true; + } + return parent::filter($uri, $config, $context); + } +} + + + + + +class HTMLPurifier_URIFilter_DisableResources extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'DisableResources'; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + return !$context->get('EmbeddedURI', true); + } +} + + + + + +// It's not clear to me whether or not Punycode means that hostnames +// do not have canonical forms anymore. As far as I can tell, it's +// not a problem (punycoding should be identity when no Unicode +// points are involved), but I'm not 100% sure +class HTMLPurifier_URIFilter_HostBlacklist extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'HostBlacklist'; + + /** + * @type array + */ + protected $blacklist = array(); + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function prepare($config) + { + $this->blacklist = $config->get('URI.HostBlacklist'); + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + foreach ($this->blacklist as $blacklisted_host_fragment) { + if (strpos($uri->host, $blacklisted_host_fragment) !== false) { + return false; + } + } + return true; + } +} + + + + + +// does not support network paths + +class HTMLPurifier_URIFilter_MakeAbsolute extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'MakeAbsolute'; + + /** + * @type + */ + protected $base; + + /** + * @type array + */ + protected $basePathStack = array(); + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function prepare($config) + { + $def = $config->getDefinition('URI'); + $this->base = $def->base; + if (is_null($this->base)) { + trigger_error( + 'URI.MakeAbsolute is being ignored due to lack of ' . + 'value for URI.Base configuration', + E_USER_WARNING + ); + return false; + } + $this->base->fragment = null; // fragment is invalid for base URI + $stack = explode('/', $this->base->path); + array_pop($stack); // discard last segment + $stack = $this->_collapseStack($stack); // do pre-parsing + $this->basePathStack = $stack; + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if (is_null($this->base)) { + return true; + } // abort early + if ($uri->path === '' && is_null($uri->scheme) && + is_null($uri->host) && is_null($uri->query) && is_null($uri->fragment)) { + // reference to current document + $uri = clone $this->base; + return true; + } + if (!is_null($uri->scheme)) { + // absolute URI already: don't change + if (!is_null($uri->host)) { + return true; + } + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + // scheme not recognized + return false; + } + if (!$scheme_obj->hierarchical) { + // non-hierarchal URI with explicit scheme, don't change + return true; + } + // special case: had a scheme but always is hierarchical and had no authority + } + if (!is_null($uri->host)) { + // network path, don't bother + return true; + } + if ($uri->path === '') { + $uri->path = $this->base->path; + } elseif ($uri->path[0] !== '/') { + // relative path, needs more complicated processing + $stack = explode('/', $uri->path); + $new_stack = array_merge($this->basePathStack, $stack); + if ($new_stack[0] !== '' && !is_null($this->base->host)) { + array_unshift($new_stack, ''); + } + $new_stack = $this->_collapseStack($new_stack); + $uri->path = implode('/', $new_stack); + } else { + // absolute path, but still we should collapse + $uri->path = implode('/', $this->_collapseStack(explode('/', $uri->path))); + } + // re-combine + $uri->scheme = $this->base->scheme; + if (is_null($uri->userinfo)) { + $uri->userinfo = $this->base->userinfo; + } + if (is_null($uri->host)) { + $uri->host = $this->base->host; + } + if (is_null($uri->port)) { + $uri->port = $this->base->port; + } + return true; + } + + /** + * Resolve dots and double-dots in a path stack + * @param array $stack + * @return array + */ + private function _collapseStack($stack) + { + $result = array(); + $is_folder = false; + for ($i = 0; isset($stack[$i]); $i++) { + $is_folder = false; + // absorb an internally duplicated slash + if ($stack[$i] == '' && $i && isset($stack[$i + 1])) { + continue; + } + if ($stack[$i] == '..') { + if (!empty($result)) { + $segment = array_pop($result); + if ($segment === '' && empty($result)) { + // error case: attempted to back out too far: + // restore the leading slash + $result[] = ''; + } elseif ($segment === '..') { + $result[] = '..'; // cannot remove .. with .. + } + } else { + // relative path, preserve the double-dots + $result[] = '..'; + } + $is_folder = true; + continue; + } + if ($stack[$i] == '.') { + // silently absorb + $is_folder = true; + continue; + } + $result[] = $stack[$i]; + } + if ($is_folder) { + $result[] = ''; + } + return $result; + } +} + + + + + +class HTMLPurifier_URIFilter_Munge extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'Munge'; + + /** + * @type bool + */ + public $post = true; + + /** + * @type string + */ + private $target; + + /** + * @type HTMLPurifier_URIParser + */ + private $parser; + + /** + * @type bool + */ + private $doEmbed; + + /** + * @type string + */ + private $secretKey; + + /** + * @type array + */ + protected $replace = array(); + + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function prepare($config) + { + $this->target = $config->get('URI.' . $this->name); + $this->parser = new HTMLPurifier_URIParser(); + $this->doEmbed = $config->get('URI.MungeResources'); + $this->secretKey = $config->get('URI.MungeSecretKey'); + if ($this->secretKey && !function_exists('hash_hmac')) { + throw new Exception("Cannot use %URI.MungeSecretKey without hash_hmac support."); + } + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + if ($context->get('EmbeddedURI', true) && !$this->doEmbed) { + return true; + } + + $scheme_obj = $uri->getSchemeObj($config, $context); + if (!$scheme_obj) { + return true; + } // ignore unknown schemes, maybe another postfilter did it + if (!$scheme_obj->browsable) { + return true; + } // ignore non-browseable schemes, since we can't munge those in a reasonable way + if ($uri->isBenign($config, $context)) { + return true; + } // don't redirect if a benign URL + + $this->makeReplace($uri, $config, $context); + $this->replace = array_map('rawurlencode', $this->replace); + + $new_uri = strtr($this->target, $this->replace); + $new_uri = $this->parser->parse($new_uri); + // don't redirect if the target host is the same as the + // starting host + if ($uri->host === $new_uri->host) { + return true; + } + $uri = $new_uri; // overwrite + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + */ + protected function makeReplace($uri, $config, $context) + { + $string = $uri->toString(); + // always available + $this->replace['%s'] = $string; + $this->replace['%r'] = $context->get('EmbeddedURI', true); + $token = $context->get('CurrentToken', true); + $this->replace['%n'] = $token ? $token->name : null; + $this->replace['%m'] = $context->get('CurrentAttr', true); + $this->replace['%p'] = $context->get('CurrentCSSProperty', true); + // not always available + if ($this->secretKey) { + $this->replace['%t'] = hash_hmac("sha256", $string, $this->secretKey); + } + } +} + + + + + +/** + * Implements safety checks for safe iframes. + * + * @warning This filter is *critical* for ensuring that %HTML.SafeIframe + * works safely. + */ +class HTMLPurifier_URIFilter_SafeIframe extends HTMLPurifier_URIFilter +{ + /** + * @type string + */ + public $name = 'SafeIframe'; + + /** + * @type bool + */ + public $always_load = true; + + /** + * @type string + */ + protected $regexp = null; + + // XXX: The not so good bit about how this is all set up now is we + // can't check HTML.SafeIframe in the 'prepare' step: we have to + // defer till the actual filtering. + /** + * @param HTMLPurifier_Config $config + * @return bool + */ + public function prepare($config) + { + $this->regexp = $config->get('URI.SafeIframeRegexp'); + return true; + } + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function filter(&$uri, $config, $context) + { + // check if filter not applicable + if (!$config->get('HTML.SafeIframe')) { + return true; + } + // check if the filter should actually trigger + if (!$context->get('EmbeddedURI', true)) { + return true; + } + $token = $context->get('CurrentToken', true); + if (!($token && $token->name == 'iframe')) { + return true; + } + // check if we actually have some whitelists enabled + if ($this->regexp === null) { + return false; + } + // actually check the whitelists + return preg_match($this->regexp, $uri->toString()); + } +} + + + + + +/** + * Implements data: URI for base64 encoded images supported by GD. + */ +class HTMLPurifier_URIScheme_data extends HTMLPurifier_URIScheme +{ + /** + * @type bool + */ + public $browsable = true; + + /** + * @type array + */ + public $allowed_types = array( + // you better write validation code for other types if you + // decide to allow them + 'image/jpeg' => true, + 'image/gif' => true, + 'image/png' => true, + ); + // this is actually irrelevant since we only write out the path + // component + /** + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $result = explode(',', $uri->path, 2); + $is_base64 = false; + $charset = null; + $content_type = null; + if (count($result) == 2) { + list($metadata, $data) = $result; + // do some legwork on the metadata + $metas = explode(';', $metadata); + while (!empty($metas)) { + $cur = array_shift($metas); + if ($cur == 'base64') { + $is_base64 = true; + break; + } + if (substr($cur, 0, 8) == 'charset=') { + // doesn't match if there are arbitrary spaces, but + // whatever dude + if ($charset !== null) { + continue; + } // garbage + $charset = substr($cur, 8); // not used + } else { + if ($content_type !== null) { + continue; + } // garbage + $content_type = $cur; + } + } + } else { + $data = $result[0]; + } + if ($content_type !== null && empty($this->allowed_types[$content_type])) { + return false; + } + if ($charset !== null) { + // error; we don't allow plaintext stuff + $charset = null; + } + $data = rawurldecode($data); + if ($is_base64) { + $raw_data = base64_decode($data); + } else { + $raw_data = $data; + } + if ( strlen($raw_data) < 12 ) { + // error; exif_imagetype throws exception with small files, + // and this likely indicates a corrupt URI/failed parse anyway + return false; + } + // XXX probably want to refactor this into a general mechanism + // for filtering arbitrary content types + if (function_exists('sys_get_temp_dir')) { + $file = tempnam(sys_get_temp_dir(), ""); + } else { + $file = tempnam("/tmp", ""); + } + file_put_contents($file, $raw_data); + if (function_exists('exif_imagetype')) { + $image_code = exif_imagetype($file); + unlink($file); + } elseif (function_exists('getimagesize')) { + set_error_handler(array($this, 'muteErrorHandler')); + $info = getimagesize($file); + restore_error_handler(); + unlink($file); + if ($info == false) { + return false; + } + $image_code = $info[2]; + } else { + trigger_error("could not find exif_imagetype or getimagesize functions", E_USER_ERROR); + } + $real_content_type = image_type_to_mime_type($image_code); + if ($real_content_type != $content_type) { + // we're nice guys; if the content type is something else we + // support, change it over + if (empty($this->allowed_types[$real_content_type])) { + return false; + } + $content_type = $real_content_type; + } + // ok, it's kosher, rewrite what we need + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->fragment = null; + $uri->query = null; + $uri->path = "$content_type;base64," . base64_encode($raw_data); + return true; + } + + /** + * @param int $errno + * @param string $errstr + */ + public function muteErrorHandler($errno, $errstr) + { + } +} + + + +/** + * Validates file as defined by RFC 1630 and RFC 1738. + */ +class HTMLPurifier_URIScheme_file extends HTMLPurifier_URIScheme +{ + /** + * Generally file:// URLs are not accessible from most + * machines, so placing them as an img src is incorrect. + * @type bool + */ + public $browsable = false; + + /** + * Basically the *only* URI scheme for which this is true, since + * accessing files on the local machine is very common. In fact, + * browsers on some operating systems don't understand the + * authority, though I hear it is used on Windows to refer to + * network shares. + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + // Authentication method is not supported + $uri->userinfo = null; + // file:// makes no provisions for accessing the resource + $uri->port = null; + // While it seems to work on Firefox, the querystring has + // no possible effect and is thus stripped. + $uri->query = null; + return true; + } +} + + + + + +/** + * Validates ftp (File Transfer Protocol) URIs as defined by generic RFC 1738. + */ +class HTMLPurifier_URIScheme_ftp extends HTMLPurifier_URIScheme +{ + /** + * @type int + */ + public $default_port = 21; + + /** + * @type bool + */ + public $browsable = true; // usually + + /** + * @type bool + */ + public $hierarchical = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->query = null; + + // typecode check + $semicolon_pos = strrpos($uri->path, ';'); // reverse + if ($semicolon_pos !== false) { + $type = substr($uri->path, $semicolon_pos + 1); // no semicolon + $uri->path = substr($uri->path, 0, $semicolon_pos); + $type_ret = ''; + if (strpos($type, '=') !== false) { + // figure out whether or not the declaration is correct + list($key, $typecode) = explode('=', $type, 2); + if ($key !== 'type') { + // invalid key, tack it back on encoded + $uri->path .= '%3B' . $type; + } elseif ($typecode === 'a' || $typecode === 'i' || $typecode === 'd') { + $type_ret = ";type=$typecode"; + } + } else { + $uri->path .= '%3B' . $type; + } + $uri->path = str_replace(';', '%3B', $uri->path); + $uri->path .= $type_ret; + } + return true; + } +} + + + + + +/** + * Validates http (HyperText Transfer Protocol) as defined by RFC 2616 + */ +class HTMLPurifier_URIScheme_http extends HTMLPurifier_URIScheme +{ + /** + * @type int + */ + public $default_port = 80; + + /** + * @type bool + */ + public $browsable = true; + + /** + * @type bool + */ + public $hierarchical = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->userinfo = null; + return true; + } +} + + + + + +/** + * Validates https (Secure HTTP) according to http scheme. + */ +class HTMLPurifier_URIScheme_https extends HTMLPurifier_URIScheme_http +{ + /** + * @type int + */ + public $default_port = 443; + /** + * @type bool + */ + public $secure = true; +} + + + + + +// VERY RELAXED! Shouldn't cause problems, not even Firefox checks if the +// email is valid, but be careful! + +/** + * Validates mailto (for E-mail) according to RFC 2368 + * @todo Validate the email address + * @todo Filter allowed query parameters + */ + +class HTMLPurifier_URIScheme_mailto extends HTMLPurifier_URIScheme +{ + /** + * @type bool + */ + public $browsable = false; + + /** + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + // we need to validate path against RFC 2368's addr-spec + return true; + } +} + + + + + +/** + * Validates news (Usenet) as defined by generic RFC 1738 + */ +class HTMLPurifier_URIScheme_news extends HTMLPurifier_URIScheme +{ + /** + * @type bool + */ + public $browsable = false; + + /** + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + $uri->query = null; + // typecode check needed on path + return true; + } +} + + + + + +/** + * Validates nntp (Network News Transfer Protocol) as defined by generic RFC 1738 + */ +class HTMLPurifier_URIScheme_nntp extends HTMLPurifier_URIScheme +{ + /** + * @type int + */ + public $default_port = 119; + + /** + * @type bool + */ + public $browsable = false; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->userinfo = null; + $uri->query = null; + return true; + } +} + + + + + +/** + * Validates tel (for phone numbers). + * + * The relevant specifications for this protocol are RFC 3966 and RFC 5341, + * but this class takes a much simpler approach: we normalize phone + * numbers so that they only include (possibly) a leading plus, + * and then any number of digits and x'es. + */ + +class HTMLPurifier_URIScheme_tel extends HTMLPurifier_URIScheme +{ + /** + * @type bool + */ + public $browsable = false; + + /** + * @type bool + */ + public $may_omit_host = true; + + /** + * @param HTMLPurifier_URI $uri + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return bool + */ + public function doValidate(&$uri, $config, $context) + { + $uri->userinfo = null; + $uri->host = null; + $uri->port = null; + + // Delete all non-numeric characters, non-x characters + // from phone number, EXCEPT for a leading plus sign. + $uri->path = preg_replace('/(?!^\+)[^\dx]/', '', + // Normalize e(x)tension to lower-case + str_replace('X', 'x', $uri->path)); + + return true; + } +} + + + + + +/** + * Performs safe variable parsing based on types which can be used by + * users. This may not be able to represent all possible data inputs, + * however. + */ +class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser +{ + /** + * @param mixed $var + * @param int $type + * @param bool $allow_null + * @return array|bool|float|int|mixed|null|string + * @throws HTMLPurifier_VarParserException + */ + protected function parseImplementation($var, $type, $allow_null) + { + if ($allow_null && $var === null) { + return null; + } + switch ($type) { + // Note: if code "breaks" from the switch, it triggers a generic + // exception to be thrown. Specific errors can be specifically + // done here. + case self::MIXED: + case self::ISTRING: + case self::STRING: + case self::TEXT: + case self::ITEXT: + return $var; + case self::INT: + if (is_string($var) && ctype_digit($var)) { + $var = (int)$var; + } + return $var; + case self::FLOAT: + if ((is_string($var) && is_numeric($var)) || is_int($var)) { + $var = (float)$var; + } + return $var; + case self::BOOL: + if (is_int($var) && ($var === 0 || $var === 1)) { + $var = (bool)$var; + } elseif (is_string($var)) { + if ($var == 'on' || $var == 'true' || $var == '1') { + $var = true; + } elseif ($var == 'off' || $var == 'false' || $var == '0') { + $var = false; + } else { + throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type"); + } + } + return $var; + case self::ALIST: + case self::HASH: + case self::LOOKUP: + if (is_string($var)) { + // special case: technically, this is an array with + // a single empty string item, but having an empty + // array is more intuitive + if ($var == '') { + return array(); + } + if (strpos($var, "\n") === false && strpos($var, "\r") === false) { + // simplistic string to array method that only works + // for simple lists of tag names or alphanumeric characters + $var = explode(',', $var); + } else { + $var = preg_split('/(,|[\n\r]+)/', $var); + } + // remove spaces + foreach ($var as $i => $j) { + $var[$i] = trim($j); + } + if ($type === self::HASH) { + // key:value,key2:value2 + $nvar = array(); + foreach ($var as $keypair) { + $c = explode(':', $keypair, 2); + if (!isset($c[1])) { + continue; + } + $nvar[trim($c[0])] = trim($c[1]); + } + $var = $nvar; + } + } + if (!is_array($var)) { + break; + } + $keys = array_keys($var); + if ($keys === array_keys($keys)) { + if ($type == self::ALIST) { + return $var; + } elseif ($type == self::LOOKUP) { + $new = array(); + foreach ($var as $key) { + $new[$key] = true; + } + return $new; + } else { + break; + } + } + if ($type === self::ALIST) { + trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING); + return array_values($var); + } + if ($type === self::LOOKUP) { + foreach ($var as $key => $value) { + if ($value !== true) { + trigger_error( + "Lookup array has non-true value at key '$key'; " . + "maybe your input array was not indexed numerically", + E_USER_WARNING + ); + } + $var[$key] = true; + } + } + return $var; + default: + $this->errorInconsistent(__CLASS__, $type); + } + $this->errorGeneric($var, $type); + } +} + + + + + +/** + * This variable parser uses PHP's internal code engine. Because it does + * this, it can represent all inputs; however, it is dangerous and cannot + * be used by users. + */ +class HTMLPurifier_VarParser_Native extends HTMLPurifier_VarParser +{ + + /** + * @param mixed $var + * @param int $type + * @param bool $allow_null + * @return null|string + */ + protected function parseImplementation($var, $type, $allow_null) + { + return $this->evalExpression($var); + } + + /** + * @param string $expr + * @return mixed + * @throws HTMLPurifier_VarParserException + */ + protected function evalExpression($expr) + { + $var = null; + $result = eval("\$var = $expr;"); + if ($result === false) { + throw new HTMLPurifier_VarParserException("Fatal error in evaluated code"); + } + return $var; + } +} + + + diff --git a/AvocadoEdition/plugin/htmlpurifier/safeiframe.txt b/AvocadoEdition/plugin/htmlpurifier/safeiframe.txt new file mode 100644 index 0000000..0238114 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/safeiframe.txt @@ -0,0 +1,12 @@ +# iframe 허용 도메인을 한줄에 하나씩만 적으세요. +# 도메인 뒤에 가급적 / 를 붙여주세요. +www.youtube(?:-nocookie)?.com/ +serviceapi.rmcnmv.naver.com/ +videofarm.daum.net/ +player.vimeo.com/ +maps.google.com/ +play.afreeca.com/ +v.nate.com/ +www.microsoft.com/showcase/video.aspx/ +w.soundcloud.com/ +www.facebook.com/ \ No newline at end of file diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php new file mode 100644 index 0000000..d5906cd --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/ConfigSchema.php @@ -0,0 +1,48 @@ +directives as $d) { + $schema->add( + $d->id->key, + $d->default, + $d->type, + $d->typeAllowsNull + ); + if ($d->allowed !== null) { + $schema->addAllowedValues( + $d->id->key, + $d->allowed + ); + } + foreach ($d->aliases as $alias) { + $schema->addAlias( + $alias->key, + $d->id->key + ); + } + if ($d->valueAliases !== null) { + $schema->addValueAliases( + $d->id->key, + $d->valueAliases + ); + } + } + $schema->postProcess(); + return $schema; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php new file mode 100644 index 0000000..5fa56f7 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Builder/Xml.php @@ -0,0 +1,144 @@ +startElement('div'); + + $purifier = HTMLPurifier::getInstance(); + $html = $purifier->purify($html); + $this->writeAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + $this->writeRaw($html); + + $this->endElement(); // div + } + + /** + * @param mixed $var + * @return string + */ + protected function export($var) + { + if ($var === array()) { + return 'array()'; + } + return var_export($var, true); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + */ + public function build($interchange) + { + // global access, only use as last resort + $this->interchange = $interchange; + + $this->setIndent(true); + $this->startDocument('1.0', 'UTF-8'); + $this->startElement('configdoc'); + $this->writeElement('title', $interchange->name); + + foreach ($interchange->directives as $directive) { + $this->buildDirective($directive); + } + + if ($this->namespace) { + $this->endElement(); + } // namespace + + $this->endElement(); // configdoc + $this->flush(); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + */ + public function buildDirective($directive) + { + // Kludge, although I suppose having a notion of a "root namespace" + // certainly makes things look nicer when documentation is built. + // Depends on things being sorted. + if (!$this->namespace || $this->namespace !== $directive->id->getRootNamespace()) { + if ($this->namespace) { + $this->endElement(); + } // namespace + $this->namespace = $directive->id->getRootNamespace(); + $this->startElement('namespace'); + $this->writeAttribute('id', $this->namespace); + $this->writeElement('name', $this->namespace); + } + + $this->startElement('directive'); + $this->writeAttribute('id', $directive->id->toString()); + + $this->writeElement('name', $directive->id->getDirective()); + + $this->startElement('aliases'); + foreach ($directive->aliases as $alias) { + $this->writeElement('alias', $alias->toString()); + } + $this->endElement(); // aliases + + $this->startElement('constraints'); + if ($directive->version) { + $this->writeElement('version', $directive->version); + } + $this->startElement('type'); + if ($directive->typeAllowsNull) { + $this->writeAttribute('allow-null', 'yes'); + } + $this->text($directive->type); + $this->endElement(); // type + if ($directive->allowed) { + $this->startElement('allowed'); + foreach ($directive->allowed as $value => $x) { + $this->writeElement('value', $value); + } + $this->endElement(); // allowed + } + $this->writeElement('default', $this->export($directive->default)); + $this->writeAttribute('xml:space', 'preserve'); + if ($directive->external) { + $this->startElement('external'); + foreach ($directive->external as $project) { + $this->writeElement('project', $project); + } + $this->endElement(); + } + $this->endElement(); // constraints + + if ($directive->deprecatedVersion) { + $this->startElement('deprecated'); + $this->writeElement('version', $directive->deprecatedVersion); + $this->writeElement('use', $directive->deprecatedUse->toString()); + $this->endElement(); // deprecated + } + + $this->startElement('description'); + $this->writeHTMLDiv($directive->description); + $this->endElement(); // description + + $this->endElement(); // directive + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Exception.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Exception.php new file mode 100644 index 0000000..2671516 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Exception.php @@ -0,0 +1,11 @@ + array(directive info) + * @type HTMLPurifier_ConfigSchema_Interchange_Directive[] + */ + public $directives = array(); + + /** + * Adds a directive array to $directives + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $directive + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function addDirective($directive) + { + if (isset($this->directives[$i = $directive->id->toString()])) { + throw new HTMLPurifier_ConfigSchema_Exception("Cannot redefine directive '$i'"); + } + $this->directives[$i] = $directive; + } + + /** + * Convenience function to perform standard validation. Throws exception + * on failed validation. + */ + public function validate() + { + $validator = new HTMLPurifier_ConfigSchema_Validator(); + return $validator->validate($this); + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php new file mode 100644 index 0000000..127a39a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Directive.php @@ -0,0 +1,89 @@ + true). + * Null if all values are allowed. + * @type array + */ + public $allowed; + + /** + * List of aliases for the directive. + * e.g. array(new HTMLPurifier_ConfigSchema_Interchange_Id('Ns', 'Dir'))). + * @type HTMLPurifier_ConfigSchema_Interchange_Id[] + */ + public $aliases = array(); + + /** + * Hash of value aliases, e.g. array('alt' => 'real'). Null if value + * aliasing is disabled (necessary for non-scalar types). + * @type array + */ + public $valueAliases; + + /** + * Version of HTML Purifier the directive was introduced, e.g. '1.3.1'. + * Null if the directive has always existed. + * @type string + */ + public $version; + + /** + * ID of directive that supercedes this old directive. + * Null if not deprecated. + * @type HTMLPurifier_ConfigSchema_Interchange_Id + */ + public $deprecatedUse; + + /** + * Version of HTML Purifier this directive was deprecated. Null if not + * deprecated. + * @type string + */ + public $deprecatedVersion; + + /** + * List of external projects this directive depends on, e.g. array('CSSTidy'). + * @type array + */ + public $external = array(); +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php new file mode 100644 index 0000000..126f09d --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Interchange/Id.php @@ -0,0 +1,58 @@ +key = $key; + } + + /** + * @return string + * @warning This is NOT magic, to ensure that people don't abuse SPL and + * cause problems for PHP 5.0 support. + */ + public function toString() + { + return $this->key; + } + + /** + * @return string + */ + public function getRootNamespace() + { + return substr($this->key, 0, strpos($this->key, ".")); + } + + /** + * @return string + */ + public function getDirective() + { + return substr($this->key, strpos($this->key, ".") + 1); + } + + /** + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id + */ + public static function make($id) + { + return new HTMLPurifier_ConfigSchema_Interchange_Id($id); + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php new file mode 100644 index 0000000..655e6dd --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/InterchangeBuilder.php @@ -0,0 +1,226 @@ +varParser = $varParser ? $varParser : new HTMLPurifier_VarParser_Native(); + } + + /** + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public static function buildFromDirectory($dir = null) + { + $builder = new HTMLPurifier_ConfigSchema_InterchangeBuilder(); + $interchange = new HTMLPurifier_ConfigSchema_Interchange(); + return $builder->buildDir($interchange, $dir); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $dir + * @return HTMLPurifier_ConfigSchema_Interchange + */ + public function buildDir($interchange, $dir = null) + { + if (!$dir) { + $dir = HTMLPURIFIER_PREFIX . '/HTMLPurifier/ConfigSchema/schema'; + } + if (file_exists($dir . '/info.ini')) { + $info = parse_ini_file($dir . '/info.ini'); + $interchange->name = $info['name']; + } + + $files = array(); + $dh = opendir($dir); + while (false !== ($file = readdir($dh))) { + if (!$file || $file[0] == '.' || strrchr($file, '.') !== '.txt') { + continue; + } + $files[] = $file; + } + closedir($dh); + + sort($files); + foreach ($files as $file) { + $this->buildFile($interchange, $dir . '/' . $file); + } + return $interchange; + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param string $file + */ + public function buildFile($interchange, $file) + { + $parser = new HTMLPurifier_StringHashParser(); + $this->build( + $interchange, + new HTMLPurifier_StringHash($parser->parseFile($file)) + ); + } + + /** + * Builds an interchange object based on a hash. + * @param HTMLPurifier_ConfigSchema_Interchange $interchange HTMLPurifier_ConfigSchema_Interchange object to build + * @param HTMLPurifier_StringHash $hash source data + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function build($interchange, $hash) + { + if (!$hash instanceof HTMLPurifier_StringHash) { + $hash = new HTMLPurifier_StringHash($hash); + } + if (!isset($hash['ID'])) { + throw new HTMLPurifier_ConfigSchema_Exception('Hash does not have any ID'); + } + if (strpos($hash['ID'], '.') === false) { + if (count($hash) == 2 && isset($hash['DESCRIPTION'])) { + $hash->offsetGet('DESCRIPTION'); // prevent complaining + } else { + throw new HTMLPurifier_ConfigSchema_Exception('All directives must have a namespace'); + } + } else { + $this->buildDirective($interchange, $hash); + } + $this->_findUnused($hash); + } + + /** + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @param HTMLPurifier_StringHash $hash + * @throws HTMLPurifier_ConfigSchema_Exception + */ + public function buildDirective($interchange, $hash) + { + $directive = new HTMLPurifier_ConfigSchema_Interchange_Directive(); + + // These are required elements: + $directive->id = $this->id($hash->offsetGet('ID')); + $id = $directive->id->toString(); // convenience + + if (isset($hash['TYPE'])) { + $type = explode('/', $hash->offsetGet('TYPE')); + if (isset($type[1])) { + $directive->typeAllowsNull = true; + } + $directive->type = $type[0]; + } else { + throw new HTMLPurifier_ConfigSchema_Exception("TYPE in directive hash '$id' not defined"); + } + + if (isset($hash['DEFAULT'])) { + try { + $directive->default = $this->varParser->parse( + $hash->offsetGet('DEFAULT'), + $directive->type, + $directive->typeAllowsNull + ); + } catch (HTMLPurifier_VarParserException $e) { + throw new HTMLPurifier_ConfigSchema_Exception($e->getMessage() . " in DEFAULT in directive hash '$id'"); + } + } + + if (isset($hash['DESCRIPTION'])) { + $directive->description = $hash->offsetGet('DESCRIPTION'); + } + + if (isset($hash['ALLOWED'])) { + $directive->allowed = $this->lookup($this->evalArray($hash->offsetGet('ALLOWED'))); + } + + if (isset($hash['VALUE-ALIASES'])) { + $directive->valueAliases = $this->evalArray($hash->offsetGet('VALUE-ALIASES')); + } + + if (isset($hash['ALIASES'])) { + $raw_aliases = trim($hash->offsetGet('ALIASES')); + $aliases = preg_split('/\s*,\s*/', $raw_aliases); + foreach ($aliases as $alias) { + $directive->aliases[] = $this->id($alias); + } + } + + if (isset($hash['VERSION'])) { + $directive->version = $hash->offsetGet('VERSION'); + } + + if (isset($hash['DEPRECATED-USE'])) { + $directive->deprecatedUse = $this->id($hash->offsetGet('DEPRECATED-USE')); + } + + if (isset($hash['DEPRECATED-VERSION'])) { + $directive->deprecatedVersion = $hash->offsetGet('DEPRECATED-VERSION'); + } + + if (isset($hash['EXTERNAL'])) { + $directive->external = preg_split('/\s*,\s*/', trim($hash->offsetGet('EXTERNAL'))); + } + + $interchange->addDirective($directive); + } + + /** + * Evaluates an array PHP code string without array() wrapper + * @param string $contents + */ + protected function evalArray($contents) + { + return eval('return array(' . $contents . ');'); + } + + /** + * Converts an array list into a lookup array. + * @param array $array + * @return array + */ + protected function lookup($array) + { + $ret = array(); + foreach ($array as $val) { + $ret[$val] = true; + } + return $ret; + } + + /** + * Convenience function that creates an HTMLPurifier_ConfigSchema_Interchange_Id + * object based on a string Id. + * @param string $id + * @return HTMLPurifier_ConfigSchema_Interchange_Id + */ + protected function id($id) + { + return HTMLPurifier_ConfigSchema_Interchange_Id::make($id); + } + + /** + * Triggers errors for any unused keys passed in the hash; such keys + * may indicate typos, missing values, etc. + * @param HTMLPurifier_StringHash $hash Hash to check. + */ + protected function _findUnused($hash) + { + $accessed = $hash->getAccessed(); + foreach ($hash as $k => $v) { + if (!isset($accessed[$k])) { + trigger_error("String hash key '$k' not used by builder", E_USER_NOTICE); + } + } + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Validator.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Validator.php new file mode 100644 index 0000000..fb31277 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/Validator.php @@ -0,0 +1,248 @@ +parser = new HTMLPurifier_VarParser(); + } + + /** + * Validates a fully-formed interchange object. + * @param HTMLPurifier_ConfigSchema_Interchange $interchange + * @return bool + */ + public function validate($interchange) + { + $this->interchange = $interchange; + $this->aliases = array(); + // PHP is a bit lax with integer <=> string conversions in + // arrays, so we don't use the identical !== comparison + foreach ($interchange->directives as $i => $directive) { + $id = $directive->id->toString(); + if ($i != $id) { + $this->error(false, "Integrity violation: key '$i' does not match internal id '$id'"); + } + $this->validateDirective($directive); + } + return true; + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Id object. + * @param HTMLPurifier_ConfigSchema_Interchange_Id $id + */ + public function validateId($id) + { + $id_string = $id->toString(); + $this->context[] = "id '$id_string'"; + if (!$id instanceof HTMLPurifier_ConfigSchema_Interchange_Id) { + // handled by InterchangeBuilder + $this->error(false, 'is not an instance of HTMLPurifier_ConfigSchema_Interchange_Id'); + } + // keys are now unconstrained (we might want to narrow down to A-Za-z0-9.) + // we probably should check that it has at least one namespace + $this->with($id, 'key') + ->assertNotEmpty() + ->assertIsString(); // implicit assertIsString handled by InterchangeBuilder + array_pop($this->context); + } + + /** + * Validates a HTMLPurifier_ConfigSchema_Interchange_Directive object. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirective($d) + { + $id = $d->id->toString(); + $this->context[] = "directive '$id'"; + $this->validateId($d->id); + + $this->with($d, 'description') + ->assertNotEmpty(); + + // BEGIN - handled by InterchangeBuilder + $this->with($d, 'type') + ->assertNotEmpty(); + $this->with($d, 'typeAllowsNull') + ->assertIsBool(); + try { + // This also tests validity of $d->type + $this->parser->parse($d->default, $d->type, $d->typeAllowsNull); + } catch (HTMLPurifier_VarParserException $e) { + $this->error('default', 'had error: ' . $e->getMessage()); + } + // END - handled by InterchangeBuilder + + if (!is_null($d->allowed) || !empty($d->valueAliases)) { + // allowed and valueAliases require that we be dealing with + // strings, so check for that early. + $d_int = HTMLPurifier_VarParser::$types[$d->type]; + if (!isset(HTMLPurifier_VarParser::$stringTypes[$d_int])) { + $this->error('type', 'must be a string type when used with allowed or value aliases'); + } + } + + $this->validateDirectiveAllowed($d); + $this->validateDirectiveValueAliases($d); + $this->validateDirectiveAliases($d); + + array_pop($this->context); + } + + /** + * Extra validation if $allowed member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveAllowed($d) + { + if (is_null($d->allowed)) { + return; + } + $this->with($d, 'allowed') + ->assertNotEmpty() + ->assertIsLookup(); // handled by InterchangeBuilder + if (is_string($d->default) && !isset($d->allowed[$d->default])) { + $this->error('default', 'must be an allowed value'); + } + $this->context[] = 'allowed'; + foreach ($d->allowed as $val => $x) { + if (!is_string($val)) { + $this->error("value $val", 'must be a string'); + } + } + array_pop($this->context); + } + + /** + * Extra validation if $valueAliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveValueAliases($d) + { + if (is_null($d->valueAliases)) { + return; + } + $this->with($d, 'valueAliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'valueAliases'; + foreach ($d->valueAliases as $alias => $real) { + if (!is_string($alias)) { + $this->error("alias $alias", 'must be a string'); + } + if (!is_string($real)) { + $this->error("alias target $real from alias '$alias'", 'must be a string'); + } + if ($alias === $real) { + $this->error("alias '$alias'", "must not be an alias to itself"); + } + } + if (!is_null($d->allowed)) { + foreach ($d->valueAliases as $alias => $real) { + if (isset($d->allowed[$alias])) { + $this->error("alias '$alias'", 'must not be an allowed value'); + } elseif (!isset($d->allowed[$real])) { + $this->error("alias '$alias'", 'must be an alias to an allowed value'); + } + } + } + array_pop($this->context); + } + + /** + * Extra validation if $aliases member variable of + * HTMLPurifier_ConfigSchema_Interchange_Directive is defined. + * @param HTMLPurifier_ConfigSchema_Interchange_Directive $d + */ + public function validateDirectiveAliases($d) + { + $this->with($d, 'aliases') + ->assertIsArray(); // handled by InterchangeBuilder + $this->context[] = 'aliases'; + foreach ($d->aliases as $alias) { + $this->validateId($alias); + $s = $alias->toString(); + if (isset($this->interchange->directives[$s])) { + $this->error("alias '$s'", 'collides with another directive'); + } + if (isset($this->aliases[$s])) { + $other_directive = $this->aliases[$s]; + $this->error("alias '$s'", "collides with alias for directive '$other_directive'"); + } + $this->aliases[$s] = $d->id->toString(); + } + array_pop($this->context); + } + + // protected helper functions + + /** + * Convenience function for generating HTMLPurifier_ConfigSchema_ValidatorAtom + * for validating simple member variables of objects. + * @param $obj + * @param $member + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + protected function with($obj, $member) + { + return new HTMLPurifier_ConfigSchema_ValidatorAtom($this->getFormattedContext(), $obj, $member); + } + + /** + * Emits an error, providing helpful context. + * @throws HTMLPurifier_ConfigSchema_Exception + */ + protected function error($target, $msg) + { + if ($target !== false) { + $prefix = ucfirst($target) . ' in ' . $this->getFormattedContext(); + } else { + $prefix = ucfirst($this->getFormattedContext()); + } + throw new HTMLPurifier_ConfigSchema_Exception(trim($prefix . ' ' . $msg)); + } + + /** + * Returns a formatted context string. + * @return string + */ + protected function getFormattedContext() + { + return implode(' in ', array_reverse($this->context)); + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php new file mode 100644 index 0000000..c9aa364 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/ValidatorAtom.php @@ -0,0 +1,130 @@ +context = $context; + $this->obj = $obj; + $this->member = $member; + $this->contents =& $obj->$member; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsString() + { + if (!is_string($this->contents)) { + $this->error('must be a string'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsBool() + { + if (!is_bool($this->contents)) { + $this->error('must be a boolean'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsArray() + { + if (!is_array($this->contents)) { + $this->error('must be an array'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotNull() + { + if ($this->contents === null) { + $this->error('must not be null'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertAlnum() + { + $this->assertIsString(); + if (!ctype_alnum($this->contents)) { + $this->error('must be alphanumeric'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertNotEmpty() + { + if (empty($this->contents)) { + $this->error('must not be empty'); + } + return $this; + } + + /** + * @return HTMLPurifier_ConfigSchema_ValidatorAtom + */ + public function assertIsLookup() + { + $this->assertIsArray(); + foreach ($this->contents as $v) { + if ($v !== true) { + $this->error('must be a lookup array'); + } + } + return $this; + } + + /** + * @param string $msg + * @throws HTMLPurifier_ConfigSchema_Exception + */ + protected function error($msg) + { + throw new HTMLPurifier_ConfigSchema_Exception(ucfirst($this->member) . ' in ' . $this->context . ' ' . $msg); + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema.ser b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema.ser new file mode 100644 index 0000000000000000000000000000000000000000..0a7a406e132dd5dfe79e4b52f8f44b7d4f8d5481 GIT binary patch literal 15598 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt new file mode 100644 index 0000000..0517fed --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedClasses.txt @@ -0,0 +1,8 @@ +Attr.AllowedClasses +TYPE: lookup/null +VERSION: 4.0.0 +DEFAULT: null +--DESCRIPTION-- +List of allowed class values in the class attribute. By default, this is null, +which means all classes are allowed. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt new file mode 100644 index 0000000..249edd6 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedFrameTargets.txt @@ -0,0 +1,12 @@ +Attr.AllowedFrameTargets +TYPE: lookup +DEFAULT: array() +--DESCRIPTION-- +Lookup table of all allowed link frame targets. Some commonly used link +targets include _blank, _self, _parent and _top. Values should be +lowercase, as validation will be done in a case-sensitive manner despite +W3C's recommendation. XHTML 1.0 Strict does not permit the target attribute +so this directive will have no effect in that doctype. XHTML 1.1 does not +enable the Target module by default, you will have to manually enable it +(see the module documentation for more details.) +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt new file mode 100644 index 0000000..9a8fa6a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRel.txt @@ -0,0 +1,9 @@ +Attr.AllowedRel +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed forward document relationships in the rel attribute. Common +values may be nofollow or print. By default, this is empty, meaning that no +document relationships are allowed. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt new file mode 100644 index 0000000..b017883 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.AllowedRev.txt @@ -0,0 +1,9 @@ +Attr.AllowedRev +TYPE: lookup +VERSION: 1.6.0 +DEFAULT: array() +--DESCRIPTION-- +List of allowed reverse document relationships in the rev attribute. This +attribute is a bit of an edge-case; if you don't know what it is for, stay +away. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt new file mode 100644 index 0000000..e774b82 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ClassUseCDATA.txt @@ -0,0 +1,19 @@ +Attr.ClassUseCDATA +TYPE: bool/null +DEFAULT: null +VERSION: 4.0.0 +--DESCRIPTION-- +If null, class will auto-detect the doctype and, if matching XHTML 1.1 or +XHTML 2.0, will use the restrictive NMTOKENS specification of class. Otherwise, +it will use a relaxed CDATA definition. If true, the relaxed CDATA definition +is forced; if false, the NMTOKENS definition is forced. To get behavior +of HTML Purifier prior to 4.0.0, set this directive to false. + +Some rational behind the auto-detection: +in previous versions of HTML Purifier, it was assumed that the form of +class was NMTOKENS, as specified by the XHTML Modularization (representing +XHTML 1.1 and XHTML 2.0). The DTDs for HTML 4.01 and XHTML 1.0, however +specify class as CDATA. HTML 5 effectively defines it as CDATA, but +with the additional constraint that each name should be unique (this is not +explicitly outlined in previous specifications). +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt new file mode 100644 index 0000000..533165e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultImageAlt.txt @@ -0,0 +1,11 @@ +Attr.DefaultImageAlt +TYPE: string/null +DEFAULT: null +VERSION: 3.2.0 +--DESCRIPTION-- +This is the content of the alt tag of an image if the user had not +previously specified an alt attribute. This applies to all images without +a valid alt attribute, as opposed to %Attr.DefaultInvalidImageAlt, which +only applies to invalid images, and overrides in the case of an invalid image. +Default behavior with null is to use the basename of the src tag for the alt. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt new file mode 100644 index 0000000..9eb7e38 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImage.txt @@ -0,0 +1,9 @@ +Attr.DefaultInvalidImage +TYPE: string +DEFAULT: '' +--DESCRIPTION-- +This is the default image an img tag will be pointed to if it does not have +a valid src attribute. In future versions, we may allow the image tag to +be removed completely, but due to design issues, this is not possible right +now. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt new file mode 100644 index 0000000..2f17bf4 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultInvalidImageAlt.txt @@ -0,0 +1,8 @@ +Attr.DefaultInvalidImageAlt +TYPE: string +DEFAULT: 'Invalid image' +--DESCRIPTION-- +This is the content of the alt tag of an invalid image if the user had not +previously specified an alt attribute. It has no effect when the image is +valid but there was no alt attribute present. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt new file mode 100644 index 0000000..52654b5 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.DefaultTextDir.txt @@ -0,0 +1,10 @@ +Attr.DefaultTextDir +TYPE: string +DEFAULT: 'ltr' +--DESCRIPTION-- +Defines the default text direction (ltr or rtl) of the document being +parsed. This generally is the same as the value of the dir attribute in +HTML, or ltr if that is not specified. +--ALLOWED-- +'ltr', 'rtl' +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt new file mode 100644 index 0000000..6440d21 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.EnableID.txt @@ -0,0 +1,16 @@ +Attr.EnableID +TYPE: bool +DEFAULT: false +VERSION: 1.2.0 +--DESCRIPTION-- +Allows the ID attribute in HTML. This is disabled by default due to the +fact that without proper configuration user input can easily break the +validation of a webpage by specifying an ID that is already on the +surrounding HTML. If you don't mind throwing caution to the wind, enable +this directive, but I strongly recommend you also consider blacklisting IDs +you use (%Attr.IDBlacklist) or prefixing all user supplied IDs +(%Attr.IDPrefix). When set to true HTML Purifier reverts to the behavior of +pre-1.2.0 versions. +--ALIASES-- +HTML.EnableAttrID +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt new file mode 100644 index 0000000..f31d226 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ForbiddenClasses.txt @@ -0,0 +1,8 @@ +Attr.ForbiddenClasses +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array() +--DESCRIPTION-- +List of forbidden class values in the class attribute. By default, this is +empty, which means that no classes are forbidden. See also %Attr.AllowedClasses. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt new file mode 100644 index 0000000..735d4b7 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.ID.HTML5.txt @@ -0,0 +1,10 @@ +Attr.ID.HTML5 +TYPE: bool/null +DEFAULT: null +VERSION: 4.8.0 +--DESCRIPTION-- +In HTML5, restrictions on the format of the id attribute have been significantly +relaxed, such that any string is valid so long as it contains no spaces and +is at least one character. In lieu of a general HTML5 compatibility flag, +set this configuration directive to true to use the relaxed rules. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt new file mode 100644 index 0000000..5f2b5e3 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklist.txt @@ -0,0 +1,5 @@ +Attr.IDBlacklist +TYPE: list +DEFAULT: array() +DESCRIPTION: Array of IDs not allowed in the document. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt new file mode 100644 index 0000000..6f58245 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDBlacklistRegexp.txt @@ -0,0 +1,9 @@ +Attr.IDBlacklistRegexp +TYPE: string/null +VERSION: 1.6.0 +DEFAULT: NULL +--DESCRIPTION-- +PCRE regular expression to be matched against all IDs. If the expression is +matches, the ID is rejected. Use this with care: may cause significant +degradation. ID matching is done after all other validation. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt new file mode 100644 index 0000000..cc49d43 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefix.txt @@ -0,0 +1,12 @@ +Attr.IDPrefix +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +String to prefix to IDs. If you have no idea what IDs your pages may use, +you may opt to simply add a prefix to all user-submitted ID attributes so +that they are still usable, but will not conflict with core page IDs. +Example: setting the directive to 'user_' will result in a user submitted +'foo' to become 'user_foo' Be sure to set %HTML.EnableAttrID to true +before using this. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt new file mode 100644 index 0000000..2c5924a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Attr.IDPrefixLocal.txt @@ -0,0 +1,14 @@ +Attr.IDPrefixLocal +TYPE: string +VERSION: 1.2.0 +DEFAULT: '' +--DESCRIPTION-- +Temporary prefix for IDs used in conjunction with %Attr.IDPrefix. If you +need to allow multiple sets of user content on web page, you may need to +have a seperate prefix that changes with each iteration. This way, +seperately submitted user content displayed on the same page doesn't +clobber each other. Ideal values are unique identifiers for the content it +represents (i.e. the id of the row in the database). Be sure to add a +seperator (like an underscore) at the end. Warning: this directive will +not work unless %Attr.IDPrefix is set to a non-empty value! +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt new file mode 100644 index 0000000..d5caa1b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.AutoParagraph.txt @@ -0,0 +1,31 @@ +AutoFormat.AutoParagraph +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on auto-paragraphing, where double newlines are + converted in to paragraphs whenever possible. Auto-paragraphing: +

        +
          +
        • Always applies to inline elements or text in the root node,
        • +
        • Applies to inline elements or text with double newlines in nodes + that allow paragraph tags,
        • +
        • Applies to double newlines in paragraph tags
        • +
        +

        + p tags must be allowed for this directive to take effect. + We do not use br tags for paragraphing, as that is + semantically incorrect. +

        +

        + To prevent auto-paragraphing as a content-producer, refrain from using + double-newlines except to specify a new paragraph or in contexts where + it has special meaning (whitespace usually has no meaning except in + tags like pre, so this should not be difficult.) To prevent + the paragraphing of inline text adjacent to block elements, wrap them + in div tags (the behavior is slightly different outside of + the root node.) +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt new file mode 100644 index 0000000..2a47648 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Custom.txt @@ -0,0 +1,12 @@ +AutoFormat.Custom +TYPE: list +VERSION: 2.0.1 +DEFAULT: array() +--DESCRIPTION-- + +

        + This directive can be used to add custom auto-format injectors. + Specify an array of injector names (class name minus the prefix) + or concrete implementations. Injector class must exist. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt new file mode 100644 index 0000000..663064a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.DisplayLinkURI.txt @@ -0,0 +1,11 @@ +AutoFormat.DisplayLinkURI +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + This directive turns on the in-text display of URIs in <a> tags, and disables + those links. For example, example becomes + example (http://example.com). +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt new file mode 100644 index 0000000..3a48ba9 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.Linkify.txt @@ -0,0 +1,12 @@ +AutoFormat.Linkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + This directive turns on linkification, auto-linking http, ftp and + https URLs. a tags with the href attribute + must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt new file mode 100644 index 0000000..db58b13 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.DocURL.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify.DocURL +TYPE: string +VERSION: 2.0.1 +DEFAULT: '#%s' +ALIASES: AutoFormatParam.PurifierLinkifyDocURL +--DESCRIPTION-- +

        + Location of configuration documentation to link to, let %s substitute + into the configuration's namespace and directive names sans the percent + sign. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt new file mode 100644 index 0000000..7996488 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.PurifierLinkify.txt @@ -0,0 +1,12 @@ +AutoFormat.PurifierLinkify +TYPE: bool +VERSION: 2.0.1 +DEFAULT: false +--DESCRIPTION-- + +

        + Internal auto-formatter that converts configuration directives in + syntax %Namespace.Directive to links. a tags + with the href attribute must be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt new file mode 100644 index 0000000..6367fe2 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.Predicate.txt @@ -0,0 +1,14 @@ +AutoFormat.RemoveEmpty.Predicate +TYPE: hash +VERSION: 4.7.0 +DEFAULT: array('colgroup' => array(), 'th' => array(), 'td' => array(), 'iframe' => array('src')) +--DESCRIPTION-- +

        + Given that an element has no contents, it will be removed by default, unless + this predicate dictates otherwise. The predicate can either be an associative + map from tag name to list of attributes that must be present for the element + to be considered preserved: thus, the default always preserves colgroup, + th and td, and also iframe if it + has a src. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt new file mode 100644 index 0000000..35c393b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions +TYPE: lookup +VERSION: 4.0.0 +DEFAULT: array('td' => true, 'th' => true) +--DESCRIPTION-- +

        + When %AutoFormat.RemoveEmpty and %AutoFormat.RemoveEmpty.RemoveNbsp + are enabled, this directive defines what HTML elements should not be + removede if they have only a non-breaking space in them. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt new file mode 100644 index 0000000..ca17eb1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.RemoveNbsp.txt @@ -0,0 +1,15 @@ +AutoFormat.RemoveEmpty.RemoveNbsp +TYPE: bool +VERSION: 4.0.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will treat any elements that contain only + non-breaking spaces as well as regular whitespace as empty, and remove + them when %AutoForamt.RemoveEmpty is enabled. +

        +

        + See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements + that don't have this behavior applied to them. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt new file mode 100644 index 0000000..34657ba --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveEmpty.txt @@ -0,0 +1,46 @@ +AutoFormat.RemoveEmpty +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + When enabled, HTML Purifier will attempt to remove empty elements that + contribute no semantic information to the document. The following types + of nodes will be removed: +

        +
        • + Tags with no attributes and no content, and that are not empty + elements (remove <a></a> but not + <br />), and +
        • +
        • + Tags with no content, except for:
            +
          • The colgroup element, or
          • +
          • + Elements with the id or name attribute, + when those attributes are permitted on those elements. +
          • +
        • +
        +

        + Please be very careful when using this functionality; while it may not + seem that empty elements contain useful information, they can alter the + layout of a document given appropriate styling. This directive is most + useful when you are processing machine-generated HTML, please avoid using + it on regular user HTML. +

        +

        + Elements that contain only whitespace will be treated as empty. Non-breaking + spaces, however, do not count as whitespace. See + %AutoFormat.RemoveEmpty.RemoveNbsp for alternate behavior. +

        +

        + This algorithm is not perfect; you may still notice some empty tags, + particularly if a node had elements, but those elements were later removed + because they were not permitted in that context, or tags that, after + being auto-closed by another tag, where empty. This is for safety reasons + to prevent clever code from breaking validation. The general rule of thumb: + if a tag looked empty on the way in, it will get removed; if HTML Purifier + made it empty, it will stay. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt new file mode 100644 index 0000000..dde990a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/AutoFormat.RemoveSpansWithoutAttributes.txt @@ -0,0 +1,11 @@ +AutoFormat.RemoveSpansWithoutAttributes +TYPE: bool +VERSION: 4.0.1 +DEFAULT: false +--DESCRIPTION-- +

        + This directive causes span tags without any attributes + to be removed. It will also remove spans that had all attributes + removed during processing. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt new file mode 100644 index 0000000..4d054b1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowDuplicates.txt @@ -0,0 +1,11 @@ +CSS.AllowDuplicates +TYPE: bool +DEFAULT: false +VERSION: 4.8.0 +--DESCRIPTION-- +

        + By default, HTML Purifier removes duplicate CSS properties, + like color:red; color:blue. If this is set to + true, duplicate properties are allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt new file mode 100644 index 0000000..b324608 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowImportant.txt @@ -0,0 +1,8 @@ +CSS.AllowImportant +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not !important cascade modifiers should +be allowed in user CSS. If false, !important will stripped. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt new file mode 100644 index 0000000..748be0e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowTricky.txt @@ -0,0 +1,11 @@ +CSS.AllowTricky +TYPE: bool +DEFAULT: false +VERSION: 3.1.0 +--DESCRIPTION-- +This parameter determines whether or not to allow "tricky" CSS properties and +values. Tricky CSS properties/values can drastically modify page layout or +be used for deceptive practices but do not directly constitute a security risk. +For example, display:none; is considered a tricky property that +will only be allowed if this directive is set to true. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt new file mode 100644 index 0000000..3fd4654 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedFonts.txt @@ -0,0 +1,12 @@ +CSS.AllowedFonts +TYPE: lookup/null +VERSION: 4.3.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + Allows you to manually specify a set of allowed fonts. If + NULL, all fonts are allowed. This directive + affects generic names (serif, sans-serif, monospace, cursive, + fantasy) as well as specific font families. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt new file mode 100644 index 0000000..460112e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.AllowedProperties.txt @@ -0,0 +1,18 @@ +CSS.AllowedProperties +TYPE: lookup/null +VERSION: 3.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's style attributes set is unsatisfactory for your needs, + you can overload it with your own list of tags to allow. Note that this + method is subtractive: it does its job by taking away from HTML Purifier + usual feature set, so you cannot add an attribute that HTML Purifier never + supported in the first place. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt new file mode 100644 index 0000000..5cb7dda --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.DefinitionRev.txt @@ -0,0 +1,11 @@ +CSS.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt new file mode 100644 index 0000000..f1f5c5f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.ForbiddenProperties.txt @@ -0,0 +1,13 @@ +CSS.ForbiddenProperties +TYPE: lookup +VERSION: 4.2.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This is the logical inverse of %CSS.AllowedProperties, and it will + override that directive or any other directive. If possible, + %CSS.AllowedProperties is recommended over this directive, + because it can sometimes be difficult to tell whether or not you've + forbidden all of the CSS properties you truly would like to disallow. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt new file mode 100644 index 0000000..7a32914 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.MaxImgLength.txt @@ -0,0 +1,16 @@ +CSS.MaxImgLength +TYPE: string/null +DEFAULT: '1200px' +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This parameter sets the maximum allowed length on img tags, + effectively the width and height properties. + Only absolute units of measurement (in, pt, pc, mm, cm) and pixels (px) are allowed. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %HTML.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the CSS max is a number with + a unit). +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt new file mode 100644 index 0000000..148eedb --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Proprietary.txt @@ -0,0 +1,10 @@ +CSS.Proprietary +TYPE: bool +VERSION: 3.0.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Whether or not to allow safe, proprietary CSS values. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt new file mode 100644 index 0000000..e733a61 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/CSS.Trusted.txt @@ -0,0 +1,9 @@ +CSS.Trusted +TYPE: bool +VERSION: 4.2.1 +DEFAULT: false +--DESCRIPTION-- +Indicates whether or not the user's CSS input is trusted or not. If the +input is trusted, a more expansive set of allowed properties. See +also %HTML.Trusted. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt new file mode 100644 index 0000000..c486724 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.DefinitionImpl.txt @@ -0,0 +1,14 @@ +Cache.DefinitionImpl +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: 'Serializer' +--DESCRIPTION-- + +This directive defines which method to use when caching definitions, +the complex data-type that makes HTML Purifier tick. Set to null +to disable caching (not recommended, as you will see a definite +performance degradation). + +--ALIASES-- +Core.DefinitionCache +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt new file mode 100644 index 0000000..5403650 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPath.txt @@ -0,0 +1,13 @@ +Cache.SerializerPath +TYPE: string/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Absolute path with no trailing slash to store serialized definitions in. + Default is within the + HTML Purifier library inside DefinitionCache/Serializer. This + path must be writable by the webserver. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt new file mode 100644 index 0000000..2e0cc81 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Cache.SerializerPermissions.txt @@ -0,0 +1,16 @@ +Cache.SerializerPermissions +TYPE: int/null +VERSION: 4.3.0 +DEFAULT: 0755 +--DESCRIPTION-- + +

        + Directory permissions of the files and directories created inside + the DefinitionCache/Serializer or other custom serializer path. +

        +

        + In HTML Purifier 4.8.0, this also supports NULL, + which means that no chmod'ing or directory creation shall + occur. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt new file mode 100644 index 0000000..568cbf3 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AggressivelyFixLt.txt @@ -0,0 +1,18 @@ +Core.AggressivelyFixLt +TYPE: bool +VERSION: 2.1.0 +DEFAULT: true +--DESCRIPTION-- +

        + This directive enables aggressive pre-filter fixes HTML Purifier can + perform in order to ensure that open angled-brackets do not get killed + during parsing stage. Enabling this will result in two preg_replace_callback + calls and at least two preg_replace calls for every HTML document parsed; + if your users make very well-formed HTML, you can set this directive false. + This has no effect when DirectLex is used. +

        +

        + Notice: This directive's default turned from false to true + in HTML Purifier 3.2.0. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt new file mode 100644 index 0000000..2c910cc --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.AllowHostnameUnderscore.txt @@ -0,0 +1,16 @@ +Core.AllowHostnameUnderscore +TYPE: bool +VERSION: 4.6.0 +DEFAULT: false +--DESCRIPTION-- +

        + By RFC 1123, underscores are not permitted in host names. + (This is in contrast to the specification for DNS, RFC + 2181, which allows underscores.) + However, most browsers do the right thing when faced with + an underscore in the host name, and so some poorly written + websites are written with the expectation this should work. + Setting this parameter to true relaxes our allowed character + check so that underscores are permitted. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt new file mode 100644 index 0000000..d731791 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.CollectErrors.txt @@ -0,0 +1,12 @@ +Core.CollectErrors +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- + +Whether or not to collect errors found while filtering the document. This +is a useful way to give feedback to your users. Warning: +Currently this feature is very patchy and experimental, with lots of +possible error messages not yet implemented. It will not cause any +problems, but it may not help your users either. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt new file mode 100644 index 0000000..c572c14 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ColorKeywords.txt @@ -0,0 +1,29 @@ +Core.ColorKeywords +TYPE: hash +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'maroon' => '#800000', + 'red' => '#FF0000', + 'orange' => '#FFA500', + 'yellow' => '#FFFF00', + 'olive' => '#808000', + 'purple' => '#800080', + 'fuchsia' => '#FF00FF', + 'white' => '#FFFFFF', + 'lime' => '#00FF00', + 'green' => '#008000', + 'navy' => '#000080', + 'blue' => '#0000FF', + 'aqua' => '#00FFFF', + 'teal' => '#008080', + 'black' => '#000000', + 'silver' => '#C0C0C0', + 'gray' => '#808080', +) +--DESCRIPTION-- + +Lookup array of color names to six digit hexadecimal number corresponding +to color, with preceding hash mark. Used when parsing colors. The lookup +is done in a case-insensitive manner. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt new file mode 100644 index 0000000..64b114f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.ConvertDocumentToFragment.txt @@ -0,0 +1,14 @@ +Core.ConvertDocumentToFragment +TYPE: bool +DEFAULT: true +--DESCRIPTION-- + +This parameter determines whether or not the filter should convert +input that is a full document with html and body tags to a fragment +of just the contents of a body tag. This parameter is simply something +HTML Purifier can do during an edge-case: for most inputs, this +processing is not necessary. + +--ALIASES-- +Core.AcceptFullDocuments +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt new file mode 100644 index 0000000..36f16e0 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DirectLexLineNumberSyncInterval.txt @@ -0,0 +1,17 @@ +Core.DirectLexLineNumberSyncInterval +TYPE: int +VERSION: 2.0.0 +DEFAULT: 0 +--DESCRIPTION-- + +

        + Specifies the number of tokens the DirectLex line number tracking + implementations should process before attempting to resyncronize the + current line count by manually counting all previous new-lines. When + at 0, this functionality is disabled. Lower values will decrease + performance, and this is only strictly necessary if the counting + algorithm is buggy (in which case you should report it as a bug). + This has no effect when %Core.MaintainLineNumbers is disabled or DirectLex is + not being used. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt new file mode 100644 index 0000000..1cd4c2c --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.DisableExcludes.txt @@ -0,0 +1,14 @@ +Core.DisableExcludes +TYPE: bool +DEFAULT: false +VERSION: 4.5.0 +--DESCRIPTION-- +

        + This directive disables SGML-style exclusions, e.g. the exclusion of + <object> in any descendant of a + <pre> tag. Disabling excludes will allow some + invalid documents to pass through HTML Purifier, but HTML Purifier + will also be less likely to accidentally remove large documents during + processing. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt new file mode 100644 index 0000000..ce243c3 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EnableIDNA.txt @@ -0,0 +1,9 @@ +Core.EnableIDNA +TYPE: bool +DEFAULT: false +VERSION: 4.4.0 +--DESCRIPTION-- +Allows international domain names in URLs. This configuration option +requires the PEAR Net_IDNA2 module to be installed. It operates by +punycoding any internationalized host names for maximum portability. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt new file mode 100644 index 0000000..8bfb47c --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Encoding.txt @@ -0,0 +1,15 @@ +Core.Encoding +TYPE: istring +DEFAULT: 'utf-8' +--DESCRIPTION-- +If for some reason you are unable to convert all webpages to UTF-8, you can +use this directive as a stop-gap compatibility change to let HTML Purifier +deal with non UTF-8 input. This technique has notable deficiencies: +absolutely no characters outside of the selected character encoding will be +preserved, not even the ones that have been ampersand escaped (this is due +to a UTF-8 specific feature that automatically resolves all +entities), making it pretty useless for anything except the most I18N-blind +applications, although %Core.EscapeNonASCIICharacters offers fixes this +trouble with another tradeoff. This directive only accepts ISO-8859-1 if +iconv is not enabled. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt new file mode 100644 index 0000000..a3881be --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidChildren.txt @@ -0,0 +1,12 @@ +Core.EscapeInvalidChildren +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +

        Warning: this configuration option is no longer does anything as of 4.6.0.

        + +

        When true, a child is found that is not allowed in the context of the +parent element will be transformed into text as if it were ASCII. When +false, that element and all internal tags will be dropped, though text will +be preserved. There is no option for dropping the element but preserving +child nodes.

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt new file mode 100644 index 0000000..a7a5b24 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeInvalidTags.txt @@ -0,0 +1,7 @@ +Core.EscapeInvalidTags +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When true, invalid tags will be written back to the document as plain text. +Otherwise, they are silently dropped. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt new file mode 100644 index 0000000..abb4999 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.EscapeNonASCIICharacters.txt @@ -0,0 +1,13 @@ +Core.EscapeNonASCIICharacters +TYPE: bool +VERSION: 1.4.0 +DEFAULT: false +--DESCRIPTION-- +This directive overcomes a deficiency in %Core.Encoding by blindly +converting all non-ASCII characters into decimal numeric entities before +converting it to its native encoding. This means that even characters that +can be expressed in the non-UTF-8 encoding will be entity-ized, which can +be a real downer for encodings like Big5. It also assumes that the ASCII +repetoire is available, although this is the case for almost all encodings. +Anyway, use UTF-8! +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt new file mode 100644 index 0000000..915391e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.HiddenElements.txt @@ -0,0 +1,19 @@ +Core.HiddenElements +TYPE: lookup +--DEFAULT-- +array ( + 'script' => true, + 'style' => true, +) +--DESCRIPTION-- + +

        + This directive is a lookup array of elements which should have their + contents removed when they are not allowed by the HTML definition. + For example, the contents of a script tag are not + normally shown in a document, so if script tags are to be removed, + their contents should be removed to. This is opposed to a b + tag, which defines some presentational changes but does not hide its + contents. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt new file mode 100644 index 0000000..233fca1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.Language.txt @@ -0,0 +1,10 @@ +Core.Language +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'en' +--DESCRIPTION-- + +ISO 639 language code for localizable things in HTML Purifier to use, +which is mainly error reporting. There is currently only an English (en) +translation, so this directive is currently useless. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt new file mode 100644 index 0000000..8983e2c --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.LexerImpl.txt @@ -0,0 +1,34 @@ +Core.LexerImpl +TYPE: mixed/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This parameter determines what lexer implementation can be used. The + valid values are: +

        +
        +
        null
        +
        + Recommended, the lexer implementation will be auto-detected based on + your PHP-version and configuration. +
        +
        string lexer identifier
        +
        + This is a slim way of manually overridding the implementation. + Currently recognized values are: DOMLex (the default PHP5 +implementation) + and DirectLex (the default PHP4 implementation). Only use this if + you know what you are doing: usually, the auto-detection will + manage things for cases you aren't even aware of. +
        +
        object lexer instance
        +
        + Super-advanced: you can specify your own, custom, implementation that + implements the interface defined by HTMLPurifier_Lexer. + I may remove this option simply because I don't expect anyone + to use it. +
        +
        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt new file mode 100644 index 0000000..eb841a7 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.MaintainLineNumbers.txt @@ -0,0 +1,16 @@ +Core.MaintainLineNumbers +TYPE: bool/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If true, HTML Purifier will add line number information to all tokens. + This is useful when error reporting is turned on, but can result in + significant performance degradation and should not be used when + unnecessary. This directive must be used with the DirectLex lexer, + as the DOMLex lexer does not (yet) support this functionality. + If the value is null, an appropriate value will be selected based + on other configuration. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt new file mode 100644 index 0000000..d77f536 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.NormalizeNewlines.txt @@ -0,0 +1,11 @@ +Core.NormalizeNewlines +TYPE: bool +VERSION: 4.2.0 +DEFAULT: true +--DESCRIPTION-- +

        + Whether or not to normalize newlines to the operating + system default. When false, HTML Purifier + will attempt to preserve mixed newline files. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt new file mode 100644 index 0000000..4070c2a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveInvalidImg.txt @@ -0,0 +1,12 @@ +Core.RemoveInvalidImg +TYPE: bool +DEFAULT: true +VERSION: 1.3.0 +--DESCRIPTION-- + +

        + This directive enables pre-emptive URI checking in img + tags, as the attribute validation strategy is not authorized to + remove elements from the document. Revert to pre-1.3.0 behavior by setting to false. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt new file mode 100644 index 0000000..3397d9f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveProcessingInstructions.txt @@ -0,0 +1,11 @@ +Core.RemoveProcessingInstructions +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +Instead of escaping processing instructions in the form <? ... +?>, remove it out-right. This may be useful if the HTML +you are validating contains XML processing instruction gunk, however, +it can also be user-unfriendly for people attempting to post PHP +snippets. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt new file mode 100644 index 0000000..a4cd966 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Core.RemoveScriptContents.txt @@ -0,0 +1,12 @@ +Core.RemoveScriptContents +TYPE: bool/null +DEFAULT: NULL +VERSION: 2.0.0 +DEPRECATED-VERSION: 2.1.0 +DEPRECATED-USE: Core.HiddenElements +--DESCRIPTION-- +

        + This directive enables HTML Purifier to remove not only script tags + but all of their contents. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt new file mode 100644 index 0000000..3db50ef --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.Custom.txt @@ -0,0 +1,11 @@ +Filter.Custom +TYPE: list +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This directive can be used to add custom filters; it is nearly the + equivalent of the now deprecated HTMLPurifier->addFilter() + method. Specify an array of concrete implementations. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt new file mode 100644 index 0000000..16829bc --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Escaping.txt @@ -0,0 +1,14 @@ +Filter.ExtractStyleBlocks.Escaping +TYPE: bool +VERSION: 3.0.0 +DEFAULT: true +ALIASES: Filter.ExtractStyleBlocksEscaping, FilterParam.ExtractStyleBlocksEscaping +--DESCRIPTION-- + +

        + Whether or not to escape the dangerous characters <, > and & + as \3C, \3E and \26, respectively. This is can be safely set to false + if the contents of StyleBlocks will be placed in an external stylesheet, + where there is no risk of it being interpreted as HTML. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt new file mode 100644 index 0000000..7f95f54 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.Scope.txt @@ -0,0 +1,29 @@ +Filter.ExtractStyleBlocks.Scope +TYPE: string/null +VERSION: 3.0.0 +DEFAULT: NULL +ALIASES: Filter.ExtractStyleBlocksScope, FilterParam.ExtractStyleBlocksScope +--DESCRIPTION-- + +

        + If you would like users to be able to define external stylesheets, but + only allow them to specify CSS declarations for a specific node and + prevent them from fiddling with other elements, use this directive. + It accepts any valid CSS selector, and will prepend this to any + CSS declaration extracted from the document. For example, if this + directive is set to #user-content and a user uses the + selector a:hover, the final selector will be + #user-content a:hover. +

        +

        + The comma shorthand may be used; consider the above example, with + #user-content, #user-content2, the final selector will + be #user-content a:hover, #user-content2 a:hover. +

        +

        + Warning: It is possible for users to bypass this measure + using a naughty + selector. This is a bug in CSS Tidy 1.3, not HTML + Purifier, and I am working to get it fixed. Until then, HTML Purifier + performs a basic check to prevent this. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt new file mode 100644 index 0000000..6c231b2 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.TidyImpl.txt @@ -0,0 +1,16 @@ +Filter.ExtractStyleBlocks.TidyImpl +TYPE: mixed/null +VERSION: 3.1.0 +DEFAULT: NULL +ALIASES: FilterParam.ExtractStyleBlocksTidyImpl +--DESCRIPTION-- +

        + If left NULL, HTML Purifier will attempt to instantiate a csstidy + class to use for internal cleaning. This will usually be good enough. +

        +

        + However, for trusted user input, you can set this to false to + disable cleaning. In addition, you can supply your own concrete implementation + of Tidy's interface to use, although I don't know why you'd want to do that. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt new file mode 100644 index 0000000..078d087 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.ExtractStyleBlocks.txt @@ -0,0 +1,74 @@ +Filter.ExtractStyleBlocks +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +EXTERNAL: CSSTidy +--DESCRIPTION-- +

        + This directive turns on the style block extraction filter, which removes + style blocks from input HTML, cleans them up with CSSTidy, + and places them in the StyleBlocks context variable, for further + use by you, usually to be placed in an external stylesheet, or a + style block in the head of your document. +

        +

        + Sample usage: +

        +
        ';
        +?>
        +
        +
        +
        +  Filter.ExtractStyleBlocks
        +body {color:#F00;} Some text';
        +
        +    $config = HTMLPurifier_Config::createDefault();
        +    $config->set('Filter', 'ExtractStyleBlocks', true);
        +    $purifier = new HTMLPurifier($config);
        +
        +    $html = $purifier->purify($dirty);
        +
        +    // This implementation writes the stylesheets to the styles/ directory.
        +    // You can also echo the styles inside the document, but it's a bit
        +    // more difficult to make sure they get interpreted properly by
        +    // browsers; try the usual CSS armoring techniques.
        +    $styles = $purifier->context->get('StyleBlocks');
        +    $dir = 'styles/';
        +    if (!is_dir($dir)) mkdir($dir);
        +    $hash = sha1($_GET['html']);
        +    foreach ($styles as $i => $style) {
        +        file_put_contents($name = $dir . $hash . "_$i");
        +        echo '';
        +    }
        +?>
        +
        +
        +  
        + +
        + + +]]>
        +

        + Warning: It is possible for a user to mount an + imagecrash attack using this CSS. Counter-measures are difficult; + it is not simply enough to limit the range of CSS lengths (using + relative lengths with many nesting levels allows for large values + to be attained without actually specifying them in the stylesheet), + and the flexible nature of selectors makes it difficult to selectively + disable lengths on image tags (HTML Purifier, however, does disable + CSS width and height in inline styling). There are probably two effective + counter measures: an explicit width and height set to auto in all + images in your document (unlikely) or the disabling of width and + height (somewhat reasonable). Whether or not these measures should be + used is left to the reader. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt new file mode 100644 index 0000000..321eaa2 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Filter.YouTube.txt @@ -0,0 +1,16 @@ +Filter.YouTube +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + Warning: Deprecated in favor of %HTML.SafeObject and + %Output.FlashCompat (turn both on to allow YouTube videos and other + Flash content). +

        +

        + This directive enables YouTube video embedding in HTML Purifier. Check + this document + on embedding videos for more information on what this filter does. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt new file mode 100644 index 0000000..0b2c106 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Allowed.txt @@ -0,0 +1,25 @@ +HTML.Allowed +TYPE: itext/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + This is a preferred convenience directive that combines + %HTML.AllowedElements and %HTML.AllowedAttributes. + Specify elements and attributes that are allowed using: + element1[attr1|attr2],element2.... For example, + if you would like to only allow paragraphs and links, specify + a[href],p. You can specify attributes that apply + to all elements using an asterisk, e.g. *[lang]. + You can also use newlines instead of commas to separate elements. +

        +

        + Warning: + All of the constraints on the component directives are still enforced. + The syntax is a subset of TinyMCE's valid_elements + whitelist: directly copy-pasting it here will probably result in + broken whitelists. If %HTML.AllowedElements or %HTML.AllowedAttributes + are set, this directive has no effect. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt new file mode 100644 index 0000000..fcf093f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedAttributes.txt @@ -0,0 +1,19 @@ +HTML.AllowedAttributes +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + If HTML Purifier's attribute set is unsatisfactory, overload it! + The syntax is "tag.attr" or "*.attr" for the global attributes + (style, id, class, dir, lang, xml:lang). +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. For + example, %HTML.EnableAttrID will take precedence over *.id in this + directive. You must set that directive to true before you can use + IDs at all. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt new file mode 100644 index 0000000..140e214 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedComments.txt @@ -0,0 +1,10 @@ +HTML.AllowedComments +TYPE: lookup +VERSION: 4.4.0 +DEFAULT: array() +--DESCRIPTION-- +A whitelist which indicates what explicit comment bodies should be +allowed, modulo leading and trailing whitespace. See also %HTML.AllowedCommentsRegexp +(these directives are union'ed together, so a comment is considered +valid if any directive deems it valid.) +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt new file mode 100644 index 0000000..f22e977 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedCommentsRegexp.txt @@ -0,0 +1,15 @@ +HTML.AllowedCommentsRegexp +TYPE: string/null +VERSION: 4.4.0 +DEFAULT: NULL +--DESCRIPTION-- +A regexp, which if it matches the body of a comment, indicates that +it should be allowed. Trailing and leading spaces are removed prior +to running this regular expression. +Warning: Make sure you specify +correct anchor metacharacters ^regex$, otherwise you may accept +comments that you did not mean to! In particular, the regex /foo|bar/ +is probably not sufficiently strict, since it also allows foobar. +See also %HTML.AllowedComments (these directives are union'ed together, +so a comment is considered valid if any directive deems it valid.) +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt new file mode 100644 index 0000000..1d3fa79 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedElements.txt @@ -0,0 +1,23 @@ +HTML.AllowedElements +TYPE: lookup/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + If HTML Purifier's tag set is unsatisfactory for your needs, you can + overload it with your own list of tags to allow. If you change + this, you probably also want to change %HTML.AllowedAttributes; see + also %HTML.Allowed which lets you set allowed elements and + attributes at the same time. +

        +

        + If you attempt to allow an element that HTML Purifier does not know + about, HTML Purifier will raise an error. You will need to manually + tell HTML Purifier about this element by using the + advanced customization features. +

        +

        + Warning: If another directive conflicts with the + elements here, that directive will win and override. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt new file mode 100644 index 0000000..5a59a55 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.AllowedModules.txt @@ -0,0 +1,20 @@ +HTML.AllowedModules +TYPE: lookup/null +VERSION: 2.0.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + A doctype comes with a set of usual modules to use. Without having + to mucking about with the doctypes, you can quickly activate or + disable these modules by specifying which modules you wish to allow + with this directive. This is most useful for unit testing specific + modules, although end users may find it useful for their own ends. +

        +

        + If you specify a module that does not exist, the manager will silently + fail to use it, so be careful! User-defined modules are not affected + by this directive. Modules defined in %HTML.CoreModules are not + affected by this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt new file mode 100644 index 0000000..151fb7b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Attr.Name.UseCDATA.txt @@ -0,0 +1,11 @@ +HTML.Attr.Name.UseCDATA +TYPE: bool +DEFAULT: false +VERSION: 4.0.0 +--DESCRIPTION-- +The W3C specification DTD defines the name attribute to be CDATA, not ID, due +to limitations of DTD. In certain documents, this relaxed behavior is desired, +whether it is to specify duplicate names, or to specify names that would be +illegal IDs (for example, names that begin with a digit.) Set this configuration +directive to true to use the relaxed parsing rules. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt new file mode 100644 index 0000000..45ae469 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.BlockWrapper.txt @@ -0,0 +1,18 @@ +HTML.BlockWrapper +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'p' +--DESCRIPTION-- + +

        + String name of element to wrap inline elements that are inside a block + context. This only occurs in the children of blockquote in strict mode. +

        +

        + Example: by default value, + <blockquote>Foo</blockquote> would become + <blockquote><p>Foo</p></blockquote>. + The <p> tags can be replaced with whatever you desire, + as long as it is a block level element. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt new file mode 100644 index 0000000..5246188 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CoreModules.txt @@ -0,0 +1,23 @@ +HTML.CoreModules +TYPE: lookup +VERSION: 2.0.0 +--DEFAULT-- +array ( + 'Structure' => true, + 'Text' => true, + 'Hypertext' => true, + 'List' => true, + 'NonXMLCommonAttributes' => true, + 'XMLCommonAttributes' => true, + 'CommonAttributes' => true, +) +--DESCRIPTION-- + +

        + Certain modularized doctypes (XHTML, namely), have certain modules + that must be included for the doctype to be an conforming document + type: put those modules here. By default, XHTML's core modules + are used. You can set this to a blank array to disable core module + protection, but this is not recommended. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt new file mode 100644 index 0000000..6ed70b5 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.CustomDoctype.txt @@ -0,0 +1,9 @@ +HTML.CustomDoctype +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +A custom doctype for power-users who defined their own document +type. This directive only applies when %HTML.Doctype is blank. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt new file mode 100644 index 0000000..103db75 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionID.txt @@ -0,0 +1,33 @@ +HTML.DefinitionID +TYPE: string/null +DEFAULT: NULL +VERSION: 2.0.0 +--DESCRIPTION-- + +

        + Unique identifier for a custom-built HTML definition. If you edit + the raw version of the HTMLDefinition, introducing changes that the + configuration object does not reflect, you must specify this variable. + If you change your custom edits, you should change this directive, or + clear your cache. Example: +

        +
        +$config = HTMLPurifier_Config::createDefault();
        +$config->set('HTML', 'DefinitionID', '1');
        +$def = $config->getHTMLDefinition();
        +$def->addAttribute('a', 'tabindex', 'Number');
        +
        +

        + In the above example, the configuration is still at the defaults, but + using the advanced API, an extra attribute has been added. The + configuration object normally has no way of knowing that this change + has taken place, so it needs an extra directive: %HTML.DefinitionID. + If someone else attempts to use the default configuration, these two + pieces of code will not clobber each other in the cache, since one has + an extra directive attached to it. +

        +

        + You must specify a value to this directive to use the + advanced API features. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt new file mode 100644 index 0000000..229ae02 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.DefinitionRev.txt @@ -0,0 +1,16 @@ +HTML.DefinitionRev +TYPE: int +VERSION: 2.0.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition specified in + %HTML.DefinitionID. This serves the same purpose: uniquely identifying + your custom definition, but this one does so in a chronological + context: revision 3 is more up-to-date then revision 2. Thus, when + this gets incremented, the cache handling is smart enough to clean + up any older revisions of your definition as well as flush the + cache. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt new file mode 100644 index 0000000..9dab497 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Doctype.txt @@ -0,0 +1,11 @@ +HTML.Doctype +TYPE: string/null +DEFAULT: NULL +--DESCRIPTION-- +Doctype to use during filtering. Technically speaking this is not actually +a doctype (as it does not identify a corresponding DTD), but we are using +this name for sake of simplicity. When non-blank, this will override any +older directives like %HTML.XHTML or %HTML.Strict. +--ALLOWED-- +'HTML 4.01 Transitional', 'HTML 4.01 Strict', 'XHTML 1.0 Transitional', 'XHTML 1.0 Strict', 'XHTML 1.1' +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt new file mode 100644 index 0000000..7878dc0 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.FlashAllowFullScreen.txt @@ -0,0 +1,11 @@ +HTML.FlashAllowFullScreen +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit embedded Flash content from + %HTML.SafeObject to expand to the full screen. Corresponds to + the allowFullScreen parameter. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt new file mode 100644 index 0000000..57358f9 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenAttributes.txt @@ -0,0 +1,21 @@ +HTML.ForbiddenAttributes +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + While this directive is similar to %HTML.AllowedAttributes, for + forwards-compatibility with XML, this attribute has a different syntax. Instead of + tag.attr, use tag@attr. To disallow href + attributes in a tags, set this directive to + a@href. You can also disallow an attribute globally with + attr or *@attr (either syntax is fine; the latter + is provided for consistency with %HTML.AllowedAttributes). +

        +

        + Warning: This directive complements %HTML.ForbiddenElements, + accordingly, check + out that directive for a discussion of why you + should think twice before using this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt new file mode 100644 index 0000000..93a53e1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.ForbiddenElements.txt @@ -0,0 +1,20 @@ +HTML.ForbiddenElements +TYPE: lookup +VERSION: 3.1.0 +DEFAULT: array() +--DESCRIPTION-- +

        + This was, perhaps, the most requested feature ever in HTML + Purifier. Please don't abuse it! This is the logical inverse of + %HTML.AllowedElements, and it will override that directive, or any + other directive. +

        +

        + If possible, %HTML.Allowed is recommended over this directive, because it + can sometimes be difficult to tell whether or not you've forbidden all of + the behavior you would like to disallow. If you forbid img + with the expectation of preventing images on your site, you'll be in for + a nasty surprise when people start using the background-image + CSS property. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt new file mode 100644 index 0000000..e424c38 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.MaxImgLength.txt @@ -0,0 +1,14 @@ +HTML.MaxImgLength +TYPE: int/null +DEFAULT: 1200 +VERSION: 3.1.1 +--DESCRIPTION-- +

        + This directive controls the maximum number of pixels in the width and + height attributes in img tags. This is + in place to prevent imagecrash attacks, disable with null at your own risk. + This directive is similar to %CSS.MaxImgLength, and both should be + concurrently edited, although there are + subtle differences in the input format (the HTML max is an integer). +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt new file mode 100644 index 0000000..700b309 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Nofollow.txt @@ -0,0 +1,7 @@ +HTML.Nofollow +TYPE: bool +VERSION: 4.3.0 +DEFAULT: FALSE +--DESCRIPTION-- +If enabled, nofollow rel attributes are added to all outgoing links. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt new file mode 100644 index 0000000..62e8e16 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Parent.txt @@ -0,0 +1,12 @@ +HTML.Parent +TYPE: string +VERSION: 1.3.0 +DEFAULT: 'div' +--DESCRIPTION-- + +

        + String name of element that HTML fragment passed to library will be + inserted in. An interesting variation would be using span as the + parent element, meaning that only inline tags would be allowed. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt new file mode 100644 index 0000000..dfb7204 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Proprietary.txt @@ -0,0 +1,12 @@ +HTML.Proprietary +TYPE: bool +VERSION: 3.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to allow proprietary elements and attributes in your + documents, as per HTMLPurifier_HTMLModule_Proprietary. + Warning: This can cause your documents to stop + validating! +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt new file mode 100644 index 0000000..cdda09a --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeEmbed.txt @@ -0,0 +1,13 @@ +HTML.SafeEmbed +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit embed tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to embed tags. Embed is a proprietary + element and will cause your website to stop validating; you should + see if you can use %Output.FlashCompat with %HTML.SafeObject instead + first.

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt new file mode 100644 index 0000000..5eb6ec2 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeIframe.txt @@ -0,0 +1,13 @@ +HTML.SafeIframe +TYPE: bool +VERSION: 4.4.0 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit iframe tags in untrusted documents. This + directive must be accompanied by a whitelist of permitted iframes, + such as %URI.SafeIframeRegexp, otherwise it will fatally error. + This directive has no effect on strict doctypes, as iframes are not + valid. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt new file mode 100644 index 0000000..ceb342e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeObject.txt @@ -0,0 +1,13 @@ +HTML.SafeObject +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Whether or not to permit object tags in documents, with a number of extra + security features added to prevent script execution. This is similar to + what websites like MySpace do to object tags. You should also enable + %Output.FlashCompat in order to generate Internet Explorer + compatibility code for your object tags. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt new file mode 100644 index 0000000..5ebc7a1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.SafeScripting.txt @@ -0,0 +1,10 @@ +HTML.SafeScripting +TYPE: lookup +VERSION: 4.5.0 +DEFAULT: array() +--DESCRIPTION-- +

        + Whether or not to permit script tags to external scripts in documents. + Inline scripting is not allowed, and the script must match an explicit whitelist. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt new file mode 100644 index 0000000..a8b1de5 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Strict.txt @@ -0,0 +1,9 @@ +HTML.Strict +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not to use Transitional (loose) or Strict rulesets. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt new file mode 100644 index 0000000..587a167 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetBlank.txt @@ -0,0 +1,8 @@ +HTML.TargetBlank +TYPE: bool +VERSION: 4.4.0 +DEFAULT: FALSE +--DESCRIPTION-- +If enabled, target=blank attributes are added to all outgoing links. +(This includes links from an HTTPS version of a page to an HTTP version.) +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt new file mode 100644 index 0000000..cb5a0b0 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TargetNoreferrer.txt @@ -0,0 +1,9 @@ +HTML.TargetNoreferrer +TYPE: bool +VERSION: 4.8.0 +DEFAULT: TRUE +--DESCRIPTION-- +If enabled, noreferrer rel attributes are added to links which have +a target attribute associated with them. This prevents malicious +destinations from overwriting the original window. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt new file mode 100644 index 0000000..b4c271b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyAdd.txt @@ -0,0 +1,8 @@ +HTML.TidyAdd +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to add to the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt new file mode 100644 index 0000000..4186ccd --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyLevel.txt @@ -0,0 +1,24 @@ +HTML.TidyLevel +TYPE: string +VERSION: 2.0.0 +DEFAULT: 'medium' +--DESCRIPTION-- + +

        General level of cleanliness the Tidy module should enforce. +There are four allowed values:

        +
        +
        none
        +
        No extra tidying should be done
        +
        light
        +
        Only fix elements that would be discarded otherwise due to + lack of support in doctype
        +
        medium
        +
        Enforce best practices
        +
        heavy
        +
        Transform all deprecated elements and attributes to standards + compliant equivalents
        +
        + +--ALLOWED-- +'none', 'light', 'medium', 'heavy' +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt new file mode 100644 index 0000000..996762b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.TidyRemove.txt @@ -0,0 +1,8 @@ +HTML.TidyRemove +TYPE: lookup +VERSION: 2.0.0 +DEFAULT: array() +--DESCRIPTION-- + +Fixes to remove from the default set of Tidy fixes as per your level. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt new file mode 100644 index 0000000..1db9237 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.Trusted.txt @@ -0,0 +1,9 @@ +HTML.Trusted +TYPE: bool +VERSION: 2.0.0 +DEFAULT: false +--DESCRIPTION-- +Indicates whether or not the user input is trusted or not. If the input is +trusted, a more expansive set of allowed tags and attributes will be used. +See also %CSS.Trusted. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt new file mode 100644 index 0000000..2a47e38 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/HTML.XHTML.txt @@ -0,0 +1,11 @@ +HTML.XHTML +TYPE: bool +DEFAULT: true +VERSION: 1.1.0 +DEPRECATED-VERSION: 1.7.0 +DEPRECATED-USE: HTML.Doctype +--DESCRIPTION-- +Determines whether or not output is XHTML 1.0 or HTML 4.01 flavor. +--ALIASES-- +Core.XHTML +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt new file mode 100644 index 0000000..08921fd --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.CommentScriptContents.txt @@ -0,0 +1,10 @@ +Output.CommentScriptContents +TYPE: bool +VERSION: 2.0.0 +DEFAULT: true +--DESCRIPTION-- +Determines whether or not HTML Purifier should attempt to fix up the +contents of script tags for legacy browsers with comments. +--ALIASES-- +Core.CommentScriptContents +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt new file mode 100644 index 0000000..d6f0d9f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FixInnerHTML.txt @@ -0,0 +1,15 @@ +Output.FixInnerHTML +TYPE: bool +VERSION: 4.3.0 +DEFAULT: true +--DESCRIPTION-- +

        + If true, HTML Purifier will protect against Internet Explorer's + mishandling of the innerHTML attribute by appending + a space to any attribute that does not contain angled brackets, spaces + or quotes, but contains a backtick. This slightly changes the + semantics of any given attribute, so if this is unacceptable and + you do not use innerHTML on any of your pages, you can + turn this directive off. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt new file mode 100644 index 0000000..93398e8 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.FlashCompat.txt @@ -0,0 +1,11 @@ +Output.FlashCompat +TYPE: bool +VERSION: 4.1.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will generate Internet Explorer compatibility + code for all object code. This is highly recommended if you enable + %HTML.SafeObject. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt new file mode 100644 index 0000000..79f8ad8 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.Newline.txt @@ -0,0 +1,13 @@ +Output.Newline +TYPE: string/null +VERSION: 2.0.1 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Newline string to format final output with. If left null, HTML Purifier + will auto-detect the default newline type of the system and use that; + you can manually override it here. Remember, \r\n is Windows, \r + is Mac, and \n is Unix. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt new file mode 100644 index 0000000..232b023 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.SortAttr.txt @@ -0,0 +1,14 @@ +Output.SortAttr +TYPE: bool +VERSION: 3.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + If true, HTML Purifier will sort attributes by name before writing them back + to the document, converting a tag like: <el b="" a="" c="" /> + to <el a="" b="" c="" />. This is a workaround for + a bug in FCKeditor which causes it to swap attributes order, adding noise + to text diffs. If you're not seeing this bug, chances are, you don't need + this directive. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt new file mode 100644 index 0000000..06bab00 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Output.TidyFormat.txt @@ -0,0 +1,25 @@ +Output.TidyFormat +TYPE: bool +VERSION: 1.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + Determines whether or not to run Tidy on the final output for pretty + formatting reasons, such as indentation and wrap. +

        +

        + This can greatly improve readability for editors who are hand-editing + the HTML, but is by no means necessary as HTML Purifier has already + fixed all major errors the HTML may have had. Tidy is a non-default + extension, and this directive will silently fail if Tidy is not + available. +

        +

        + If you are looking to make the overall look of your page's source + better, I recommend running Tidy on the entire page rather than just + user-content (after all, the indentation relative to the containing + blocks will be incorrect). +

        +--ALIASES-- +Core.TidyFormat +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt new file mode 100644 index 0000000..071bc02 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/Test.ForceNoIconv.txt @@ -0,0 +1,7 @@ +Test.ForceNoIconv +TYPE: bool +DEFAULT: false +--DESCRIPTION-- +When set to true, HTMLPurifier_Encoder will act as if iconv does not exist +and use only pure PHP implementations. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt new file mode 100644 index 0000000..eb97307 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.AllowedSchemes.txt @@ -0,0 +1,18 @@ +URI.AllowedSchemes +TYPE: lookup +--DEFAULT-- +array ( + 'http' => true, + 'https' => true, + 'mailto' => true, + 'ftp' => true, + 'nntp' => true, + 'news' => true, + 'tel' => true, +) +--DESCRIPTION-- +Whitelist that defines the schemes that a URI is allowed to have. This +prevents XSS attacks from using pseudo-schemes like javascript or mocha. +There is also support for the data and file +URI schemes, but they are not enabled by default. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt new file mode 100644 index 0000000..876f068 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Base.txt @@ -0,0 +1,17 @@ +URI.Base +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + The base URI is the URI of the document this purified HTML will be + inserted into. This information is important if HTML Purifier needs + to calculate absolute URIs from relative URIs, such as when %URI.MakeAbsolute + is on. You may use a non-absolute URI for this value, but behavior + may vary (%URI.MakeAbsolute deals nicely with both absolute and + relative paths, but forwards-compatibility is not guaranteed). + Warning: If set, the scheme on this URI + overrides the one specified by %URI.DefaultScheme. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt new file mode 100644 index 0000000..728e378 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefaultScheme.txt @@ -0,0 +1,10 @@ +URI.DefaultScheme +TYPE: string +DEFAULT: 'http' +--DESCRIPTION-- + +

        + Defines through what scheme the output will be served, in order to + select the proper object validator when no scheme information is present. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt new file mode 100644 index 0000000..f05312b --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionID.txt @@ -0,0 +1,11 @@ +URI.DefinitionID +TYPE: string/null +VERSION: 2.1.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Unique identifier for a custom-built URI definition. If you want + to add custom URIFilters, you must specify this value. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt new file mode 100644 index 0000000..80cfea9 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DefinitionRev.txt @@ -0,0 +1,11 @@ +URI.DefinitionRev +TYPE: int +VERSION: 2.1.0 +DEFAULT: 1 +--DESCRIPTION-- + +

        + Revision identifier for your custom definition. See + %HTML.DefinitionRev for details. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt new file mode 100644 index 0000000..71ce025 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Disable.txt @@ -0,0 +1,14 @@ +URI.Disable +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Disables all URIs in all forms. Not sure why you'd want to do that + (after all, the Internet's founded on the notion of a hyperlink). +

        + +--ALIASES-- +Attr.DisableURI +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt new file mode 100644 index 0000000..13c122c --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternal.txt @@ -0,0 +1,11 @@ +URI.DisableExternal +TYPE: bool +VERSION: 1.2.0 +DEFAULT: false +--DESCRIPTION-- +Disables links to external websites. This is a highly effective anti-spam +and anti-pagerank-leech measure, but comes at a hefty price: nolinks or +images outside of your domain will be allowed. Non-linkified URIs will +still be preserved. If you want to be able to link to subdomains or use +absolute URIs, specify %URI.Host for your website. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt new file mode 100644 index 0000000..abcc1ef --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableExternalResources.txt @@ -0,0 +1,13 @@ +URI.DisableExternalResources +TYPE: bool +VERSION: 1.3.0 +DEFAULT: false +--DESCRIPTION-- +Disables the embedding of external resources, preventing users from +embedding things like images from other hosts. This prevents access +tracking (good for email viewers), bandwidth leeching, cross-site request +forging, goatse.cx posting, and other nasties, but also results in a loss +of end-user functionality (they can't directly post a pic they posted from +Flickr anymore). Use it if you don't have a robust user-content moderation +team. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt new file mode 100644 index 0000000..f891de4 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.DisableResources.txt @@ -0,0 +1,15 @@ +URI.DisableResources +TYPE: bool +VERSION: 4.2.0 +DEFAULT: false +--DESCRIPTION-- +

        + Disables embedding resources, essentially meaning no pictures. You can + still link to them though. See %URI.DisableExternalResources for why + this might be a good idea. +

        +

        + Note: While this directive has been available since 1.3.0, + it didn't actually start doing anything until 4.2.0. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt new file mode 100644 index 0000000..ee83b12 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Host.txt @@ -0,0 +1,19 @@ +URI.Host +TYPE: string/null +VERSION: 1.2.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Defines the domain name of the server, so we can determine whether or + an absolute URI is from your website or not. Not strictly necessary, + as users should be using relative URIs to reference resources on your + website. It will, however, let you use absolute URIs to link to + subdomains of the domain you post here: i.e. example.com will allow + sub.example.com. However, higher up domains will still be excluded: + if you set %URI.Host to sub.example.com, example.com will be blocked. + Note: This directive overrides %URI.Base because + a given page may be on a sub-domain, but you wish HTML Purifier to be + more relaxed and allow some of the parent domains too. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt new file mode 100644 index 0000000..0b6df76 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.HostBlacklist.txt @@ -0,0 +1,9 @@ +URI.HostBlacklist +TYPE: list +VERSION: 1.3.0 +DEFAULT: array() +--DESCRIPTION-- +List of strings that are forbidden in the host of any URI. Use it to kill +domain names of spam, etc. Note that it will catch anything in the domain, +so moo.com will catch moo.com.example.com. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt new file mode 100644 index 0000000..4214900 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MakeAbsolute.txt @@ -0,0 +1,13 @@ +URI.MakeAbsolute +TYPE: bool +VERSION: 2.1.0 +DEFAULT: false +--DESCRIPTION-- + +

        + Converts all URIs into absolute forms. This is useful when the HTML + being filtered assumes a specific base path, but will actually be + viewed in a different context (and setting an alternate base URI is + not possible). %URI.Base must be set for this directive to work. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt new file mode 100644 index 0000000..58c81dc --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.Munge.txt @@ -0,0 +1,83 @@ +URI.Munge +TYPE: string/null +VERSION: 1.3.0 +DEFAULT: NULL +--DESCRIPTION-- + +

        + Munges all browsable (usually http, https and ftp) + absolute URIs into another URI, usually a URI redirection service. + This directive accepts a URI, formatted with a %s where + the url-encoded original URI should be inserted (sample: + http://www.google.com/url?q=%s). +

        +

        + Uses for this directive: +

        +
          +
        • + Prevent PageRank leaks, while being fairly transparent + to users (you may also want to add some client side JavaScript to + override the text in the statusbar). Notice: + Many security experts believe that this form of protection does not deter spam-bots. +
        • +
        • + Redirect users to a splash page telling them they are leaving your + website. While this is poor usability practice, it is often mandated + in corporate environments. +
        • +
        +

        + Prior to HTML Purifier 3.1.1, this directive also enabled the munging + of browsable external resources, which could break things if your redirection + script was a splash page or used meta tags. To revert to + previous behavior, please use %URI.MungeResources. +

        +

        + You may want to also use %URI.MungeSecretKey along with this directive + in order to enforce what URIs your redirector script allows. Open + redirector scripts can be a security risk and negatively affect the + reputation of your domain name. +

        +

        + Starting with HTML Purifier 3.1.1, there is also these substitutions: +

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        KeyDescriptionExample <a href="">
        %r1 - The URI embeds a resource
        (blank) - The URI is merely a link
        %nThe name of the tag this URI came froma
        %mThe name of the attribute this URI came fromhref
        %pThe name of the CSS property this URI came from, or blank if irrelevant
        +

        + Admittedly, these letters are somewhat arbitrary; the only stipulation + was that they couldn't be a through f. r is for resource (I would have preferred + e, but you take what you can get), n is for name, m + was picked because it came after n (and I couldn't use a), p is for + property. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt new file mode 100644 index 0000000..6fce0fd --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeResources.txt @@ -0,0 +1,17 @@ +URI.MungeResources +TYPE: bool +VERSION: 3.1.1 +DEFAULT: false +--DESCRIPTION-- +

        + If true, any URI munging directives like %URI.Munge + will also apply to embedded resources, such as <img src="">. + Be careful enabling this directive if you have a redirector script + that does not use the Location HTTP header; all of your images + and other embedded resources will break. +

        +

        + Warning: It is strongly advised you use this in conjunction + %URI.MungeSecretKey to mitigate the security risk of an open redirector. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt new file mode 100644 index 0000000..1e17c1d --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.MungeSecretKey.txt @@ -0,0 +1,30 @@ +URI.MungeSecretKey +TYPE: string/null +VERSION: 3.1.1 +DEFAULT: NULL +--DESCRIPTION-- +

        + This directive enables secure checksum generation along with %URI.Munge. + It should be set to a secure key that is not shared with anyone else. + The checksum can be placed in the URI using %t. Use of this checksum + affords an additional level of protection by allowing a redirector + to check if a URI has passed through HTML Purifier with this line: +

        + +
        $checksum === hash_hmac("sha256", $url, $secret_key)
        + +

        + If the output is TRUE, the redirector script should accept the URI. +

        + +

        + Please note that it would still be possible for an attacker to procure + secure hashes en-mass by abusing your website's Preview feature or the + like, but this service affords an additional level of protection + that should be combined with website blacklisting. +

        + +

        + Remember this has no effect if %URI.Munge is not on. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt new file mode 100644 index 0000000..23331a4 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.OverrideAllowedSchemes.txt @@ -0,0 +1,9 @@ +URI.OverrideAllowedSchemes +TYPE: bool +DEFAULT: true +--DESCRIPTION-- +If this is set to true (which it is by default), you can override +%URI.AllowedSchemes by simply registering a HTMLPurifier_URIScheme to the +registry. If false, you will also have to update that directive in order +to add more schemes. +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt new file mode 100644 index 0000000..7908483 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/URI.SafeIframeRegexp.txt @@ -0,0 +1,22 @@ +URI.SafeIframeRegexp +TYPE: string/null +VERSION: 4.4.0 +DEFAULT: NULL +--DESCRIPTION-- +

        + A PCRE regular expression that will be matched against an iframe URI. This is + a relatively inflexible scheme, but works well enough for the most common + use-case of iframes: embedded video. This directive only has an effect if + %HTML.SafeIframe is enabled. Here are some example values: +

        +
          +
        • %^http://www.youtube.com/embed/% - Allow YouTube videos
        • +
        • %^http://player.vimeo.com/video/% - Allow Vimeo videos
        • +
        • %^http://(www.youtube.com/embed/|player.vimeo.com/video/)% - Allow both
        • +
        +

        + Note that this directive does not give you enough granularity to, say, disable + all autoplay videos. Pipe up on the HTML Purifier forums if this + is a capability you want. +

        +--# vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/info.ini b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/info.ini new file mode 100644 index 0000000..5de4505 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/ConfigSchema/schema/info.ini @@ -0,0 +1,3 @@ +name = "HTML Purifier" + +; vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/EntityLookup/entities.ser b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/EntityLookup/entities.ser new file mode 100644 index 0000000..e8b0812 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/EntityLookup/entities.ser @@ -0,0 +1 @@ +a:253:{s:4:"fnof";s:2:"ƒ";s:5:"Alpha";s:2:"Α";s:4:"Beta";s:2:"Β";s:5:"Gamma";s:2:"Γ";s:5:"Delta";s:2:"Δ";s:7:"Epsilon";s:2:"Ε";s:4:"Zeta";s:2:"Ζ";s:3:"Eta";s:2:"Η";s:5:"Theta";s:2:"Θ";s:4:"Iota";s:2:"Ι";s:5:"Kappa";s:2:"Κ";s:6:"Lambda";s:2:"Λ";s:2:"Mu";s:2:"Μ";s:2:"Nu";s:2:"Ν";s:2:"Xi";s:2:"Ξ";s:7:"Omicron";s:2:"Ο";s:2:"Pi";s:2:"Π";s:3:"Rho";s:2:"Ρ";s:5:"Sigma";s:2:"Σ";s:3:"Tau";s:2:"Τ";s:7:"Upsilon";s:2:"Υ";s:3:"Phi";s:2:"Φ";s:3:"Chi";s:2:"Χ";s:3:"Psi";s:2:"Ψ";s:5:"Omega";s:2:"Ω";s:5:"alpha";s:2:"α";s:4:"beta";s:2:"β";s:5:"gamma";s:2:"γ";s:5:"delta";s:2:"δ";s:7:"epsilon";s:2:"ε";s:4:"zeta";s:2:"ζ";s:3:"eta";s:2:"η";s:5:"theta";s:2:"θ";s:4:"iota";s:2:"ι";s:5:"kappa";s:2:"κ";s:6:"lambda";s:2:"λ";s:2:"mu";s:2:"μ";s:2:"nu";s:2:"ν";s:2:"xi";s:2:"ξ";s:7:"omicron";s:2:"ο";s:2:"pi";s:2:"π";s:3:"rho";s:2:"ρ";s:6:"sigmaf";s:2:"ς";s:5:"sigma";s:2:"σ";s:3:"tau";s:2:"τ";s:7:"upsilon";s:2:"υ";s:3:"phi";s:2:"φ";s:3:"chi";s:2:"χ";s:3:"psi";s:2:"ψ";s:5:"omega";s:2:"ω";s:8:"thetasym";s:2:"ϑ";s:5:"upsih";s:2:"ϒ";s:3:"piv";s:2:"ϖ";s:4:"bull";s:3:"•";s:6:"hellip";s:3:"…";s:5:"prime";s:3:"′";s:5:"Prime";s:3:"″";s:5:"oline";s:3:"‾";s:5:"frasl";s:3:"⁄";s:6:"weierp";s:3:"℘";s:5:"image";s:3:"ℑ";s:4:"real";s:3:"ℜ";s:5:"trade";s:3:"™";s:7:"alefsym";s:3:"ℵ";s:4:"larr";s:3:"←";s:4:"uarr";s:3:"↑";s:4:"rarr";s:3:"→";s:4:"darr";s:3:"↓";s:4:"harr";s:3:"↔";s:5:"crarr";s:3:"↵";s:4:"lArr";s:3:"⇐";s:4:"uArr";s:3:"⇑";s:4:"rArr";s:3:"⇒";s:4:"dArr";s:3:"⇓";s:4:"hArr";s:3:"⇔";s:6:"forall";s:3:"∀";s:4:"part";s:3:"∂";s:5:"exist";s:3:"∃";s:5:"empty";s:3:"∅";s:5:"nabla";s:3:"∇";s:4:"isin";s:3:"∈";s:5:"notin";s:3:"∉";s:2:"ni";s:3:"∋";s:4:"prod";s:3:"∏";s:3:"sum";s:3:"∑";s:5:"minus";s:3:"−";s:6:"lowast";s:3:"∗";s:5:"radic";s:3:"√";s:4:"prop";s:3:"∝";s:5:"infin";s:3:"∞";s:3:"ang";s:3:"∠";s:3:"and";s:3:"∧";s:2:"or";s:3:"∨";s:3:"cap";s:3:"∩";s:3:"cup";s:3:"∪";s:3:"int";s:3:"∫";s:6:"there4";s:3:"∴";s:3:"sim";s:3:"∼";s:4:"cong";s:3:"≅";s:5:"asymp";s:3:"≈";s:2:"ne";s:3:"≠";s:5:"equiv";s:3:"≡";s:2:"le";s:3:"≤";s:2:"ge";s:3:"≥";s:3:"sub";s:3:"⊂";s:3:"sup";s:3:"⊃";s:4:"nsub";s:3:"⊄";s:4:"sube";s:3:"⊆";s:4:"supe";s:3:"⊇";s:5:"oplus";s:3:"⊕";s:6:"otimes";s:3:"⊗";s:4:"perp";s:3:"⊥";s:4:"sdot";s:3:"⋅";s:5:"lceil";s:3:"⌈";s:5:"rceil";s:3:"⌉";s:6:"lfloor";s:3:"⌊";s:6:"rfloor";s:3:"⌋";s:4:"lang";s:3:"〈";s:4:"rang";s:3:"〉";s:3:"loz";s:3:"◊";s:6:"spades";s:3:"♠";s:5:"clubs";s:3:"♣";s:6:"hearts";s:3:"♥";s:5:"diams";s:3:"♦";s:4:"quot";s:1:""";s:3:"amp";s:1:"&";s:2:"lt";s:1:"<";s:2:"gt";s:1:">";s:4:"apos";s:1:"'";s:5:"OElig";s:2:"Œ";s:5:"oelig";s:2:"œ";s:6:"Scaron";s:2:"Š";s:6:"scaron";s:2:"š";s:4:"Yuml";s:2:"Ÿ";s:4:"circ";s:2:"ˆ";s:5:"tilde";s:2:"˜";s:4:"ensp";s:3:" ";s:4:"emsp";s:3:" ";s:6:"thinsp";s:3:" ";s:4:"zwnj";s:3:"‌";s:3:"zwj";s:3:"‍";s:3:"lrm";s:3:"‎";s:3:"rlm";s:3:"‏";s:5:"ndash";s:3:"–";s:5:"mdash";s:3:"—";s:5:"lsquo";s:3:"‘";s:5:"rsquo";s:3:"’";s:5:"sbquo";s:3:"‚";s:5:"ldquo";s:3:"“";s:5:"rdquo";s:3:"”";s:5:"bdquo";s:3:"„";s:6:"dagger";s:3:"†";s:6:"Dagger";s:3:"‡";s:6:"permil";s:3:"‰";s:6:"lsaquo";s:3:"‹";s:6:"rsaquo";s:3:"›";s:4:"euro";s:3:"€";s:4:"nbsp";s:2:" ";s:5:"iexcl";s:2:"¡";s:4:"cent";s:2:"¢";s:5:"pound";s:2:"£";s:6:"curren";s:2:"¤";s:3:"yen";s:2:"¥";s:6:"brvbar";s:2:"¦";s:4:"sect";s:2:"§";s:3:"uml";s:2:"¨";s:4:"copy";s:2:"©";s:4:"ordf";s:2:"ª";s:5:"laquo";s:2:"«";s:3:"not";s:2:"¬";s:3:"shy";s:2:"­";s:3:"reg";s:2:"®";s:4:"macr";s:2:"¯";s:3:"deg";s:2:"°";s:6:"plusmn";s:2:"±";s:4:"sup2";s:2:"²";s:4:"sup3";s:2:"³";s:5:"acute";s:2:"´";s:5:"micro";s:2:"µ";s:4:"para";s:2:"¶";s:6:"middot";s:2:"·";s:5:"cedil";s:2:"¸";s:4:"sup1";s:2:"¹";s:4:"ordm";s:2:"º";s:5:"raquo";s:2:"»";s:6:"frac14";s:2:"¼";s:6:"frac12";s:2:"½";s:6:"frac34";s:2:"¾";s:6:"iquest";s:2:"¿";s:6:"Agrave";s:2:"À";s:6:"Aacute";s:2:"Á";s:5:"Acirc";s:2:"Â";s:6:"Atilde";s:2:"Ã";s:4:"Auml";s:2:"Ä";s:5:"Aring";s:2:"Å";s:5:"AElig";s:2:"Æ";s:6:"Ccedil";s:2:"Ç";s:6:"Egrave";s:2:"È";s:6:"Eacute";s:2:"É";s:5:"Ecirc";s:2:"Ê";s:4:"Euml";s:2:"Ë";s:6:"Igrave";s:2:"Ì";s:6:"Iacute";s:2:"Í";s:5:"Icirc";s:2:"Î";s:4:"Iuml";s:2:"Ï";s:3:"ETH";s:2:"Ð";s:6:"Ntilde";s:2:"Ñ";s:6:"Ograve";s:2:"Ò";s:6:"Oacute";s:2:"Ó";s:5:"Ocirc";s:2:"Ô";s:6:"Otilde";s:2:"Õ";s:4:"Ouml";s:2:"Ö";s:5:"times";s:2:"×";s:6:"Oslash";s:2:"Ø";s:6:"Ugrave";s:2:"Ù";s:6:"Uacute";s:2:"Ú";s:5:"Ucirc";s:2:"Û";s:4:"Uuml";s:2:"Ü";s:6:"Yacute";s:2:"Ý";s:5:"THORN";s:2:"Þ";s:5:"szlig";s:2:"ß";s:6:"agrave";s:2:"à";s:6:"aacute";s:2:"á";s:5:"acirc";s:2:"â";s:6:"atilde";s:2:"ã";s:4:"auml";s:2:"ä";s:5:"aring";s:2:"å";s:5:"aelig";s:2:"æ";s:6:"ccedil";s:2:"ç";s:6:"egrave";s:2:"è";s:6:"eacute";s:2:"é";s:5:"ecirc";s:2:"ê";s:4:"euml";s:2:"ë";s:6:"igrave";s:2:"ì";s:6:"iacute";s:2:"í";s:5:"icirc";s:2:"î";s:4:"iuml";s:2:"ï";s:3:"eth";s:2:"ð";s:6:"ntilde";s:2:"ñ";s:6:"ograve";s:2:"ò";s:6:"oacute";s:2:"ó";s:5:"ocirc";s:2:"ô";s:6:"otilde";s:2:"õ";s:4:"ouml";s:2:"ö";s:6:"divide";s:2:"÷";s:6:"oslash";s:2:"ø";s:6:"ugrave";s:2:"ù";s:6:"uacute";s:2:"ú";s:5:"ucirc";s:2:"û";s:4:"uuml";s:2:"ü";s:6:"yacute";s:2:"ý";s:5:"thorn";s:2:"þ";s:4:"yuml";s:2:"ÿ";} \ No newline at end of file diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php new file mode 100644 index 0000000..08e62c1 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/ExtractStyleBlocks.php @@ -0,0 +1,338 @@ + blocks from input HTML, cleans them up + * using CSSTidy, and then places them in $purifier->context->get('StyleBlocks') + * so they can be used elsewhere in the document. + * + * @note + * See tests/HTMLPurifier/Filter/ExtractStyleBlocksTest.php for + * sample usage. + * + * @note + * This filter can also be used on stylesheets not included in the + * document--something purists would probably prefer. Just directly + * call HTMLPurifier_Filter_ExtractStyleBlocks->cleanCSS() + */ +class HTMLPurifier_Filter_ExtractStyleBlocks extends HTMLPurifier_Filter +{ + /** + * @type string + */ + public $name = 'ExtractStyleBlocks'; + + /** + * @type array + */ + private $_styleMatches = array(); + + /** + * @type csstidy + */ + private $_tidy; + + /** + * @type HTMLPurifier_AttrDef_HTML_ID + */ + private $_id_attrdef; + + /** + * @type HTMLPurifier_AttrDef_CSS_Ident + */ + private $_class_attrdef; + + /** + * @type HTMLPurifier_AttrDef_Enum + */ + private $_enum_attrdef; + + public function __construct() + { + $this->_tidy = new csstidy(); + $this->_tidy->set_cfg('lowercase_s', false); + $this->_id_attrdef = new HTMLPurifier_AttrDef_HTML_ID(true); + $this->_class_attrdef = new HTMLPurifier_AttrDef_CSS_Ident(); + $this->_enum_attrdef = new HTMLPurifier_AttrDef_Enum( + array( + 'first-child', + 'link', + 'visited', + 'active', + 'hover', + 'focus' + ) + ); + } + + /** + * Save the contents of CSS blocks to style matches + * @param array $matches preg_replace style $matches array + */ + protected function styleCallback($matches) + { + $this->_styleMatches[] = $matches[1]; + } + + /** + * Removes inline #isU', array($this, 'styleCallback'), $html); + $style_blocks = $this->_styleMatches; + $this->_styleMatches = array(); // reset + $context->register('StyleBlocks', $style_blocks); // $context must not be reused + if ($this->_tidy) { + foreach ($style_blocks as &$style) { + $style = $this->cleanCSS($style, $config, $context); + } + } + return $html; + } + + /** + * Takes CSS (the stuff found in in a font-family prop). + if ($config->get('Filter.ExtractStyleBlocks.Escaping')) { + $css = str_replace( + array('<', '>', '&'), + array('\3C ', '\3E ', '\26 '), + $css + ); + } + return $css; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/YouTube.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/YouTube.php new file mode 100644 index 0000000..276d836 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Filter/YouTube.php @@ -0,0 +1,65 @@ +]+>.+?' . + '(?:http:)?//www.youtube.com/((?:v|cp)/[A-Za-z0-9\-_=]+).+?#s'; + $pre_replace = '\1'; + return preg_replace($pre_regex, $pre_replace, $html); + } + + /** + * @param string $html + * @param HTMLPurifier_Config $config + * @param HTMLPurifier_Context $context + * @return string + */ + public function postFilter($html, $config, $context) + { + $post_regex = '#((?:v|cp)/[A-Za-z0-9\-_=]+)#'; + return preg_replace_callback($post_regex, array($this, 'postFilterCallback'), $html); + } + + /** + * @param $url + * @return string + */ + protected function armorUrl($url) + { + return str_replace('--', '--', $url); + } + + /** + * @param array $matches + * @return string + */ + protected function postFilterCallback($matches) + { + $url = $this->armorUrl($matches[1]); + return '' . + '' . + '' . + ''; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/classes/en-x-test.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/classes/en-x-test.php new file mode 100644 index 0000000..8828f5c --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/classes/en-x-test.php @@ -0,0 +1,9 @@ + 'HTML Purifier X' +); + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en-x-testmini.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en-x-testmini.php new file mode 100644 index 0000000..806c83f --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en-x-testmini.php @@ -0,0 +1,12 @@ + 'HTML Purifier XNone' +); + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en.php new file mode 100644 index 0000000..c7f197e --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Language/messages/en.php @@ -0,0 +1,55 @@ + 'HTML Purifier', +// for unit testing purposes + 'LanguageFactoryTest: Pizza' => 'Pizza', + 'LanguageTest: List' => '$1', + 'LanguageTest: Hash' => '$1.Keys; $1.Values', + 'Item separator' => ', ', + 'Item separator last' => ' and ', // non-Harvard style + + 'ErrorCollector: No errors' => 'No errors detected. However, because error reporting is still incomplete, there may have been errors that the error collector was not notified of; please inspect the output HTML carefully.', + 'ErrorCollector: At line' => ' at line $line', + 'ErrorCollector: Incidental errors' => 'Incidental errors', + 'Lexer: Unclosed comment' => 'Unclosed comment', + 'Lexer: Unescaped lt' => 'Unescaped less-than sign (<) should be <', + 'Lexer: Missing gt' => 'Missing greater-than sign (>), previous less-than sign (<) should be escaped', + 'Lexer: Missing attribute key' => 'Attribute declaration has no key', + 'Lexer: Missing end quote' => 'Attribute declaration has no end quote', + 'Lexer: Extracted body' => 'Removed document metadata tags', + 'Strategy_RemoveForeignElements: Tag transform' => '<$1> element transformed into $CurrentToken.Serialized', + 'Strategy_RemoveForeignElements: Missing required attribute' => '$CurrentToken.Compact element missing required attribute $1', + 'Strategy_RemoveForeignElements: Foreign element to text' => 'Unrecognized $CurrentToken.Serialized tag converted to text', + 'Strategy_RemoveForeignElements: Foreign element removed' => 'Unrecognized $CurrentToken.Serialized tag removed', + 'Strategy_RemoveForeignElements: Comment removed' => 'Comment containing "$CurrentToken.Data" removed', + 'Strategy_RemoveForeignElements: Foreign meta element removed' => 'Unrecognized $CurrentToken.Serialized meta tag and all descendants removed', + 'Strategy_RemoveForeignElements: Token removed to end' => 'Tags and text starting from $1 element where removed to end', + 'Strategy_RemoveForeignElements: Trailing hyphen in comment removed' => 'Trailing hyphen(s) in comment removed', + 'Strategy_RemoveForeignElements: Hyphens in comment collapsed' => 'Double hyphens in comments are not allowed, and were collapsed into single hyphens', + 'Strategy_MakeWellFormed: Unnecessary end tag removed' => 'Unnecessary $CurrentToken.Serialized tag removed', + 'Strategy_MakeWellFormed: Unnecessary end tag to text' => 'Unnecessary $CurrentToken.Serialized tag converted to text', + 'Strategy_MakeWellFormed: Tag auto closed' => '$1.Compact started on line $1.Line auto-closed by $CurrentToken.Compact', + 'Strategy_MakeWellFormed: Tag carryover' => '$1.Compact started on line $1.Line auto-continued into $CurrentToken.Compact', + 'Strategy_MakeWellFormed: Stray end tag removed' => 'Stray $CurrentToken.Serialized tag removed', + 'Strategy_MakeWellFormed: Stray end tag to text' => 'Stray $CurrentToken.Serialized tag converted to text', + 'Strategy_MakeWellFormed: Tag closed by element end' => '$1.Compact tag started on line $1.Line closed by end of $CurrentToken.Serialized', + 'Strategy_MakeWellFormed: Tag closed by document end' => '$1.Compact tag started on line $1.Line closed by end of document', + 'Strategy_FixNesting: Node removed' => '$CurrentToken.Compact node removed', + 'Strategy_FixNesting: Node excluded' => '$CurrentToken.Compact node removed due to descendant exclusion by ancestor element', + 'Strategy_FixNesting: Node reorganized' => 'Contents of $CurrentToken.Compact node reorganized to enforce its content model', + 'Strategy_FixNesting: Node contents removed' => 'Contents of $CurrentToken.Compact node removed', + 'AttrValidator: Attributes transformed' => 'Attributes on $CurrentToken.Compact transformed from $1.Keys to $2.Keys', + 'AttrValidator: Attribute removed' => '$CurrentAttr.Name attribute on $CurrentToken.Compact removed', +); + +$errorNames = array( + E_ERROR => 'Error', + E_WARNING => 'Warning', + E_NOTICE => 'Notice' +); + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Lexer/PH5P.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Lexer/PH5P.php new file mode 100644 index 0000000..ff4fa21 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Lexer/PH5P.php @@ -0,0 +1,4787 @@ +normalize($html, $config, $context); + $new_html = $this->wrapHTML($new_html, $config, $context); + try { + $parser = new HTML5($new_html); + $doc = $parser->save(); + } catch (DOMException $e) { + // Uh oh, it failed. Punt to DirectLex. + $lexer = new HTMLPurifier_Lexer_DirectLex(); + $context->register('PH5PError', $e); // save the error, so we can detect it + return $lexer->tokenizeHTML($html, $config, $context); // use original HTML + } + $tokens = array(); + $this->tokenizeDOM( + $doc->getElementsByTagName('html')->item(0)-> // + getElementsByTagName('body')->item(0) // + , + $tokens + ); + return $tokens; + } +} + +/* + +Copyright 2007 Jeroen van der Meer + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +*/ + +class HTML5 +{ + private $data; + private $char; + private $EOF; + private $state; + private $tree; + private $token; + private $content_model; + private $escape = false; + private $entities = array( + 'AElig;', + 'AElig', + 'AMP;', + 'AMP', + 'Aacute;', + 'Aacute', + 'Acirc;', + 'Acirc', + 'Agrave;', + 'Agrave', + 'Alpha;', + 'Aring;', + 'Aring', + 'Atilde;', + 'Atilde', + 'Auml;', + 'Auml', + 'Beta;', + 'COPY;', + 'COPY', + 'Ccedil;', + 'Ccedil', + 'Chi;', + 'Dagger;', + 'Delta;', + 'ETH;', + 'ETH', + 'Eacute;', + 'Eacute', + 'Ecirc;', + 'Ecirc', + 'Egrave;', + 'Egrave', + 'Epsilon;', + 'Eta;', + 'Euml;', + 'Euml', + 'GT;', + 'GT', + 'Gamma;', + 'Iacute;', + 'Iacute', + 'Icirc;', + 'Icirc', + 'Igrave;', + 'Igrave', + 'Iota;', + 'Iuml;', + 'Iuml', + 'Kappa;', + 'LT;', + 'LT', + 'Lambda;', + 'Mu;', + 'Ntilde;', + 'Ntilde', + 'Nu;', + 'OElig;', + 'Oacute;', + 'Oacute', + 'Ocirc;', + 'Ocirc', + 'Ograve;', + 'Ograve', + 'Omega;', + 'Omicron;', + 'Oslash;', + 'Oslash', + 'Otilde;', + 'Otilde', + 'Ouml;', + 'Ouml', + 'Phi;', + 'Pi;', + 'Prime;', + 'Psi;', + 'QUOT;', + 'QUOT', + 'REG;', + 'REG', + 'Rho;', + 'Scaron;', + 'Sigma;', + 'THORN;', + 'THORN', + 'TRADE;', + 'Tau;', + 'Theta;', + 'Uacute;', + 'Uacute', + 'Ucirc;', + 'Ucirc', + 'Ugrave;', + 'Ugrave', + 'Upsilon;', + 'Uuml;', + 'Uuml', + 'Xi;', + 'Yacute;', + 'Yacute', + 'Yuml;', + 'Zeta;', + 'aacute;', + 'aacute', + 'acirc;', + 'acirc', + 'acute;', + 'acute', + 'aelig;', + 'aelig', + 'agrave;', + 'agrave', + 'alefsym;', + 'alpha;', + 'amp;', + 'amp', + 'and;', + 'ang;', + 'apos;', + 'aring;', + 'aring', + 'asymp;', + 'atilde;', + 'atilde', + 'auml;', + 'auml', + 'bdquo;', + 'beta;', + 'brvbar;', + 'brvbar', + 'bull;', + 'cap;', + 'ccedil;', + 'ccedil', + 'cedil;', + 'cedil', + 'cent;', + 'cent', + 'chi;', + 'circ;', + 'clubs;', + 'cong;', + 'copy;', + 'copy', + 'crarr;', + 'cup;', + 'curren;', + 'curren', + 'dArr;', + 'dagger;', + 'darr;', + 'deg;', + 'deg', + 'delta;', + 'diams;', + 'divide;', + 'divide', + 'eacute;', + 'eacute', + 'ecirc;', + 'ecirc', + 'egrave;', + 'egrave', + 'empty;', + 'emsp;', + 'ensp;', + 'epsilon;', + 'equiv;', + 'eta;', + 'eth;', + 'eth', + 'euml;', + 'euml', + 'euro;', + 'exist;', + 'fnof;', + 'forall;', + 'frac12;', + 'frac12', + 'frac14;', + 'frac14', + 'frac34;', + 'frac34', + 'frasl;', + 'gamma;', + 'ge;', + 'gt;', + 'gt', + 'hArr;', + 'harr;', + 'hearts;', + 'hellip;', + 'iacute;', + 'iacute', + 'icirc;', + 'icirc', + 'iexcl;', + 'iexcl', + 'igrave;', + 'igrave', + 'image;', + 'infin;', + 'int;', + 'iota;', + 'iquest;', + 'iquest', + 'isin;', + 'iuml;', + 'iuml', + 'kappa;', + 'lArr;', + 'lambda;', + 'lang;', + 'laquo;', + 'laquo', + 'larr;', + 'lceil;', + 'ldquo;', + 'le;', + 'lfloor;', + 'lowast;', + 'loz;', + 'lrm;', + 'lsaquo;', + 'lsquo;', + 'lt;', + 'lt', + 'macr;', + 'macr', + 'mdash;', + 'micro;', + 'micro', + 'middot;', + 'middot', + 'minus;', + 'mu;', + 'nabla;', + 'nbsp;', + 'nbsp', + 'ndash;', + 'ne;', + 'ni;', + 'not;', + 'not', + 'notin;', + 'nsub;', + 'ntilde;', + 'ntilde', + 'nu;', + 'oacute;', + 'oacute', + 'ocirc;', + 'ocirc', + 'oelig;', + 'ograve;', + 'ograve', + 'oline;', + 'omega;', + 'omicron;', + 'oplus;', + 'or;', + 'ordf;', + 'ordf', + 'ordm;', + 'ordm', + 'oslash;', + 'oslash', + 'otilde;', + 'otilde', + 'otimes;', + 'ouml;', + 'ouml', + 'para;', + 'para', + 'part;', + 'permil;', + 'perp;', + 'phi;', + 'pi;', + 'piv;', + 'plusmn;', + 'plusmn', + 'pound;', + 'pound', + 'prime;', + 'prod;', + 'prop;', + 'psi;', + 'quot;', + 'quot', + 'rArr;', + 'radic;', + 'rang;', + 'raquo;', + 'raquo', + 'rarr;', + 'rceil;', + 'rdquo;', + 'real;', + 'reg;', + 'reg', + 'rfloor;', + 'rho;', + 'rlm;', + 'rsaquo;', + 'rsquo;', + 'sbquo;', + 'scaron;', + 'sdot;', + 'sect;', + 'sect', + 'shy;', + 'shy', + 'sigma;', + 'sigmaf;', + 'sim;', + 'spades;', + 'sub;', + 'sube;', + 'sum;', + 'sup1;', + 'sup1', + 'sup2;', + 'sup2', + 'sup3;', + 'sup3', + 'sup;', + 'supe;', + 'szlig;', + 'szlig', + 'tau;', + 'there4;', + 'theta;', + 'thetasym;', + 'thinsp;', + 'thorn;', + 'thorn', + 'tilde;', + 'times;', + 'times', + 'trade;', + 'uArr;', + 'uacute;', + 'uacute', + 'uarr;', + 'ucirc;', + 'ucirc', + 'ugrave;', + 'ugrave', + 'uml;', + 'uml', + 'upsih;', + 'upsilon;', + 'uuml;', + 'uuml', + 'weierp;', + 'xi;', + 'yacute;', + 'yacute', + 'yen;', + 'yen', + 'yuml;', + 'yuml', + 'zeta;', + 'zwj;', + 'zwnj;' + ); + + const PCDATA = 0; + const RCDATA = 1; + const CDATA = 2; + const PLAINTEXT = 3; + + const DOCTYPE = 0; + const STARTTAG = 1; + const ENDTAG = 2; + const COMMENT = 3; + const CHARACTR = 4; + const EOF = 5; + + public function __construct($data) + { + $this->data = $data; + $this->char = -1; + $this->EOF = strlen($data); + $this->tree = new HTML5TreeConstructer; + $this->content_model = self::PCDATA; + + $this->state = 'data'; + + while ($this->state !== null) { + $this->{$this->state . 'State'}(); + } + } + + public function save() + { + return $this->tree->save(); + } + + private function char() + { + return ($this->char < $this->EOF) + ? $this->data[$this->char] + : false; + } + + private function character($s, $l = 0) + { + if ($s + $l < $this->EOF) { + if ($l === 0) { + return $this->data[$s]; + } else { + return substr($this->data, $s, $l); + } + } + } + + private function characters($char_class, $start) + { + return preg_replace('#^([' . $char_class . ']+).*#s', '\\1', substr($this->data, $start)); + } + + private function dataState() + { + // Consume the next input character + $this->char++; + $char = $this->char(); + + if ($char === '&' && ($this->content_model === self::PCDATA || $this->content_model === self::RCDATA)) { + /* U+0026 AMPERSAND (&) + When the content model flag is set to one of the PCDATA or RCDATA + states: switch to the entity data state. Otherwise: treat it as per + the "anything else" entry below. */ + $this->state = 'entityData'; + + } elseif ($char === '-') { + /* If the content model flag is set to either the RCDATA state or + the CDATA state, and the escape flag is false, and there are at + least three characters before this one in the input stream, and the + last four characters in the input stream, including this one, are + U+003C LESS-THAN SIGN, U+0021 EXCLAMATION MARK, U+002D HYPHEN-MINUS, + and U+002D HYPHEN-MINUS (""), + set the escape flag to false. */ + if (($this->content_model === self::RCDATA || + $this->content_model === self::CDATA) && $this->escape === true && + $this->character($this->char, 3) === '-->' + ) { + $this->escape = false; + } + + /* In any case, emit the input character as a character token. + Stay in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + } elseif ($this->char === $this->EOF) { + /* EOF + Emit an end-of-file token. */ + $this->EOF(); + + } elseif ($this->content_model === self::PLAINTEXT) { + /* When the content model flag is set to the PLAINTEXT state + THIS DIFFERS GREATLY FROM THE SPEC: Get the remaining characters of + the text and emit it as a character token. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => substr($this->data, $this->char) + ) + ); + + $this->EOF(); + + } else { + /* Anything else + THIS DIFFERS GREATLY FROM THE SPEC: Get as many character that + otherwise would also be treated as a character token and emit it + as a single character token. Stay in the data state. */ + $len = strcspn($this->data, '<&', $this->char); + $char = substr($this->data, $this->char, $len); + $this->char += $len - 1; + + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + $this->state = 'data'; + } + } + + private function entityDataState() + { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, emit a U+0026 AMPERSAND character token. + // Otherwise, emit the character token that was returned. + $char = (!$entity) ? '&' : $entity; + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => $char + ) + ); + + // Finally, switch to the data state. + $this->state = 'data'; + } + + private function tagOpenState() + { + switch ($this->content_model) { + case self::RCDATA: + case self::CDATA: + /* If the next input character is a U+002F SOLIDUS (/) character, + consume it and switch to the close tag open state. If the next + input character is not a U+002F SOLIDUS (/) character, emit a + U+003C LESS-THAN SIGN character token and switch to the data + state to process the next input character. */ + if ($this->character($this->char + 1) === '/') { + $this->char++; + $this->state = 'closeTagOpen'; + + } else { + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); + + $this->state = 'data'; + } + break; + + case self::PCDATA: + // If the content model flag is set to the PCDATA state + // Consume the next input character: + $this->char++; + $char = $this->char(); + + if ($char === '!') { + /* U+0021 EXCLAMATION MARK (!) + Switch to the markup declaration open state. */ + $this->state = 'markupDeclarationOpen'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the close tag open state. */ + $this->state = 'closeTagOpen'; + + } elseif (preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new start tag token, set its tag name to the lowercase + version of the input character (add 0x0020 to the character's code + point), then switch to the tag name state. (Don't emit the token + yet; further details will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::STARTTAG, + 'attr' => array() + ); + + $this->state = 'tagName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit a U+003C LESS-THAN SIGN character token and a + U+003E GREATER-THAN SIGN character token. Switch to the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<>' + ) + ); + + $this->state = 'data'; + + } elseif ($char === '?') { + /* U+003F QUESTION MARK (?) + Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + + } else { + /* Anything else + Parse error. Emit a U+003C LESS-THAN SIGN character token and + reconsume the current input character in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => '<' + ) + ); + + $this->char--; + $this->state = 'data'; + } + break; + } + } + + private function closeTagOpenState() + { + $next_node = strtolower($this->characters('A-Za-z', $this->char + 1)); + $the_same = count($this->tree->stack) > 0 && $next_node === end($this->tree->stack)->nodeName; + + if (($this->content_model === self::RCDATA || $this->content_model === self::CDATA) && + (!$the_same || ($the_same && (!preg_match( + '/[\t\n\x0b\x0c >\/]/', + $this->character($this->char + 1 + strlen($next_node)) + ) || $this->EOF === $this->char))) + ) { + /* If the content model flag is set to the RCDATA or CDATA states then + examine the next few characters. If they do not match the tag name of + the last start tag token emitted (case insensitively), or if they do but + they are not immediately followed by one of the following characters: + * U+0009 CHARACTER TABULATION + * U+000A LINE FEED (LF) + * U+000B LINE TABULATION + * U+000C FORM FEED (FF) + * U+0020 SPACE + * U+003E GREATER-THAN SIGN (>) + * U+002F SOLIDUS (/) + * EOF + ...then there is a parse error. Emit a U+003C LESS-THAN SIGN character + token, a U+002F SOLIDUS character token, and switch to the data state + to process the next input character. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'state = 'data'; + + } else { + /* Otherwise, if the content model flag is set to the PCDATA state, + or if the next few characters do match that tag name, consume the + next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[A-Za-z]$/', $char)) { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new end tag token, set its tag name to the lowercase version + of the input character (add 0x0020 to the character's code point), then + switch to the tag name state. (Don't emit the token yet; further details + will be filled in before it is emitted.) */ + $this->token = array( + 'name' => strtolower($char), + 'type' => self::ENDTAG + ); + + $this->state = 'tagName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Switch to the data state. */ + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F + SOLIDUS character token. Reconsume the EOF character in the data state. */ + $this->emitToken( + array( + 'type' => self::CHARACTR, + 'data' => 'char--; + $this->state = 'data'; + + } else { + /* Parse error. Switch to the bogus comment state. */ + $this->state = 'bogusComment'; + } + } + } + + private function tagNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } else { + /* Anything else + Append the current input character to the current tag token's tag name. + Stay in the tag name state. */ + $this->token['name'] .= strtolower($char); + $this->state = 'tagName'; + } + } + + private function beforeAttributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Stay in the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function attributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the before + attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's name. + Stay in the attribute name state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['name'] .= strtolower($char); + + $this->state = 'attributeName'; + } + } + + private function afterAttributeNameState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after attribute name state. */ + $this->state = 'afterAttributeName'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '/' && $this->character($this->char + 1) !== '>') { + /* U+002F SOLIDUS (/) + Parse error unless this is a permitted slash. Switch to the + before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the EOF + character in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = array( + 'name' => strtolower($char), + 'value' => null + ); + + $this->state = 'attributeName'; + } + } + + private function beforeAttributeValueState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute value state. */ + $this->state = 'beforeAttributeValue'; + + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the attribute value (double-quoted) state. */ + $this->state = 'attributeValueDoubleQuoted'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the attribute value (unquoted) state and reconsume + this input character. */ + $this->char--; + $this->state = 'attributeValueUnquoted'; + + } elseif ($char === '\'') { + /* U+0027 APOSTROPHE (') + Switch to the attribute value (single-quoted) state. */ + $this->state = 'attributeValueSingleQuoted'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Switch to the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function attributeValueDoubleQuotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('double'); + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (double-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueDoubleQuoted'; + } + } + + private function attributeValueSingleQuotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if ($char === '\'') { + /* U+0022 QUOTATION MARK (') + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState('single'); + + } elseif ($this->char === $this->EOF) { + /* EOF + Parse error. Emit the current tag token. Reconsume the character + in the data state. */ + $this->emitToken($this->token); + + $this->char--; + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (single-quoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueSingleQuoted'; + } + } + + private function attributeValueUnquotedState() + { + // Consume the next input character: + $this->char++; + $char = $this->character($this->char); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000B LINE TABULATION + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $this->state = 'beforeAttributeName'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->entityInAttributeValueState(); + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $this->state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $this->state = 'attributeValueUnquoted'; + } + } + + private function entityInAttributeValueState() + { + // Attempt to consume an entity. + $entity = $this->entity(); + + // If nothing is returned, append a U+0026 AMPERSAND character to the + // current attribute's value. Otherwise, emit the character token that + // was returned. + $char = (!$entity) + ? '&' + : $entity; + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + } + + private function bogusCommentState() + { + /* Consume every character up to the first U+003E GREATER-THAN SIGN + character (>) or the end of the file (EOF), whichever comes first. Emit + a comment token whose data is the concatenation of all the characters + starting from and including the character that caused the state machine + to switch into the bogus comment state, up to and including the last + consumed character before the U+003E character, if any, or up to the + end of the file otherwise. (If the comment was started by the end of + the file (EOF), the token is empty.) */ + $data = $this->characters('^>', $this->char); + $this->emitToken( + array( + 'data' => $data, + 'type' => self::COMMENT + ) + ); + + $this->char += strlen($data); + + /* Switch to the data state. */ + $this->state = 'data'; + + /* If the end of the file was reached, reconsume the EOF character. */ + if ($this->char === $this->EOF) { + $this->char = $this->EOF - 1; + } + } + + private function markupDeclarationOpenState() + { + /* If the next two characters are both U+002D HYPHEN-MINUS (-) + characters, consume those two characters, create a comment token whose + data is the empty string, and switch to the comment state. */ + if ($this->character($this->char + 1, 2) === '--') { + $this->char += 2; + $this->state = 'comment'; + $this->token = array( + 'data' => null, + 'type' => self::COMMENT + ); + + /* Otherwise if the next seven chacacters are a case-insensitive match + for the word "DOCTYPE", then consume those characters and switch to the + DOCTYPE state. */ + } elseif (strtolower($this->character($this->char + 1, 7)) === 'doctype') { + $this->char += 7; + $this->state = 'doctype'; + + /* Otherwise, is is a parse error. Switch to the bogus comment state. + The next character that is consumed, if any, is the first character + that will be in the comment. */ + } else { + $this->char++; + $this->state = 'bogusComment'; + } + } + + private function commentState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if ($char === '-') { + /* Switch to the comment dash state */ + $this->state = 'commentDash'; + + /* EOF */ + } elseif ($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append the input character to the comment token's data. Stay in + the comment state. */ + $this->token['data'] .= $char; + } + } + + private function commentDashState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + /* U+002D HYPHEN-MINUS (-) */ + if ($char === '-') { + /* Switch to the comment end state */ + $this->state = 'commentEnd'; + + /* EOF */ + } elseif ($this->char === $this->EOF) { + /* Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + /* Anything else */ + } else { + /* Append a U+002D HYPHEN-MINUS (-) character and the input + character to the comment token's data. Switch to the comment state. */ + $this->token['data'] .= '-' . $char; + $this->state = 'comment'; + } + } + + private function commentEndState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($char === '-') { + $this->token['data'] .= '-'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['data'] .= '--' . $char; + $this->state = 'comment'; + } + } + + private function doctypeState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'beforeDoctypeName'; + + } else { + $this->char--; + $this->state = 'beforeDoctypeName'; + } + } + + private function beforeDoctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the before DOCTYPE name state. + + } elseif (preg_match('/^[a-z]$/', $char)) { + $this->token = array( + 'name' => strtoupper($char), + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + + } elseif ($char === '>') { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); + + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken( + array( + 'name' => null, + 'type' => self::DOCTYPE, + 'error' => true + ) + ); + + $this->char--; + $this->state = 'data'; + + } else { + $this->token = array( + 'name' => $char, + 'type' => self::DOCTYPE, + 'error' => true + ); + + $this->state = 'doctypeName'; + } + } + + private function doctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + $this->state = 'AfterDoctypeName'; + + } elseif ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif (preg_match('/^[a-z]$/', $char)) { + $this->token['name'] .= strtoupper($char); + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['name'] .= $char; + } + + $this->token['error'] = ($this->token['name'] === 'HTML') + ? false + : true; + } + + private function afterDoctypeNameState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if (preg_match('/^[\t\n\x0b\x0c ]$/', $char)) { + // Stay in the DOCTYPE name state. + + } elseif ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + $this->token['error'] = true; + $this->state = 'bogusDoctype'; + } + } + + private function bogusDoctypeState() + { + /* Consume the next input character: */ + $this->char++; + $char = $this->char(); + + if ($char === '>') { + $this->emitToken($this->token); + $this->state = 'data'; + + } elseif ($this->char === $this->EOF) { + $this->emitToken($this->token); + $this->char--; + $this->state = 'data'; + + } else { + // Stay in the bogus DOCTYPE state. + } + } + + private function entity() + { + $start = $this->char; + + // This section defines how to consume an entity. This definition is + // used when parsing entities in text and in attributes. + + // The behaviour depends on the identity of the next character (the + // one immediately after the U+0026 AMPERSAND character): + + switch ($this->character($this->char + 1)) { + // U+0023 NUMBER SIGN (#) + case '#': + + // The behaviour further depends on the character after the + // U+0023 NUMBER SIGN: + switch ($this->character($this->char + 1)) { + // U+0078 LATIN SMALL LETTER X + // U+0058 LATIN CAPITAL LETTER X + case 'x': + case 'X': + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE, U+0061 LATIN SMALL LETTER A through to U+0066 + // LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER + // A, through to U+0046 LATIN CAPITAL LETTER F (in other + // words, 0-9, A-F, a-f). + $char = 1; + $char_class = '0-9A-Fa-f'; + break; + + // Anything else + default: + // Follow the steps below, but using the range of + // characters U+0030 DIGIT ZERO through to U+0039 DIGIT + // NINE (i.e. just 0-9). + $char = 0; + $char_class = '0-9'; + break; + } + + // Consume as many characters as match the range of characters + // given above. + $this->char++; + $e_name = $this->characters($char_class, $this->char + $char + 1); + $entity = $this->character($start, $this->char); + $cond = strlen($e_name) > 0; + + // The rest of the parsing happens bellow. + break; + + // Anything else + default: + // Consume the maximum number of characters possible, with the + // consumed characters case-sensitively matching one of the + // identifiers in the first column of the entities table. + $e_name = $this->characters('0-9A-Za-z;', $this->char + 1); + $len = strlen($e_name); + + for ($c = 1; $c <= $len; $c++) { + $id = substr($e_name, 0, $c); + $this->char++; + + if (in_array($id, $this->entities)) { + if ($e_name[$c - 1] !== ';') { + if ($c < $len && $e_name[$c] == ';') { + $this->char++; // consume extra semicolon + } + } + $entity = $id; + break; + } + } + + $cond = isset($entity); + // The rest of the parsing happens bellow. + break; + } + + if (!$cond) { + // If no match can be made, then this is a parse error. No + // characters are consumed, and nothing is returned. + $this->char = $start; + return false; + } + + // Return a character token for the character corresponding to the + // entity name (as given by the second column of the entities table). + return html_entity_decode('&' . $entity . ';', ENT_QUOTES, 'UTF-8'); + } + + private function emitToken($token) + { + $emit = $this->tree->emitToken($token); + + if (is_int($emit)) { + $this->content_model = $emit; + + } elseif ($token['type'] === self::ENDTAG) { + $this->content_model = self::PCDATA; + } + } + + private function EOF() + { + $this->state = null; + $this->tree->emitToken( + array( + 'type' => self::EOF + ) + ); + } +} + +class HTML5TreeConstructer +{ + public $stack = array(); + + private $phase; + private $mode; + private $dom; + private $foster_parent = null; + private $a_formatting = array(); + + private $head_pointer = null; + private $form_pointer = null; + + private $scoping = array('button', 'caption', 'html', 'marquee', 'object', 'table', 'td', 'th'); + private $formatting = array( + 'a', + 'b', + 'big', + 'em', + 'font', + 'i', + 'nobr', + 's', + 'small', + 'strike', + 'strong', + 'tt', + 'u' + ); + private $special = array( + 'address', + 'area', + 'base', + 'basefont', + 'bgsound', + 'blockquote', + 'body', + 'br', + 'center', + 'col', + 'colgroup', + 'dd', + 'dir', + 'div', + 'dl', + 'dt', + 'embed', + 'fieldset', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'hr', + 'iframe', + 'image', + 'img', + 'input', + 'isindex', + 'li', + 'link', + 'listing', + 'menu', + 'meta', + 'noembed', + 'noframes', + 'noscript', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'plaintext', + 'pre', + 'script', + 'select', + 'spacer', + 'style', + 'tbody', + 'textarea', + 'tfoot', + 'thead', + 'title', + 'tr', + 'ul', + 'wbr' + ); + + // The different phases. + const INIT_PHASE = 0; + const ROOT_PHASE = 1; + const MAIN_PHASE = 2; + const END_PHASE = 3; + + // The different insertion modes for the main phase. + const BEFOR_HEAD = 0; + const IN_HEAD = 1; + const AFTER_HEAD = 2; + const IN_BODY = 3; + const IN_TABLE = 4; + const IN_CAPTION = 5; + const IN_CGROUP = 6; + const IN_TBODY = 7; + const IN_ROW = 8; + const IN_CELL = 9; + const IN_SELECT = 10; + const AFTER_BODY = 11; + const IN_FRAME = 12; + const AFTR_FRAME = 13; + + // The different types of elements. + const SPECIAL = 0; + const SCOPING = 1; + const FORMATTING = 2; + const PHRASING = 3; + + const MARKER = 0; + + public function __construct() + { + $this->phase = self::INIT_PHASE; + $this->mode = self::BEFOR_HEAD; + $this->dom = new DOMDocument; + + $this->dom->encoding = 'UTF-8'; + $this->dom->preserveWhiteSpace = true; + $this->dom->substituteEntities = true; + $this->dom->strictErrorChecking = false; + } + + // Process tag tokens + public function emitToken($token) + { + switch ($this->phase) { + case self::INIT_PHASE: + return $this->initPhase($token); + break; + case self::ROOT_PHASE: + return $this->rootElementPhase($token); + break; + case self::MAIN_PHASE: + return $this->mainPhase($token); + break; + case self::END_PHASE : + return $this->trailingEndPhase($token); + break; + } + } + + private function initPhase($token) + { + /* Initially, the tree construction stage must handle each token + emitted from the tokenisation stage as follows: */ + + /* A DOCTYPE token that is marked as being in error + A comment token + A start tag token + An end tag token + A character token that is not one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE + An end-of-file token */ + if ((isset($token['error']) && $token['error']) || + $token['type'] === HTML5::COMMENT || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF || + ($token['type'] === HTML5::CHARACTR && isset($token['data']) && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) + ) { + /* This specification does not define how to handle this case. In + particular, user agents may ignore the entirety of this specification + altogether for such documents, and instead invoke special parse modes + with a greater emphasis on backwards compatibility. */ + + $this->phase = self::ROOT_PHASE; + return $this->rootElementPhase($token); + + /* A DOCTYPE token marked as being correct */ + } elseif (isset($token['error']) && !$token['error']) { + /* Append a DocumentType node to the Document node, with the name + attribute set to the name given in the DOCTYPE token (which will be + "HTML"), and the other attributes specific to DocumentType objects + set to null, empty lists, or the empty string as appropriate. */ + $doctype = new DOMDocumentType(null, null, 'HTML'); + + /* Then, switch to the root element phase of the tree construction + stage. */ + $this->phase = self::ROOT_PHASE; + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif (isset($token['data']) && preg_match( + '/^[\t\n\x0b\x0c ]+$/', + $token['data'] + ) + ) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + } + } + + private function rootElementPhase($token) + { + /* After the initial phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append that character to the Document node. */ + $text = $this->dom->createTextNode($token['data']); + $this->dom->appendChild($text); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED + (FF), or U+0020 SPACE + A start tag token + An end tag token + An end-of-file token */ + } elseif (($token['type'] === HTML5::CHARACTR && + !preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || + $token['type'] === HTML5::ENDTAG || + $token['type'] === HTML5::EOF + ) { + /* Create an HTMLElement node with the tag name html, in the HTML + namespace. Append it to the Document object. Switch to the main + phase and reprocess the current token. */ + $html = $this->dom->createElement('html'); + $this->dom->appendChild($html); + $this->stack[] = $html; + + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + } + } + + private function mainPhase($token) + { + /* Tokens in the main phase must be handled as follows: */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A start tag token with the tag name "html" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'html') { + /* If this start tag token was not the first start tag token, then + it is a parse error. */ + + /* For each attribute on the token, check to see if the attribute + is already present on the top element of the stack of open elements. + If it is not, add the attribute and its corresponding value to that + element. */ + foreach ($token['attr'] as $attr) { + if (!$this->stack[0]->hasAttribute($attr['name'])) { + $this->stack[0]->setAttribute($attr['name'], $attr['value']); + } + } + + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Anything else. */ + } else { + /* Depends on the insertion mode: */ + switch ($this->mode) { + case self::BEFOR_HEAD: + return $this->beforeHead($token); + break; + case self::IN_HEAD: + return $this->inHead($token); + break; + case self::AFTER_HEAD: + return $this->afterHead($token); + break; + case self::IN_BODY: + return $this->inBody($token); + break; + case self::IN_TABLE: + return $this->inTable($token); + break; + case self::IN_CAPTION: + return $this->inCaption($token); + break; + case self::IN_CGROUP: + return $this->inColumnGroup($token); + break; + case self::IN_TBODY: + return $this->inTableBody($token); + break; + case self::IN_ROW: + return $this->inRow($token); + break; + case self::IN_CELL: + return $this->inCell($token); + break; + case self::IN_SELECT: + return $this->inSelect($token); + break; + case self::AFTER_BODY: + return $this->afterBody($token); + break; + case self::IN_FRAME: + return $this->inFrameset($token); + break; + case self::AFTR_FRAME: + return $this->afterFrameset($token); + break; + case self::END_PHASE: + return $this->trailingEndPhase($token); + break; + } + } + } + + private function beforeHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "head" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') { + /* Create an element for the token, append the new element to the + current node and push it onto the stack of open elements. */ + $element = $this->insertElement($token); + + /* Set the head element pointer to this new element node. */ + $this->head_pointer = $element; + + /* Change the insertion mode to "in head". */ + $this->mode = self::IN_HEAD; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title". Or an end tag with the tag name "html". + Or a character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or any other start tag token */ + } elseif ($token['type'] === HTML5::STARTTAG || + ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') || + ($token['type'] === HTML5::CHARACTR && !preg_match( + '/^[\t\n\x0b\x0c ]$/', + $token['data'] + )) + ) { + /* Act as if a start tag token with the tag name "head" and no + attributes had been seen, then reprocess the current token. */ + $this->beforeHead( + array( + 'name' => 'head', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inHead($token); + + /* Any other end tag */ + } elseif ($token['type'] === HTML5::ENDTAG) { + /* Parse error. Ignore the token. */ + } + } + + private function inHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. + + THIS DIFFERS FROM THE SPEC: If the current node is either a title, style + or script element, append the character to the current node regardless + of its content. */ + if (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || ( + $token['type'] === HTML5::CHARACTR && in_array( + end($this->stack)->nodeName, + array('title', 'style', 'script') + )) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('title', 'style', 'script')) + ) { + array_pop($this->stack); + return HTML5::PCDATA; + + /* A start tag with the tag name "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'title') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $element = $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the RCDATA state. */ + return HTML5::RCDATA; + + /* A start tag with the tag name "style" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'style') { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + } else { + $this->insertElement($token); + } + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "script" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'script') { + /* Create an element for the token. */ + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + + /* A start tag with the tag name "base", "link", or "meta" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta') + ) + ) { + /* Create an element for the token and append the new element to the + node pointed to by the head element pointer, or, if that is null + (innerHTML case), to the current node. */ + if ($this->head_pointer !== null) { + $element = $this->insertElement($token, false); + $this->head_pointer->appendChild($element); + array_pop($this->stack); + + } else { + $this->insertElement($token); + } + + /* An end tag with the tag name "head" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'head') { + /* If the current node is a head element, pop the current node off + the stack of open elements. */ + if ($this->head_pointer->isSameNode(end($this->stack))) { + array_pop($this->stack); + + /* Otherwise, this is a parse error. */ + } else { + // k + } + + /* Change the insertion mode to "after head". */ + $this->mode = self::AFTER_HEAD; + + /* A start tag with the tag name "head" or an end tag except "html". */ + } elseif (($token['type'] === HTML5::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5::ENDTAG && $token['name'] !== 'html') + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* If the current node is a head element, act as if an end tag + token with the tag name "head" had been seen. */ + if ($this->head_pointer->isSameNode(end($this->stack))) { + $this->inHead( + array( + 'name' => 'head', + 'type' => HTML5::ENDTAG + ) + ); + + /* Otherwise, change the insertion mode to "after head". */ + } else { + $this->mode = self::AFTER_HEAD; + } + + /* Then, reprocess the current token. */ + return $this->afterHead($token); + } + } + + private function afterHead($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token with the tag name "body" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'body') { + /* Insert a body element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in body". */ + $this->mode = self::IN_BODY; + + /* A start tag token with the tag name "frameset" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'frameset') { + /* Insert a frameset element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in frameset". */ + $this->mode = self::IN_FRAME; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('base', 'link', 'meta', 'script', 'style', 'title') + ) + ) { + /* Parse error. Switch the insertion mode back to "in head" and + reprocess the token. */ + $this->mode = self::IN_HEAD; + return $this->inHead($token); + + /* Anything else */ + } else { + /* Act as if a start tag token with the tag name "body" and no + attributes had been seen, and then reprocess the current token. */ + $this->afterHead( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inBody($token); + } + } + + private function inBody($token) + { + /* Handle the token as follows: */ + + switch ($token['type']) { + /* A character token */ + case HTML5::CHARACTR: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + break; + + /* A comment token */ + case HTML5::COMMENT: + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + break; + + case HTML5::STARTTAG: + switch ($token['name']) { + /* A start tag token whose tag name is one of: "script", + "style" */ + case 'script': + case 'style': + /* Process the token as if the insertion mode had been "in + head". */ + return $this->inHead($token); + break; + + /* A start tag token whose tag name is one of: "base", "link", + "meta", "title" */ + case 'base': + case 'link': + case 'meta': + case 'title': + /* Parse error. Process the token as if the insertion mode + had been "in head". */ + return $this->inHead($token); + break; + + /* A start tag token with the tag name "body" */ + case 'body': + /* Parse error. If the second element on the stack of open + elements is not a body element, or, if the stack of open + elements has only one node on it, then ignore the token. + (innerHTML case) */ + if (count($this->stack) === 1 || $this->stack[1]->nodeName !== 'body') { + // Ignore + + /* Otherwise, for each attribute on the token, check to see + if the attribute is already present on the body element (the + second element) on the stack of open elements. If it is not, + add the attribute and its corresponding value to that + element. */ + } else { + foreach ($token['attr'] as $attr) { + if (!$this->stack[1]->hasAttribute($attr['name'])) { + $this->stack[1]->setAttribute($attr['name'], $attr['value']); + } + } + } + break; + + /* A start tag whose tag name is one of: "address", + "blockquote", "center", "dir", "div", "dl", "fieldset", + "listing", "menu", "ol", "p", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'p': + case 'ul': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "form" */ + case 'form': + /* If the form element pointer is not null, ignore the + token with a parse error. */ + if ($this->form_pointer !== null) { + // Ignore. + + /* Otherwise: */ + } else { + /* If the stack of open elements has a p element in + scope, then act as if an end tag with the tag name p + had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token, and set the + form element pointer to point to the element created. */ + $element = $this->insertElement($token); + $this->form_pointer = $element; + } + break; + + /* A start tag whose tag name is "li", "dd" or "dt" */ + case 'li': + case 'dd': + case 'dt': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + $stack_length = count($this->stack) - 1; + + for ($n = $stack_length; 0 <= $n; $n--) { + /* 1. Initialise node to be the current node (the + bottommost node of the stack). */ + $stop = false; + $node = $this->stack[$n]; + $cat = $this->getElementCategory($node->tagName); + + /* 2. If node is an li, dd or dt element, then pop all + the nodes from the current node up to node, including + node, then stop this algorithm. */ + if ($token['name'] === $node->tagName || ($token['name'] !== 'li' + && ($node->tagName === 'dd' || $node->tagName === 'dt')) + ) { + for ($x = $stack_length; $x >= $n; $x--) { + array_pop($this->stack); + } + + break; + } + + /* 3. If node is not in the formatting category, and is + not in the phrasing category, and is not an address or + div element, then stop this algorithm. */ + if ($cat !== self::FORMATTING && $cat !== self::PHRASING && + $node->tagName !== 'address' && $node->tagName !== 'div' + ) { + break; + } + } + + /* Finally, insert an HTML element with the same tag + name as the token's. */ + $this->insertElement($token); + break; + + /* A start tag token whose tag name is "plaintext" */ + case 'plaintext': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + return HTML5::PLAINTEXT; + break; + + /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + this is a parse error; pop elements from the stack until an + element with one of those tag names has been popped from the + stack. */ + while ($this->elementInScope(array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'))) { + array_pop($this->stack); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is "a" */ + case 'a': + /* If the list of active formatting elements contains + an element whose tag name is "a" between the end of the + list and the last marker on the list (or the start of + the list if there is no marker on the list), then this + is a parse error; act as if an end tag with the tag name + "a" had been seen, then remove that element from the list + of active formatting elements and the stack of open + elements if the end tag didn't already remove it (it + might not have if the element is not in table scope). */ + $leng = count($this->a_formatting); + + for ($n = $leng - 1; $n >= 0; $n--) { + if ($this->a_formatting[$n] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$n]->nodeName === 'a') { + $this->emitToken( + array( + 'name' => 'a', + 'type' => HTML5::ENDTAG + ) + ); + break; + } + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag whose tag name is one of: "b", "big", "em", "font", + "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + /* A start tag token whose tag name is "button" */ + case 'button': + /* If the stack of open elements has a button element in scope, + then this is a parse error; act as if an end tag with the tag + name "button" had been seen, then reprocess the token. (We don't + do that. Unnecessary.) */ + if ($this->elementInScope('button')) { + $this->inBody( + array( + 'name' => 'button', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is one of: "marquee", "object" */ + case 'marquee': + case 'object': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + break; + + /* A start tag token whose tag name is "xmp" */ + case 'xmp': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Switch the content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "table" */ + case 'table': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + break; + + /* A start tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'img': + case 'param': + case 'spacer': + case 'wbr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "hr" */ + case 'hr': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "image" */ + case 'image': + /* Parse error. Change the token's tag name to "img" and + reprocess it. (Don't ask.) */ + $token['name'] = 'img'; + return $this->inBody($token); + break; + + /* A start tag whose tag name is "input" */ + case 'input': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an input element for the token. */ + $element = $this->insertElement($token, false); + + /* If the form element pointer is not null, then associate the + input element with the form element pointed to by the form + element pointer. */ + $this->form_pointer !== null + ? $this->form_pointer->appendChild($element) + : end($this->stack)->appendChild($element); + + /* Pop that input element off the stack of open elements. */ + array_pop($this->stack); + break; + + /* A start tag whose tag name is "isindex" */ + case 'isindex': + /* Parse error. */ + // w/e + + /* If the form element pointer is not null, + then ignore the token. */ + if ($this->form_pointer === null) { + /* Act as if a start tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a start tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + /* Act as if a stream of character tokens had been seen. */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if a start tag token with the tag name "input" + had been seen, with all the attributes from the "isindex" + token, except with the "name" attribute set to the value + "isindex" (ignoring any explicit "name" attribute). */ + $attr = $token['attr']; + $attr[] = array('name' => 'name', 'value' => 'isindex'); + + $this->inBody( + array( + 'name' => 'input', + 'type' => HTML5::STARTTAG, + 'attr' => $attr + ) + ); + + /* Act as if a stream of character tokens had been seen + (see below for what they should say). */ + $this->insertText( + 'This is a searchable index. ' . + 'Insert your search keywords here: ' + ); + + /* Act as if an end tag token with the tag name "label" + had been seen. */ + $this->inBody( + array( + 'name' => 'label', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "p" had + been seen. */ + $this->inBody( + array( + 'name' => 'p', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->inBody( + array( + 'name' => 'hr', + 'type' => HTML5::ENDTAG + ) + ); + + /* Act as if an end tag token with the tag name "form" had + been seen. */ + $this->inBody( + array( + 'name' => 'form', + 'type' => HTML5::ENDTAG + ) + ); + } + break; + + /* A start tag whose tag name is "textarea" */ + case 'textarea': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the + RCDATA state. */ + return HTML5::RCDATA; + break; + + /* A start tag whose tag name is one of: "iframe", "noembed", + "noframes" */ + case 'iframe': + case 'noembed': + case 'noframes': + $this->insertElement($token); + + /* Switch the tokeniser's content model flag to the CDATA state. */ + return HTML5::CDATA; + break; + + /* A start tag whose tag name is "select" */ + case 'select': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in select". */ + $this->mode = self::IN_SELECT; + break; + + /* A start or end tag whose tag name is one of: "caption", "col", + "colgroup", "frame", "frameset", "head", "option", "optgroup", + "tbody", "td", "tfoot", "th", "thead", "tr". */ + case 'caption': + case 'col': + case 'colgroup': + case 'frame': + case 'frameset': + case 'head': + case 'option': + case 'optgroup': + case 'tbody': + case 'td': + case 'tfoot': + case 'th': + case 'thead': + case 'tr': + // Parse error. Ignore the token. + break; + + /* A start or end tag whose tag name is one of: "event-source", + "section", "nav", "article", "aside", "header", "footer", + "datagrid", "command" */ + case 'event-source': + case 'section': + case 'nav': + case 'article': + case 'aside': + case 'header': + case 'footer': + case 'datagrid': + case 'command': + // Work in progress! + break; + + /* A start tag token not covered by the previous entries */ + default: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + $this->insertElement($token, true, true); + break; + } + break; + + case HTML5::ENDTAG: + switch ($token['name']) { + /* An end tag with the tag name "body" */ + case 'body': + /* If the second element in the stack of open elements is + not a body element, this is a parse error. Ignore the token. + (innerHTML case) */ + if (count($this->stack) < 2 || $this->stack[1]->nodeName !== 'body') { + // Ignore. + + /* If the current node is not the body element, then this + is a parse error. */ + } elseif (end($this->stack)->nodeName !== 'body') { + // Parse error. + } + + /* Change the insertion mode to "after body". */ + $this->mode = self::AFTER_BODY; + break; + + /* An end tag with the tag name "html" */ + case 'html': + /* Act as if an end tag with tag name "body" had been seen, + then, if that token wasn't ignored, reprocess the current + token. */ + $this->inBody( + array( + 'name' => 'body', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->afterBody($token); + break; + + /* An end tag whose tag name is one of: "address", "blockquote", + "center", "dir", "div", "dl", "fieldset", "listing", "menu", + "ol", "pre", "ul" */ + case 'address': + case 'blockquote': + case 'center': + case 'dir': + case 'div': + case 'dl': + case 'fieldset': + case 'listing': + case 'menu': + case 'ol': + case 'pre': + case 'ul': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with + the same tag name as that of the token, then this + is a parse error. */ + // w/e + + /* If the stack of open elements has an element in + scope with the same tag name as that of the token, + then pop elements from this stack until an element + with that tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is "form" */ + case 'form': + /* If the stack of open elements has an element in scope + with the same tag name as that of the token, then generate + implied end tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + } + + if (end($this->stack)->nodeName !== $token['name']) { + /* Now, if the current node is not an element with the + same tag name as that of the token, then this is a parse + error. */ + // w/e + + } else { + /* Otherwise, if the current node is an element with + the same tag name as that of the token pop that element + from the stack. */ + array_pop($this->stack); + } + + /* In any case, set the form element pointer to null. */ + $this->form_pointer = null; + break; + + /* An end tag whose tag name is "p" */ + case 'p': + /* If the stack of open elements has a p element in scope, + then generate implied end tags, except for p elements. */ + if ($this->elementInScope('p')) { + $this->generateImpliedEndTags(array('p')); + + /* If the current node is not a p element, then this is + a parse error. */ + // k + + /* If the stack of open elements has a p element in + scope, then pop elements from this stack until the stack + no longer has a p element in scope. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->elementInScope('p')) { + array_pop($this->stack); + + } else { + break; + } + } + } + break; + + /* An end tag whose tag name is "dd", "dt", or "li" */ + case 'dd': + case 'dt': + case 'li': + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + generate implied end tags, except for elements with the + same tag name as the token. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(array($token['name'])); + + /* If the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then + pop elements from this stack until an element with that + tag name has been popped from the stack. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': + case 'h2': + case 'h3': + case 'h4': + case 'h5': + case 'h6': + $elements = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'); + + /* If the stack of open elements has in scope an element whose + tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then + generate implied end tags. */ + if ($this->elementInScope($elements)) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as that of the token, then this is a parse error. */ + // w/e + + /* If the stack of open elements has in scope an element + whose tag name is one of "h1", "h2", "h3", "h4", "h5", or + "h6", then pop elements from the stack until an element + with one of those tag names has been popped from the stack. */ + while ($this->elementInScope($elements)) { + array_pop($this->stack); + } + } + break; + + /* An end tag whose tag name is one of: "a", "b", "big", "em", + "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */ + case 'a': + case 'b': + case 'big': + case 'em': + case 'font': + case 'i': + case 'nobr': + case 's': + case 'small': + case 'strike': + case 'strong': + case 'tt': + case 'u': + /* 1. Let the formatting element be the last element in + the list of active formatting elements that: + * is between the end of the list and the last scope + marker in the list, if any, or the start of the list + otherwise, and + * has the same tag name as the token. + */ + while (true) { + for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) { + if ($this->a_formatting[$a] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$a]->tagName === $token['name']) { + $formatting_element = $this->a_formatting[$a]; + $in_stack = in_array($formatting_element, $this->stack, true); + $fe_af_pos = $a; + break; + } + } + + /* If there is no such node, or, if that node is + also in the stack of open elements but the element + is not in scope, then this is a parse error. Abort + these steps. The token is ignored. */ + if (!isset($formatting_element) || ($in_stack && + !$this->elementInScope($token['name'])) + ) { + break; + + /* Otherwise, if there is such a node, but that node + is not in the stack of open elements, then this is a + parse error; remove the element from the list, and + abort these steps. */ + } elseif (isset($formatting_element) && !$in_stack) { + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 2. Let the furthest block be the topmost node in the + stack of open elements that is lower in the stack + than the formatting element, and is not an element in + the phrasing or formatting categories. There might + not be one. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $length = count($this->stack); + + for ($s = $fe_s_pos + 1; $s < $length; $s++) { + $category = $this->getElementCategory($this->stack[$s]->nodeName); + + if ($category !== self::PHRASING && $category !== self::FORMATTING) { + $furthest_block = $this->stack[$s]; + } + } + + /* 3. If there is no furthest block, then the UA must + skip the subsequent steps and instead just pop all + the nodes from the bottom of the stack of open + elements, from the current node up to the formatting + element, and remove the formatting element from the + list of active formatting elements. */ + if (!isset($furthest_block)) { + for ($n = $length - 1; $n >= $fe_s_pos; $n--) { + array_pop($this->stack); + } + + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + break; + } + + /* 4. Let the common ancestor be the element + immediately above the formatting element in the stack + of open elements. */ + $common_ancestor = $this->stack[$fe_s_pos - 1]; + + /* 5. If the furthest block has a parent node, then + remove the furthest block from its parent node. */ + if ($furthest_block->parentNode !== null) { + $furthest_block->parentNode->removeChild($furthest_block); + } + + /* 6. Let a bookmark note the position of the + formatting element in the list of active formatting + elements relative to the elements on either side + of it in the list. */ + $bookmark = $fe_af_pos; + + /* 7. Let node and last node be the furthest block. + Follow these steps: */ + $node = $furthest_block; + $last_node = $furthest_block; + + while (true) { + for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) { + /* 7.1 Let node be the element immediately + prior to node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 7.2 If node is not in the list of active + formatting elements, then remove node from + the stack of open elements and then go back + to step 1. */ + if (!in_array($node, $this->a_formatting, true)) { + unset($this->stack[$n]); + $this->stack = array_merge($this->stack); + + } else { + break; + } + } + + /* 7.3 Otherwise, if node is the formatting + element, then go to the next step in the overall + algorithm. */ + if ($node === $formatting_element) { + break; + + /* 7.4 Otherwise, if last node is the furthest + block, then move the aforementioned bookmark to + be immediately after the node in the list of + active formatting elements. */ + } elseif ($last_node === $furthest_block) { + $bookmark = array_search($node, $this->a_formatting, true) + 1; + } + + /* 7.5 If node has any children, perform a + shallow clone of node, replace the entry for + node in the list of active formatting elements + with an entry for the clone, replace the entry + for node in the stack of open elements with an + entry for the clone, and let node be the clone. */ + if ($node->hasChildNodes()) { + $clone = $node->cloneNode(); + $s_pos = array_search($node, $this->stack, true); + $a_pos = array_search($node, $this->a_formatting, true); + + $this->stack[$s_pos] = $clone; + $this->a_formatting[$a_pos] = $clone; + $node = $clone; + } + + /* 7.6 Insert last node into node, first removing + it from its previous parent node if any. */ + if ($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $node->appendChild($last_node); + + /* 7.7 Let last node be node. */ + $last_node = $node; + } + + /* 8. Insert whatever last node ended up being in + the previous step into the common ancestor node, + first removing it from its previous parent node if + any. */ + if ($last_node->parentNode !== null) { + $last_node->parentNode->removeChild($last_node); + } + + $common_ancestor->appendChild($last_node); + + /* 9. Perform a shallow clone of the formatting + element. */ + $clone = $formatting_element->cloneNode(); + + /* 10. Take all of the child nodes of the furthest + block and append them to the clone created in the + last step. */ + while ($furthest_block->hasChildNodes()) { + $child = $furthest_block->firstChild; + $furthest_block->removeChild($child); + $clone->appendChild($child); + } + + /* 11. Append that clone to the furthest block. */ + $furthest_block->appendChild($clone); + + /* 12. Remove the formatting element from the list + of active formatting elements, and insert the clone + into the list of active formatting elements at the + position of the aforementioned bookmark. */ + $fe_af_pos = array_search($formatting_element, $this->a_formatting, true); + unset($this->a_formatting[$fe_af_pos]); + $this->a_formatting = array_merge($this->a_formatting); + + $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1); + $af_part2 = array_slice($this->a_formatting, $bookmark, count($this->a_formatting)); + $this->a_formatting = array_merge($af_part1, array($clone), $af_part2); + + /* 13. Remove the formatting element from the stack + of open elements, and insert the clone into the stack + of open elements immediately after (i.e. in a more + deeply nested position than) the position of the + furthest block in that stack. */ + $fe_s_pos = array_search($formatting_element, $this->stack, true); + $fb_s_pos = array_search($furthest_block, $this->stack, true); + unset($this->stack[$fe_s_pos]); + + $s_part1 = array_slice($this->stack, 0, $fb_s_pos); + $s_part2 = array_slice($this->stack, $fb_s_pos + 1, count($this->stack)); + $this->stack = array_merge($s_part1, array($clone), $s_part2); + + /* 14. Jump back to step 1 in this series of steps. */ + unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block); + } + break; + + /* An end tag token whose tag name is one of: "button", + "marquee", "object" */ + case 'button': + case 'marquee': + case 'object': + /* If the stack of open elements has an element in scope whose + tag name matches the tag name of the token, then generate implied + tags. */ + if ($this->elementInScope($token['name'])) { + $this->generateImpliedEndTags(); + + /* Now, if the current node is not an element with the same + tag name as the token, then this is a parse error. */ + // k + + /* Now, if the stack of open elements has an element in scope + whose tag name matches the tag name of the token, then pop + elements from the stack until that element has been popped from + the stack, and clear the list of active formatting elements up + to the last marker. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === $token['name']) { + $n = -1; + } + + array_pop($this->stack); + } + + $marker = end(array_keys($this->a_formatting, self::MARKER, true)); + + for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) { + array_pop($this->a_formatting); + } + } + break; + + /* Or an end tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "hr", "iframe", "image", "img", + "input", "isindex", "noembed", "noframes", "param", "select", + "spacer", "table", "textarea", "wbr" */ + case 'area': + case 'basefont': + case 'bgsound': + case 'br': + case 'embed': + case 'hr': + case 'iframe': + case 'image': + case 'img': + case 'input': + case 'isindex': + case 'noembed': + case 'noframes': + case 'param': + case 'select': + case 'spacer': + case 'table': + case 'textarea': + case 'wbr': + // Parse error. Ignore the token. + break; + + /* An end tag token not covered by the previous entries */ + default: + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + /* Initialise node to be the current node (the bottommost + node of the stack). */ + $node = end($this->stack); + + /* If node has the same tag name as the end tag token, + then: */ + if ($token['name'] === $node->nodeName) { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* If the tag name of the end tag token does not + match the tag name of the current node, this is a + parse error. */ + // k + + /* Pop all the nodes from the current node up to + node, including node, then stop this algorithm. */ + for ($x = count($this->stack) - $n; $x >= $n; $x--) { + array_pop($this->stack); + } + + } else { + $category = $this->getElementCategory($node); + + if ($category !== self::SPECIAL && $category !== self::SCOPING) { + /* Otherwise, if node is in neither the formatting + category nor the phrasing category, then this is a + parse error. Stop this algorithm. The end tag token + is ignored. */ + return false; + } + } + } + break; + } + break; + } + } + + private function inTable($token) + { + $clear = array('html', 'table'); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "caption" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'caption' + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + + /* Insert an HTML element for the token, then switch the + insertion mode to "in caption". */ + $this->insertElement($token); + $this->mode = self::IN_CAPTION; + + /* A start tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'colgroup' + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the + insertion mode to "in column group". */ + $this->insertElement($token); + $this->mode = self::IN_CGROUP; + + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'col' + ) { + $this->inTable( + array( + 'name' => 'colgroup', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + $this->inColumnGroup($token); + + /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('tbody', 'tfoot', 'thead') + ) + ) { + /* Clear the stack back to a table context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in table body". */ + $this->insertElement($token); + $this->mode = self::IN_TBODY; + + /* A start tag whose tag name is one of: "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && + in_array($token['name'], array('td', 'th', 'tr')) + ) { + /* Act as if a start tag token with the tag name "tbody" had been + seen, then reprocess the current token. */ + $this->inTable( + array( + 'name' => 'tbody', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inTableBody($token); + + /* A start tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'table' + ) { + /* Parse error. Act as if an end tag token with the tag name "table" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inTable( + array( + 'name' => 'table', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->mainPhase($token); + + /* An end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table' + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + return false; + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a table element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a table element has been + popped from the stack. */ + while (true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($current === 'table') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'caption', + 'col', + 'colgroup', + 'html', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Parse error. Process the token as if the insertion mode was "in + body", with the following exception: */ + + /* If the current node is a table, tbody, tfoot, thead, or tr + element, then, whenever a node would be inserted into the current + node, it must instead be inserted into the foster parent element. */ + if (in_array( + end($this->stack)->nodeName, + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* The foster parent element is the parent element of the last + table element in the stack of open elements, if there is a + table element and it has such a parent element. If there is no + table element in the stack of open elements (innerHTML case), + then the foster parent element is the first element in the + stack of open elements (the html element). Otherwise, if there + is a table element in the stack of open elements, but the last + table element in the stack of open elements has no parent, or + its parent node is not an element, then the foster parent + element is the element before the last table element in the + stack of open elements. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table') { + $table = $this->stack[$n]; + break; + } + } + + if (isset($table) && $table->parentNode !== null) { + $this->foster_parent = $table->parentNode; + + } elseif (!isset($table)) { + $this->foster_parent = $this->stack[0]; + + } elseif (isset($table) && ($table->parentNode === null || + $table->parentNode->nodeType !== XML_ELEMENT_NODE) + ) { + $this->foster_parent = $this->stack[$n - 1]; + } + } + + $this->inBody($token); + } + } + + private function inCaption($token) + { + /* An end tag whose tag name is "caption" */ + if ($token['type'] === HTML5::ENDTAG && $token['name'] === 'caption') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Generate implied end tags. */ + $this->generateImpliedEndTags(); + + /* Now, if the current node is not a caption element, then this + is a parse error. */ + // w/e + + /* Pop elements from this stack until a caption element has + been popped from the stack. */ + while (true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($node === 'caption') { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag + name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + )) || ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'table') + ) { + /* Parse error. Act as if an end tag with the tag name "caption" + had been seen, then, if that token wasn't ignored, reprocess the + current token. */ + $this->inCaption( + array( + 'name' => 'caption', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inTable($token); + + /* An end tag whose tag name is one of: "body", "col", "colgroup", + "html", "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array( + 'body', + 'col', + 'colgroup', + 'html', + 'tbody', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + // Parse error. Ignore the token. + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inColumnGroup($token) + { + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $text = $this->dom->createTextNode($token['data']); + end($this->stack)->appendChild($text); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + end($this->stack)->appendChild($comment); + + /* A start tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::STARTTAG && $token['name'] === 'col') { + /* Insert a col element for the token. Immediately pop the current + node off the stack of open elements. */ + $this->insertElement($token); + array_pop($this->stack); + + /* An end tag whose tag name is "colgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'colgroup' + ) { + /* If the current node is the root html element, then this is a + parse error, ignore the token. (innerHTML case) */ + if (end($this->stack)->nodeName === 'html') { + // Ignore + + /* Otherwise, pop the current node (which will be a colgroup + element) from the stack of open elements. Switch the insertion + mode to "in table". */ + } else { + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* An end tag whose tag name is "col" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'col') { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Act as if an end tag with the tag name "colgroup" had been seen, + and then, if that token wasn't ignored, reprocess the current token. */ + $this->inColumnGroup( + array( + 'name' => 'colgroup', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inTable($token); + } + } + + private function inTableBody($token) + { + $clear = array('tbody', 'tfoot', 'thead', 'html'); + + /* A start tag whose tag name is "tr" */ + if ($token['type'] === HTML5::STARTTAG && $token['name'] === 'tr') { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Insert a tr element for the token, then switch the insertion + mode to "in row". */ + $this->insertElement($token); + $this->mode = self::IN_ROW; + + /* A start tag whose tag name is one of: "th", "td" */ + } elseif ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { + /* Parse error. Act as if a start tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inTableBody( + array( + 'name' => 'tr', + 'type' => HTML5::STARTTAG, + 'attr' => array() + ) + ); + + return $this->inRow($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node from the stack of open elements. Switch + the insertion mode to "in table". */ + array_pop($this->stack); + $this->mode = self::IN_TABLE; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */ + } elseif (($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoor', 'thead') + )) || + ($token['type'] === HTML5::STARTTAG && $token['name'] === 'table') + ) { + /* If the stack of open elements does not have a tbody, thead, or + tfoot element in table scope, this is a parse error. Ignore the + token. (innerHTML case) */ + if (!$this->elementInScope(array('tbody', 'thead', 'tfoot'), true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table body context. */ + $this->clearStackToTableContext($clear); + + /* Act as if an end tag with the same tag name as the current + node ("tbody", "tfoot", or "thead") had been seen, then + reprocess the current token. */ + $this->inTableBody( + array( + 'name' => end($this->stack)->nodeName, + 'type' => HTML5::ENDTAG + ) + ); + + return $this->mainPhase($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inRow($token) + { + $clear = array('tr', 'html'); + + /* A start tag whose tag name is one of: "th", "td" */ + if ($token['type'] === HTML5::STARTTAG && + ($token['name'] === 'th' || $token['name'] === 'td') + ) { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Insert an HTML element for the token, then switch the insertion + mode to "in cell". */ + $this->insertElement($token); + $this->mode = self::IN_CELL; + + /* Insert a marker at the end of the list of active formatting + elements. */ + $this->a_formatting[] = self::MARKER; + + /* An end tag whose tag name is "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'tr') { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Clear the stack back to a table row context. */ + $this->clearStackToTableContext($clear); + + /* Pop the current node (which will be a tr element) from the + stack of open elements. Switch the insertion mode to "in table + body". */ + array_pop($this->stack); + $this->mode = self::IN_TBODY; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array('caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* Act as if an end tag with the tag name "tr" had been seen, then, + if that token wasn't ignored, reprocess the current token. */ + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inCell($token); + + /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */ + } elseif ($token['type'] === HTML5::ENDTAG && + in_array($token['name'], array('tbody', 'tfoot', 'thead')) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Otherwise, act as if an end tag with the tag name "tr" had + been seen, then reprocess the current token. */ + $this->inRow( + array( + 'name' => 'tr', + 'type' => HTML5::ENDTAG + ) + ); + + return $this->inCell($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html", "td", "th" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr') + ) + ) { + /* Parse error. Ignore the token. */ + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in table". */ + $this->inTable($token); + } + } + + private function inCell($token) + { + /* An end tag whose tag name is one of: "td", "th" */ + if ($token['type'] === HTML5::ENDTAG && + ($token['name'] === 'td' || $token['name'] === 'th') + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token, then this is a + parse error and the token must be ignored. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise: */ + } else { + /* Generate implied end tags, except for elements with the same + tag name as the token. */ + $this->generateImpliedEndTags(array($token['name'])); + + /* Now, if the current node is not an element with the same tag + name as the token, then this is a parse error. */ + // k + + /* Pop elements from this stack until an element with the same + tag name as the token has been popped from the stack. */ + while (true) { + $node = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($node === $token['name']) { + break; + } + } + + /* Clear the list of active formatting elements up to the last + marker. */ + $this->clearTheActiveFormattingElementsUpToTheLastMarker(); + + /* Switch the insertion mode to "in row". (The current node + will be a tr element at this point.) */ + $this->mode = self::IN_ROW; + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if (!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* A start tag whose tag name is one of: "caption", "col", "colgroup", + "tbody", "td", "tfoot", "th", "thead", "tr" */ + } elseif ($token['type'] === HTML5::STARTTAG && in_array( + $token['name'], + array( + 'caption', + 'col', + 'colgroup', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'tr' + ) + ) + ) { + /* If the stack of open elements does not have a td or th element + in table scope, then this is a parse error; ignore the token. + (innerHTML case) */ + if (!$this->elementInScope(array('td', 'th'), true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* An end tag whose tag name is one of: "body", "caption", "col", + "colgroup", "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('body', 'caption', 'col', 'colgroup', 'html') + ) + ) { + /* Parse error. Ignore the token. */ + + /* An end tag whose tag name is one of: "table", "tbody", "tfoot", + "thead", "tr" */ + } elseif ($token['type'] === HTML5::ENDTAG && in_array( + $token['name'], + array('table', 'tbody', 'tfoot', 'thead', 'tr') + ) + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as that of the token (which can only + happen for "tbody", "tfoot" and "thead", or, in the innerHTML case), + then this is a parse error and the token must be ignored. */ + if (!$this->elementInScope($token['name'], true)) { + // Ignore. + + /* Otherwise, close the cell (see below) and reprocess the current + token. */ + } else { + $this->closeCell(); + return $this->inRow($token); + } + + /* Anything else */ + } else { + /* Process the token as if the insertion mode was "in body". */ + $this->inBody($token); + } + } + + private function inSelect($token) + { + /* Handle the token as follows: */ + + /* A character token */ + if ($token['type'] === HTML5::CHARACTR) { + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'option' + ) { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* A start tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::STARTTAG && + $token['name'] === 'optgroup' + ) { + /* If the current node is an option element, act as if an end tag + with the tag name "option" had been seen. */ + if (end($this->stack)->nodeName === 'option') { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the current node is an optgroup element, act as if an end tag + with the tag name "optgroup" had been seen. */ + if (end($this->stack)->nodeName === 'optgroup') { + $this->inSelect( + array( + 'name' => 'optgroup', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* An end tag token whose tag name is "optgroup" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'optgroup' + ) { + /* First, if the current node is an option element, and the node + immediately before it in the stack of open elements is an optgroup + element, then act as if an end tag with the tag name "option" had + been seen. */ + $elements_in_stack = count($this->stack); + + if ($this->stack[$elements_in_stack - 1]->nodeName === 'option' && + $this->stack[$elements_in_stack - 2]->nodeName === 'optgroup' + ) { + $this->inSelect( + array( + 'name' => 'option', + 'type' => HTML5::ENDTAG + ) + ); + } + + /* If the current node is an optgroup element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if ($this->stack[$elements_in_stack - 1] === 'optgroup') { + array_pop($this->stack); + } + + /* An end tag token whose tag name is "option" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'option' + ) { + /* If the current node is an option element, then pop that node + from the stack of open elements. Otherwise, this is a parse error, + ignore the token. */ + if (end($this->stack)->nodeName === 'option') { + array_pop($this->stack); + } + + /* An end tag whose tag name is "select" */ + } elseif ($token['type'] === HTML5::ENDTAG && + $token['name'] === 'select' + ) { + /* If the stack of open elements does not have an element in table + scope with the same tag name as the token, this is a parse error. + Ignore the token. (innerHTML case) */ + if (!$this->elementInScope($token['name'], true)) { + // w/e + + /* Otherwise: */ + } else { + /* Pop elements from the stack of open elements until a select + element has been popped from the stack. */ + while (true) { + $current = end($this->stack)->nodeName; + array_pop($this->stack); + + if ($current === 'select') { + break; + } + } + + /* Reset the insertion mode appropriately. */ + $this->resetInsertionMode(); + } + + /* A start tag whose tag name is "select" */ + } elseif ($token['name'] === 'select' && + $token['type'] === HTML5::STARTTAG + ) { + /* Parse error. Act as if the token had been an end tag with the + tag name "select" instead. */ + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); + + /* An end tag whose tag name is one of: "caption", "table", "tbody", + "tfoot", "thead", "tr", "td", "th" */ + } elseif (in_array( + $token['name'], + array( + 'caption', + 'table', + 'tbody', + 'tfoot', + 'thead', + 'tr', + 'td', + 'th' + ) + ) && $token['type'] === HTML5::ENDTAG + ) { + /* Parse error. */ + // w/e + + /* If the stack of open elements has an element in table scope with + the same tag name as that of the token, then act as if an end tag + with the tag name "select" had been seen, and reprocess the token. + Otherwise, ignore the token. */ + if ($this->elementInScope($token['name'], true)) { + $this->inSelect( + array( + 'name' => 'select', + 'type' => HTML5::ENDTAG + ) + ); + + $this->mainPhase($token); + } + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterBody($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Process the token as it would be processed if the insertion mode + was "in body". */ + $this->inBody($token); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the first element in the stack of open + elements (the html element), with the data attribute set to the + data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->stack[0]->appendChild($comment); + + /* An end tag with the tag name "html" */ + } elseif ($token['type'] === HTML5::ENDTAG && $token['name'] === 'html') { + /* If the parser was originally created in order to handle the + setting of an element's innerHTML attribute, this is a parse error; + ignore the token. (The element will be an html element in this + case.) (innerHTML case) */ + + /* Otherwise, switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* Anything else */ + } else { + /* Parse error. Set the insertion mode to "in body" and reprocess + the token. */ + $this->mode = self::IN_BODY; + return $this->inBody($token); + } + } + + private function inFrameset($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A start tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::STARTTAG + ) { + $this->insertElement($token); + + /* An end tag with the tag name "frameset" */ + } elseif ($token['name'] === 'frameset' && + $token['type'] === HTML5::ENDTAG + ) { + /* If the current node is the root html element, then this is a + parse error; ignore the token. (innerHTML case) */ + if (end($this->stack)->nodeName === 'html') { + // Ignore + + } else { + /* Otherwise, pop the current node from the stack of open + elements. */ + array_pop($this->stack); + + /* If the parser was not originally created in order to handle + the setting of an element's innerHTML attribute (innerHTML case), + and the current node is no longer a frameset element, then change + the insertion mode to "after frameset". */ + $this->mode = self::AFTR_FRAME; + } + + /* A start tag with the tag name "frame" */ + } elseif ($token['name'] === 'frame' && + $token['type'] === HTML5::STARTTAG + ) { + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function afterFrameset($token) + { + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */ + if ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* An end tag with the tag name "html" */ + } elseif ($token['name'] === 'html' && + $token['type'] === HTML5::ENDTAG + ) { + /* Switch to the trailing end phase. */ + $this->phase = self::END_PHASE; + + /* A start tag with the tag name "noframes" */ + } elseif ($token['name'] === 'noframes' && + $token['type'] === HTML5::STARTTAG + ) { + /* Process the token as if the insertion mode had been "in body". */ + $this->inBody($token); + + /* Anything else */ + } else { + /* Parse error. Ignore the token. */ + } + } + + private function trailingEndPhase($token) + { + /* After the main phase, as each token is emitted from the tokenisation + stage, it must be processed as described in this section. */ + + /* A DOCTYPE token */ + if ($token['type'] === HTML5::DOCTYPE) { + // Parse error. Ignore the token. + + /* A comment token */ + } elseif ($token['type'] === HTML5::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data']) + ) { + /* Process the token as it would be processed in the main phase. */ + $this->mainPhase($token); + + /* A character token that is not one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. Or a start tag token. Or an end tag token. */ + } elseif (($token['type'] === HTML5::CHARACTR && + preg_match('/^[\t\n\x0b\x0c ]+$/', $token['data'])) || + $token['type'] === HTML5::STARTTAG || $token['type'] === HTML5::ENDTAG + ) { + /* Parse error. Switch back to the main phase and reprocess the + token. */ + $this->phase = self::MAIN_PHASE; + return $this->mainPhase($token); + + /* An end-of-file token */ + } elseif ($token['type'] === HTML5::EOF) { + /* OMG DONE!! */ + } + } + + private function insertElement($token, $append = true, $check = false) + { + // Proprietary workaround for libxml2's limitations with tag names + if ($check) { + // Slightly modified HTML5 tag-name modification, + // removing anything that's not an ASCII letter, digit, or hyphen + $token['name'] = preg_replace('/[^a-z0-9-]/i', '', $token['name']); + // Remove leading hyphens and numbers + $token['name'] = ltrim($token['name'], '-0..9'); + // In theory, this should ever be needed, but just in case + if ($token['name'] === '') { + $token['name'] = 'span'; + } // arbitrary generic choice + } + + $el = $this->dom->createElement($token['name']); + + foreach ($token['attr'] as $attr) { + if (!$el->hasAttribute($attr['name'])) { + $el->setAttribute($attr['name'], $attr['value']); + } + } + + $this->appendToRealParent($el); + $this->stack[] = $el; + + return $el; + } + + private function insertText($data) + { + $text = $this->dom->createTextNode($data); + $this->appendToRealParent($text); + } + + private function insertComment($data) + { + $comment = $this->dom->createComment($data); + $this->appendToRealParent($comment); + } + + private function appendToRealParent($node) + { + if ($this->foster_parent === null) { + end($this->stack)->appendChild($node); + + } elseif ($this->foster_parent !== null) { + /* If the foster parent element is the parent element of the + last table element in the stack of open elements, then the new + node must be inserted immediately before the last table element + in the stack of open elements in the foster parent element; + otherwise, the new node must be appended to the foster parent + element. */ + for ($n = count($this->stack) - 1; $n >= 0; $n--) { + if ($this->stack[$n]->nodeName === 'table' && + $this->stack[$n]->parentNode !== null + ) { + $table = $this->stack[$n]; + break; + } + } + + if (isset($table) && $this->foster_parent->isSameNode($table->parentNode)) { + $this->foster_parent->insertBefore($node, $table); + } else { + $this->foster_parent->appendChild($node); + } + + $this->foster_parent = null; + } + } + + private function elementInScope($el, $table = false) + { + if (is_array($el)) { + foreach ($el as $element) { + if ($this->elementInScope($element, $table)) { + return true; + } + } + + return false; + } + + $leng = count($this->stack); + + for ($n = 0; $n < $leng; $n++) { + /* 1. Initialise node to be the current node (the bottommost node of + the stack). */ + $node = $this->stack[$leng - 1 - $n]; + + if ($node->tagName === $el) { + /* 2. If node is the target node, terminate in a match state. */ + return true; + + } elseif ($node->tagName === 'table') { + /* 3. Otherwise, if node is a table element, terminate in a failure + state. */ + return false; + + } elseif ($table === true && in_array( + $node->tagName, + array( + 'caption', + 'td', + 'th', + 'button', + 'marquee', + 'object' + ) + ) + ) { + /* 4. Otherwise, if the algorithm is the "has an element in scope" + variant (rather than the "has an element in table scope" variant), + and node is one of the following, terminate in a failure state. */ + return false; + + } elseif ($node === $node->ownerDocument->documentElement) { + /* 5. Otherwise, if node is an html element (root element), terminate + in a failure state. (This can only happen if the node is the topmost + node of the stack of open elements, and prevents the next step from + being invoked if there are no more elements in the stack.) */ + return false; + } + + /* Otherwise, set node to the previous entry in the stack of open + elements and return to step 2. (This will never fail, since the loop + will always terminate in the previous step if the top of the stack + is reached.) */ + } + } + + private function reconstructActiveFormattingElements() + { + /* 1. If there are no entries in the list of active formatting elements, + then there is nothing to reconstruct; stop this algorithm. */ + $formatting_elements = count($this->a_formatting); + + if ($formatting_elements === 0) { + return false; + } + + /* 3. Let entry be the last (most recently added) element in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. If the last (most recently added) entry in the list of active + formatting elements is a marker, or if it is an element that is in the + stack of open elements, then there is nothing to reconstruct; stop this + algorithm. */ + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { + return false; + } + + for ($a = $formatting_elements - 1; $a >= 0; true) { + /* 4. If there are no entries before entry in the list of active + formatting elements, then jump to step 8. */ + if ($a === 0) { + $step_seven = false; + break; + } + + /* 5. Let entry be the entry one earlier than entry in the list of + active formatting elements. */ + $a--; + $entry = $this->a_formatting[$a]; + + /* 6. If entry is neither a marker nor an element that is also in + thetack of open elements, go to step 4. */ + if ($entry === self::MARKER || in_array($entry, $this->stack, true)) { + break; + } + } + + while (true) { + /* 7. Let entry be the element one later than entry in the list of + active formatting elements. */ + if (isset($step_seven) && $step_seven === true) { + $a++; + $entry = $this->a_formatting[$a]; + } + + /* 8. Perform a shallow clone of the element entry to obtain clone. */ + $clone = $entry->cloneNode(); + + /* 9. Append clone to the current node and push it onto the stack + of open elements so that it is the new current node. */ + end($this->stack)->appendChild($clone); + $this->stack[] = $clone; + + /* 10. Replace the entry for entry in the list with an entry for + clone. */ + $this->a_formatting[$a] = $clone; + + /* 11. If the entry for clone in the list of active formatting + elements is not the last entry in the list, return to step 7. */ + if (end($this->a_formatting) !== $clone) { + $step_seven = true; + } else { + break; + } + } + } + + private function clearTheActiveFormattingElementsUpToTheLastMarker() + { + /* When the steps below require the UA to clear the list of active + formatting elements up to the last marker, the UA must perform the + following steps: */ + + while (true) { + /* 1. Let entry be the last (most recently added) entry in the list + of active formatting elements. */ + $entry = end($this->a_formatting); + + /* 2. Remove entry from the list of active formatting elements. */ + array_pop($this->a_formatting); + + /* 3. If entry was a marker, then stop the algorithm at this point. + The list has been cleared up to the last marker. */ + if ($entry === self::MARKER) { + break; + } + } + } + + private function generateImpliedEndTags($exclude = array()) + { + /* When the steps below require the UA to generate implied end tags, + then, if the current node is a dd element, a dt element, an li element, + a p element, a td element, a th element, or a tr element, the UA must + act as if an end tag with the respective tag name had been seen and + then generate implied end tags again. */ + $node = end($this->stack); + $elements = array_diff(array('dd', 'dt', 'li', 'p', 'td', 'th', 'tr'), $exclude); + + while (in_array(end($this->stack)->nodeName, $elements)) { + array_pop($this->stack); + } + } + + private function getElementCategory($node) + { + $name = $node->tagName; + if (in_array($name, $this->special)) { + return self::SPECIAL; + } elseif (in_array($name, $this->scoping)) { + return self::SCOPING; + } elseif (in_array($name, $this->formatting)) { + return self::FORMATTING; + } else { + return self::PHRASING; + } + } + + private function clearStackToTableContext($elements) + { + /* When the steps above require the UA to clear the stack back to a + table context, it means that the UA must, while the current node is not + a table element or an html element, pop elements from the stack of open + elements. If this causes any elements to be popped from the stack, then + this is a parse error. */ + while (true) { + $node = end($this->stack)->nodeName; + + if (in_array($node, $elements)) { + break; + } else { + array_pop($this->stack); + } + } + } + + private function resetInsertionMode() + { + /* 1. Let last be false. */ + $last = false; + $leng = count($this->stack); + + for ($n = $leng - 1; $n >= 0; $n--) { + /* 2. Let node be the last node in the stack of open elements. */ + $node = $this->stack[$n]; + + /* 3. If node is the first node in the stack of open elements, then + set last to true. If the element whose innerHTML attribute is being + set is neither a td element nor a th element, then set node to the + element whose innerHTML attribute is being set. (innerHTML case) */ + if ($this->stack[0]->isSameNode($node)) { + $last = true; + } + + /* 4. If node is a select element, then switch the insertion mode to + "in select" and abort these steps. (innerHTML case) */ + if ($node->nodeName === 'select') { + $this->mode = self::IN_SELECT; + break; + + /* 5. If node is a td or th element, then switch the insertion mode + to "in cell" and abort these steps. */ + } elseif ($node->nodeName === 'td' || $node->nodeName === 'th') { + $this->mode = self::IN_CELL; + break; + + /* 6. If node is a tr element, then switch the insertion mode to + "in row" and abort these steps. */ + } elseif ($node->nodeName === 'tr') { + $this->mode = self::IN_ROW; + break; + + /* 7. If node is a tbody, thead, or tfoot element, then switch the + insertion mode to "in table body" and abort these steps. */ + } elseif (in_array($node->nodeName, array('tbody', 'thead', 'tfoot'))) { + $this->mode = self::IN_TBODY; + break; + + /* 8. If node is a caption element, then switch the insertion mode + to "in caption" and abort these steps. */ + } elseif ($node->nodeName === 'caption') { + $this->mode = self::IN_CAPTION; + break; + + /* 9. If node is a colgroup element, then switch the insertion mode + to "in column group" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'colgroup') { + $this->mode = self::IN_CGROUP; + break; + + /* 10. If node is a table element, then switch the insertion mode + to "in table" and abort these steps. */ + } elseif ($node->nodeName === 'table') { + $this->mode = self::IN_TABLE; + break; + + /* 11. If node is a head element, then switch the insertion mode + to "in body" ("in body"! not "in head"!) and abort these steps. + (innerHTML case) */ + } elseif ($node->nodeName === 'head') { + $this->mode = self::IN_BODY; + break; + + /* 12. If node is a body element, then switch the insertion mode to + "in body" and abort these steps. */ + } elseif ($node->nodeName === 'body') { + $this->mode = self::IN_BODY; + break; + + /* 13. If node is a frameset element, then switch the insertion + mode to "in frameset" and abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'frameset') { + $this->mode = self::IN_FRAME; + break; + + /* 14. If node is an html element, then: if the head element + pointer is null, switch the insertion mode to "before head", + otherwise, switch the insertion mode to "after head". In either + case, abort these steps. (innerHTML case) */ + } elseif ($node->nodeName === 'html') { + $this->mode = ($this->head_pointer === null) + ? self::BEFOR_HEAD + : self::AFTER_HEAD; + + break; + + /* 15. If last is true, then set the insertion mode to "in body" + and abort these steps. (innerHTML case) */ + } elseif ($last) { + $this->mode = self::IN_BODY; + break; + } + } + } + + private function closeCell() + { + /* If the stack of open elements has a td or th element in table scope, + then act as if an end tag token with that tag name had been seen. */ + foreach (array('td', 'th') as $cell) { + if ($this->elementInScope($cell, true)) { + $this->inCell( + array( + 'name' => $cell, + 'type' => HTML5::ENDTAG + ) + ); + + break; + } + } + } + + public function save() + { + return $this->dom; + } +} diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer.php new file mode 100644 index 0000000..549e4ce --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer.php @@ -0,0 +1,218 @@ +getAll(); + $context = new HTMLPurifier_Context(); + $this->generator = new HTMLPurifier_Generator($config, $context); + } + + /** + * Main function that renders object or aspect of that object + * @note Parameters vary depending on printer + */ + // function render() {} + + /** + * Returns a start tag + * @param string $tag Tag name + * @param array $attr Attribute array + * @return string + */ + protected function start($tag, $attr = array()) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Start($tag, $attr ? $attr : array()) + ); + } + + /** + * Returns an end tag + * @param string $tag Tag name + * @return string + */ + protected function end($tag) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_End($tag) + ); + } + + /** + * Prints a complete element with content inside + * @param string $tag Tag name + * @param string $contents Element contents + * @param array $attr Tag attributes + * @param bool $escape whether or not to escape contents + * @return string + */ + protected function element($tag, $contents, $attr = array(), $escape = true) + { + return $this->start($tag, $attr) . + ($escape ? $this->escape($contents) : $contents) . + $this->end($tag); + } + + /** + * @param string $tag + * @param array $attr + * @return string + */ + protected function elementEmpty($tag, $attr = array()) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Empty($tag, $attr) + ); + } + + /** + * @param string $text + * @return string + */ + protected function text($text) + { + return $this->generator->generateFromToken( + new HTMLPurifier_Token_Text($text) + ); + } + + /** + * Prints a simple key/value row in a table. + * @param string $name Key + * @param mixed $value Value + * @return string + */ + protected function row($name, $value) + { + if (is_bool($value)) { + $value = $value ? 'On' : 'Off'; + } + return + $this->start('tr') . "\n" . + $this->element('th', $name) . "\n" . + $this->element('td', $value) . "\n" . + $this->end('tr'); + } + + /** + * Escapes a string for HTML output. + * @param string $string String to escape + * @return string + */ + protected function escape($string) + { + $string = HTMLPurifier_Encoder::cleanUTF8($string); + $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8'); + return $string; + } + + /** + * Takes a list of strings and turns them into a single list + * @param string[] $array List of strings + * @param bool $polite Bool whether or not to add an end before the last + * @return string + */ + protected function listify($array, $polite = false) + { + if (empty($array)) { + return 'None'; + } + $ret = ''; + $i = count($array); + foreach ($array as $value) { + $i--; + $ret .= $value; + if ($i > 0 && !($polite && $i == 1)) { + $ret .= ', '; + } + if ($polite && $i == 1) { + $ret .= 'and '; + } + } + return $ret; + } + + /** + * Retrieves the class of an object without prefixes, as well as metadata + * @param object $obj Object to determine class of + * @param string $sec_prefix Further prefix to remove + * @return string + */ + protected function getClass($obj, $sec_prefix = '') + { + static $five = null; + if ($five === null) { + $five = version_compare(PHP_VERSION, '5', '>='); + } + $prefix = 'HTMLPurifier_' . $sec_prefix; + if (!$five) { + $prefix = strtolower($prefix); + } + $class = str_replace($prefix, '', get_class($obj)); + $lclass = strtolower($class); + $class .= '('; + switch ($lclass) { + case 'enum': + $values = array(); + foreach ($obj->valid_values as $value => $bool) { + $values[] = $value; + } + $class .= implode(', ', $values); + break; + case 'css_composite': + $values = array(); + foreach ($obj->defs as $def) { + $values[] = $this->getClass($def, $sec_prefix); + } + $class .= implode(', ', $values); + break; + case 'css_multiple': + $class .= $this->getClass($obj->single, $sec_prefix) . ', '; + $class .= $obj->max; + break; + case 'css_denyelementdecorator': + $class .= $this->getClass($obj->def, $sec_prefix) . ', '; + $class .= $obj->element; + break; + case 'css_importantdecorator': + $class .= $this->getClass($obj->def, $sec_prefix); + if ($obj->allow) { + $class .= ', !important'; + } + break; + } + $class .= ')'; + return $class; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/CSSDefinition.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/CSSDefinition.php new file mode 100644 index 0000000..29505fe --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/CSSDefinition.php @@ -0,0 +1,44 @@ +def = $config->getCSSDefinition(); + $ret = ''; + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + $ret .= $this->start('table'); + + $ret .= $this->element('caption', 'Properties ($info)'); + + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Property', array('class' => 'heavy')); + $ret .= $this->element('th', 'Definition', array('class' => 'heavy', 'style' => 'width:auto;')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + + ksort($this->def->info); + foreach ($this->def->info as $property => $obj) { + $name = $this->getClass($obj, 'AttrDef_'); + $ret .= $this->row($property, $name); + } + + $ret .= $this->end('table'); + $ret .= $this->end('div'); + + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.css b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.css new file mode 100644 index 0000000..3ff1a88 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.css @@ -0,0 +1,10 @@ + +.hp-config {} + +.hp-config tbody th {text-align:right; padding-right:0.5em;} +.hp-config thead, .hp-config .namespace {background:#3C578C; color:#FFF;} +.hp-config .namespace th {text-align:center;} +.hp-config .verbose {display:none;} +.hp-config .controls {text-align:center;} + +/* vim: et sw=4 sts=4 */ diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.js b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.js new file mode 100644 index 0000000..cba00c9 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.js @@ -0,0 +1,5 @@ +function toggleWriteability(id_of_patient, checked) { + document.getElementById(id_of_patient).disabled = checked; +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.php new file mode 100644 index 0000000..65a7779 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/ConfigForm.php @@ -0,0 +1,451 @@ +docURL = $doc_url; + $this->name = $name; + $this->compress = $compress; + // initialize sub-printers + $this->fields[0] = new HTMLPurifier_Printer_ConfigForm_default(); + $this->fields[HTMLPurifier_VarParser::BOOL] = new HTMLPurifier_Printer_ConfigForm_bool(); + } + + /** + * Sets default column and row size for textareas in sub-printers + * @param $cols Integer columns of textarea, null to use default + * @param $rows Integer rows of textarea, null to use default + */ + public function setTextareaDimensions($cols = null, $rows = null) + { + if ($cols) { + $this->fields['default']->cols = $cols; + } + if ($rows) { + $this->fields['default']->rows = $rows; + } + } + + /** + * Retrieves styling, in case it is not accessible by webserver + */ + public static function getCSS() + { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.css'); + } + + /** + * Retrieves JavaScript, in case it is not accessible by webserver + */ + public static function getJavaScript() + { + return file_get_contents(HTMLPURIFIER_PREFIX . '/HTMLPurifier/Printer/ConfigForm.js'); + } + + /** + * Returns HTML output for a configuration form + * @param HTMLPurifier_Config|array $config Configuration object of current form state, or an array + * where [0] has an HTML namespace and [1] is being rendered. + * @param array|bool $allowed Optional namespace(s) and directives to restrict form to. + * @param bool $render_controls + * @return string + */ + public function render($config, $allowed = true, $render_controls = true) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + + $this->config = $config; + $this->genConfig = $gen_config; + $this->prepareGenerator($gen_config); + + $allowed = HTMLPurifier_Config::getAllowedDirectivesForForm($allowed, $config->def); + $all = array(); + foreach ($allowed as $key) { + list($ns, $directive) = $key; + $all[$ns][$directive] = $config->get($ns . '.' . $directive); + } + + $ret = ''; + $ret .= $this->start('table', array('class' => 'hp-config')); + $ret .= $this->start('thead'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Directive', array('class' => 'hp-directive')); + $ret .= $this->element('th', 'Value', array('class' => 'hp-value')); + $ret .= $this->end('tr'); + $ret .= $this->end('thead'); + foreach ($all as $ns => $directives) { + $ret .= $this->renderNamespace($ns, $directives); + } + if ($render_controls) { + $ret .= $this->start('tbody'); + $ret .= $this->start('tr'); + $ret .= $this->start('td', array('colspan' => 2, 'class' => 'controls')); + $ret .= $this->elementEmpty('input', array('type' => 'submit', 'value' => 'Submit')); + $ret .= '[Reset]'; + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a single namespace + * @param $ns String namespace name + * @param array $directives array of directives to values + * @return string + */ + protected function renderNamespace($ns, $directives) + { + $ret = ''; + $ret .= $this->start('tbody', array('class' => 'namespace')); + $ret .= $this->start('tr'); + $ret .= $this->element('th', $ns, array('colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->end('tbody'); + $ret .= $this->start('tbody'); + foreach ($directives as $directive => $value) { + $ret .= $this->start('tr'); + $ret .= $this->start('th'); + if ($this->docURL) { + $url = str_replace('%s', urlencode("$ns.$directive"), $this->docURL); + $ret .= $this->start('a', array('href' => $url)); + } + $attr = array('for' => "{$this->name}:$ns.$directive"); + + // crop directive name if it's too long + if (!$this->compress || (strlen($directive) < $this->compress)) { + $directive_disp = $directive; + } else { + $directive_disp = substr($directive, 0, $this->compress - 2) . '...'; + $attr['title'] = $directive; + } + + $ret .= $this->element( + 'label', + $directive_disp, + // component printers must create an element with this id + $attr + ); + if ($this->docURL) { + $ret .= $this->end('a'); + } + $ret .= $this->end('th'); + + $ret .= $this->start('td'); + $def = $this->config->def->info["$ns.$directive"]; + if (is_int($def)) { + $allow_null = $def < 0; + $type = abs($def); + } else { + $type = $def->type; + $allow_null = isset($def->allow_null); + } + if (!isset($this->fields[$type])) { + $type = 0; + } // default + $type_obj = $this->fields[$type]; + if ($allow_null) { + $type_obj = new HTMLPurifier_Printer_ConfigForm_NullDecorator($type_obj); + } + $ret .= $type_obj->render($ns, $directive, $value, $this->name, array($this->genConfig, $this->config)); + $ret .= $this->end('td'); + $ret .= $this->end('tr'); + } + $ret .= $this->end('tbody'); + return $ret; + } + +} + +/** + * Printer decorator for directives that accept null + */ +class HTMLPurifier_Printer_ConfigForm_NullDecorator extends HTMLPurifier_Printer +{ + /** + * Printer being decorated + * @type HTMLPurifier_Printer + */ + protected $obj; + + /** + * @param HTMLPurifier_Printer $obj Printer to decorate + */ + public function __construct($obj) + { + parent::__construct(); + $this->obj = $obj; + } + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + + $ret = ''; + $ret .= $this->start('label', array('for' => "$name:Null_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Null/Disabled'); + $ret .= $this->end('label'); + $attr = array( + 'type' => 'checkbox', + 'value' => '1', + 'class' => 'null-toggle', + 'name' => "$name" . "[Null_$ns.$directive]", + 'id' => "$name:Null_$ns.$directive", + 'onclick' => "toggleWriteability('$name:$ns.$directive',checked)" // INLINE JAVASCRIPT!!!! + ); + if ($this->obj instanceof HTMLPurifier_Printer_ConfigForm_bool) { + // modify inline javascript slightly + $attr['onclick'] = + "toggleWriteability('$name:Yes_$ns.$directive',checked);" . + "toggleWriteability('$name:No_$ns.$directive',checked)"; + } + if ($value === null) { + $attr['checked'] = 'checked'; + } + $ret .= $this->elementEmpty('input', $attr); + $ret .= $this->text(' or '); + $ret .= $this->elementEmpty('br'); + $ret .= $this->obj->render($ns, $directive, $value, $name, array($gen_config, $config)); + return $ret; + } +} + +/** + * Swiss-army knife configuration form field printer + */ +class HTMLPurifier_Printer_ConfigForm_default extends HTMLPurifier_Printer +{ + /** + * @type int + */ + public $cols = 18; + + /** + * @type int + */ + public $rows = 5; + + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + // this should probably be split up a little + $ret = ''; + $def = $config->def->info["$ns.$directive"]; + if (is_int($def)) { + $type = abs($def); + } else { + $type = $def->type; + } + if (is_array($value)) { + switch ($type) { + case HTMLPurifier_VarParser::LOOKUP: + $array = $value; + $value = array(); + foreach ($array as $val => $b) { + $value[] = $val; + } + //TODO does this need a break? + case HTMLPurifier_VarParser::ALIST: + $value = implode(PHP_EOL, $value); + break; + case HTMLPurifier_VarParser::HASH: + $nvalue = ''; + foreach ($value as $i => $v) { + if (is_array($v)) { + // HACK + $v = implode(";", $v); + } + $nvalue .= "$i:$v" . PHP_EOL; + } + $value = $nvalue; + break; + default: + $value = ''; + } + } + if ($type === HTMLPurifier_VarParser::MIXED) { + return 'Not supported'; + $value = serialize($value); + } + $attr = array( + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:$ns.$directive" + ); + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + if (isset($def->allowed)) { + $ret .= $this->start('select', $attr); + foreach ($def->allowed as $val => $b) { + $attr = array(); + if ($value == $val) { + $attr['selected'] = 'selected'; + } + $ret .= $this->element('option', $val, $attr); + } + $ret .= $this->end('select'); + } elseif ($type === HTMLPurifier_VarParser::TEXT || + $type === HTMLPurifier_VarParser::ITEXT || + $type === HTMLPurifier_VarParser::ALIST || + $type === HTMLPurifier_VarParser::HASH || + $type === HTMLPurifier_VarParser::LOOKUP) { + $attr['cols'] = $this->cols; + $attr['rows'] = $this->rows; + $ret .= $this->start('textarea', $attr); + $ret .= $this->text($value); + $ret .= $this->end('textarea'); + } else { + $attr['value'] = $value; + $attr['type'] = 'text'; + $ret .= $this->elementEmpty('input', $attr); + } + return $ret; + } +} + +/** + * Bool form field printer + */ +class HTMLPurifier_Printer_ConfigForm_bool extends HTMLPurifier_Printer +{ + /** + * @param string $ns + * @param string $directive + * @param string $value + * @param string $name + * @param HTMLPurifier_Config|array $config + * @return string + */ + public function render($ns, $directive, $value, $name, $config) + { + if (is_array($config) && isset($config[0])) { + $gen_config = $config[0]; + $config = $config[1]; + } else { + $gen_config = $config; + } + $this->prepareGenerator($gen_config); + $ret = ''; + $ret .= $this->start('div', array('id' => "$name:$ns.$directive")); + + $ret .= $this->start('label', array('for' => "$name:Yes_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' Yes'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:Yes_$ns.$directive", + 'value' => '1' + ); + if ($value === true) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->start('label', array('for' => "$name:No_$ns.$directive")); + $ret .= $this->element('span', "$ns.$directive:", array('class' => 'verbose')); + $ret .= $this->text(' No'); + $ret .= $this->end('label'); + + $attr = array( + 'type' => 'radio', + 'name' => "$name" . "[$ns.$directive]", + 'id' => "$name:No_$ns.$directive", + 'value' => '0' + ); + if ($value === false) { + $attr['checked'] = 'checked'; + } + if ($value === null) { + $attr['disabled'] = 'disabled'; + } + $ret .= $this->elementEmpty('input', $attr); + + $ret .= $this->end('div'); + + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/HTMLDefinition.php b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/HTMLDefinition.php new file mode 100644 index 0000000..5f2f2f8 --- /dev/null +++ b/AvocadoEdition/plugin/htmlpurifier/standalone/HTMLPurifier/Printer/HTMLDefinition.php @@ -0,0 +1,324 @@ +config =& $config; + + $this->def = $config->getHTMLDefinition(); + + $ret .= $this->start('div', array('class' => 'HTMLPurifier_Printer')); + + $ret .= $this->renderDoctype(); + $ret .= $this->renderEnvironment(); + $ret .= $this->renderContentSets(); + $ret .= $this->renderInfo(); + + $ret .= $this->end('div'); + + return $ret; + } + + /** + * Renders the Doctype table + * @return string + */ + protected function renderDoctype() + { + $doctype = $this->def->doctype; + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Doctype'); + $ret .= $this->row('Name', $doctype->name); + $ret .= $this->row('XML', $doctype->xml ? 'Yes' : 'No'); + $ret .= $this->row('Default Modules', implode($doctype->modules, ', ')); + $ret .= $this->row('Default Tidy Modules', implode($doctype->tidyModules, ', ')); + $ret .= $this->end('table'); + return $ret; + } + + + /** + * Renders environment table, which is miscellaneous info + * @return string + */ + protected function renderEnvironment() + { + $def = $this->def; + + $ret = ''; + + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Environment'); + + $ret .= $this->row('Parent of fragment', $def->info_parent); + $ret .= $this->renderChildren($def->info_parent_def->child); + $ret .= $this->row('Block wrap name', $def->info_block_wrapper); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Global attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->info_global_attr), null, 0); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Tag transforms'); + $list = array(); + foreach ($def->info_tag_transform as $old => $new) { + $new = $this->getClass($new, 'TagTransform_'); + $list[] = "<$old> with $new"; + } + $ret .= $this->element('td', $this->listify($list)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_pre)); + $ret .= $this->end('tr'); + + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->info_attr_transform_post)); + $ret .= $this->end('tr'); + + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Content Sets table + * @return string + */ + protected function renderContentSets() + { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Content Sets'); + foreach ($this->def->info_content_sets as $name => $lookup) { + $ret .= $this->heavyHeader($name); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($lookup)); + $ret .= $this->end('tr'); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders the Elements ($info) table + * @return string + */ + protected function renderInfo() + { + $ret = ''; + $ret .= $this->start('table'); + $ret .= $this->element('caption', 'Elements ($info)'); + ksort($this->def->info); + $ret .= $this->heavyHeader('Allowed tags', 2); + $ret .= $this->start('tr'); + $ret .= $this->element('td', $this->listifyTagLookup($this->def->info), array('colspan' => 2)); + $ret .= $this->end('tr'); + foreach ($this->def->info as $name => $def) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', "<$name>", array('class' => 'heavy', 'colspan' => 2)); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Inline content'); + $ret .= $this->element('td', $def->descendants_are_inline ? 'Yes' : 'No'); + $ret .= $this->end('tr'); + if (!empty($def->excludes)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Excludes'); + $ret .= $this->element('td', $this->listifyTagLookup($def->excludes)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_pre)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Pre-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_pre)); + $ret .= $this->end('tr'); + } + if (!empty($def->attr_transform_post)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Post-AttrTransform'); + $ret .= $this->element('td', $this->listifyObjectList($def->attr_transform_post)); + $ret .= $this->end('tr'); + } + if (!empty($def->auto_close)) { + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Auto closed by'); + $ret .= $this->element('td', $this->listifyTagLookup($def->auto_close)); + $ret .= $this->end('tr'); + } + $ret .= $this->start('tr'); + $ret .= $this->element('th', 'Allowed attributes'); + $ret .= $this->element('td', $this->listifyAttr($def->attr), array(), 0); + $ret .= $this->end('tr'); + + if (!empty($def->required_attr)) { + $ret .= $this->row('Required attributes', $this->listify($def->required_attr)); + } + + $ret .= $this->renderChildren($def->child); + } + $ret .= $this->end('table'); + return $ret; + } + + /** + * Renders a row describing the allowed children of an element + * @param HTMLPurifier_ChildDef $def HTMLPurifier_ChildDef of pertinent element + * @return string + */ + protected function renderChildren($def) + { + $context = new HTMLPurifier_Context(); + $ret = ''; + $ret .= $this->start('tr'); + $elements = array(); + $attr = array(); + if (isset($def->elements)) { + if ($def->type == 'strictblockquote') { + $def->validateChildren(array(), $this->config, $context); + } + $elements = $def->elements; + } + if ($def->type == 'chameleon') { + $attr['rowspan'] = 2; + } elseif ($def->type == 'empty') { + $elements = array(); + } elseif ($def->type == 'table') { + $elements = array_flip( + array( + 'col', + 'caption', + 'colgroup', + 'thead', + 'tfoot', + 'tbody', + 'tr' + ) + ); + } + $ret .= $this->element('th', 'Allowed children', $attr); + + if ($def->type == 'chameleon') { + + $ret .= $this->element( + 'td', + 'Block: ' . + $this->escape($this->listifyTagLookup($def->block->elements)), + null, + 0 + ); + $ret .= $this->end('tr'); + $ret .= $this->start('tr'); + $ret .= $this->element( + 'td', + 'Inline: ' . + $this->escape($this->listifyTagLookup($def->inline->elements)), + null, + 0 + ); + + } elseif ($def->type == 'custom') { + + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $def->dtd_regex + ); + + } else { + $ret .= $this->element( + 'td', + '' . ucfirst($def->type) . ': ' . + $this->escape($this->listifyTagLookup($elements)), + null, + 0 + ); + } + $ret .= $this->end('tr'); + return $ret; + } + + /** + * Listifies a tag lookup table. + * @param array $array Tag lookup array in form of array('tagname' => true) + * @return string + */ + protected function listifyTagLookup($array) + { + ksort($array); + $list = array(); + foreach ($array as $name => $discard) { + if ($name !== '#PCDATA' && !isset($this->def->info[$name])) { + continue; + } + $list[] = $name; + } + return $this->listify($list); + } + + /** + * Listifies a list of objects by retrieving class names and internal state + * @param array $array List of objects + * @return string + * @todo Also add information about internal state + */ + protected function listifyObjectList($array) + { + ksort($array); + $list = array(); + foreach ($array as $obj) { + $list[] = $this->getClass($obj, 'AttrTransform_'); + } + return $this->listify($list); + } + + /** + * Listifies a hash of attributes to AttrDef classes + * @param array $array Array hash in form of array('attrname' => HTMLPurifier_AttrDef) + * @return string + */ + protected function listifyAttr($array) + { + ksort($array); + $list = array(); + foreach ($array as $name => $obj) { + if ($obj === false) { + continue; + } + $list[] = "$name = " . $this->getClass($obj, 'AttrDef_') . ''; + } + return $this->listify($list); + } + + /** + * Creates a heavy header row + * @param string $text + * @param int $num + * @return string + */ + protected function heavyHeader($text, $num = 1) + { + $ret = ''; + $ret .= $this->start('tr'); + $ret .= $this->element('th', $text, array('colspan' => $num, 'class' => 'heavy')); + $ret .= $this->end('tr'); + return $ret; + } +} + +// vim: et sw=4 sts=4 diff --git a/AvocadoEdition/plugin/jqplot/MIT-LICENSE.txt b/AvocadoEdition/plugin/jqplot/MIT-LICENSE.txt new file mode 100644 index 0000000..f8111b9 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +Title: MIT License + +Copyright (c) 2009-2013 Chris Leonello + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/excanvas.js b/AvocadoEdition/plugin/jqplot/excanvas.js new file mode 100644 index 0000000..4ca9653 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/excanvas.js @@ -0,0 +1,1438 @@ +// Memory Leaks patch from http://explorercanvas.googlecode.com/svn/trunk/ +// svn : r73 +// ------------------------------------------------------------------ +// 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 only support repeat. +// * 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) +// * Non uniform scaling does not correctly scale strokes. +// * Optimize. There is always room for speed improvements. + +// Only add this code if we do not already have a canvas implementation +if (!document.createElement('canvas').getContext) { + +(function() { + + // alias some functions to make (compiled) code shorter + var m = Math; + var mr = m.round; + var ms = m.sin; + var mc = m.cos; + var abs = m.abs; + var sqrt = m.sqrt; + + // this is used for sub pixel precision + var Z = 10; + var Z2 = Z / 2; + + var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; + + /** + * This funtion is assigned to the elements as element.getContext(). + * @this {HTMLElement} + * @return {CanvasRenderingContext2D_} + */ + function getContext() { + return this.context_ || + (this.context_ = new CanvasRenderingContext2D_(this)); + } + + var slice = Array.prototype.slice; + + /** + * Binds a function to an object. The returned function will always use the + * passed in {@code obj} as {@code this}. + * + * Example: + * + * g = bind(f, obj, a, b) + * g(c, d) // will do f.call(obj, a, b, c, d) + * + * @param {Function} f The function to bind the object to + * @param {Object} obj The object that should act as this when the function + * is called + * @param {*} var_args Rest arguments that will be used as the initial + * arguments when the function is called + * @return {Function} A new function that has bound this + */ + function bind(f, obj, var_args) { + var a = slice.call(arguments, 2); + return function() { + return f.apply(obj, a.concat(slice.call(arguments))); + }; + } + + function encodeHtmlAttribute(s) { + return String(s).replace(/&/g, '&').replace(/"/g, '"'); + } + + function addNamespace(doc, prefix, urn) { + if (!doc.namespaces[prefix]) { + doc.namespaces.add(prefix, urn, '#default#VML'); + } + } + + function addNamespacesAndStylesheet(doc) { + addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); + addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); + + // Setup default CSS. Only add one style sheet per document + if (!doc.styleSheets['ex_canvas_']) { + var ss = doc.createStyleSheet(); + ss.owningElement.id = 'ex_canvas_'; + ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + + // default size is 300x150 in Gecko and Opera + 'text-align:left;width:300px;height:150px}'; + } + } + + // Add namespaces and stylesheet at startup. + addNamespacesAndStylesheet(document); + + var G_vmlCanvasManager_ = { + init: function(opt_doc) { + var doc = opt_doc || document; + // Create a dummy element so that IE will allow canvas elements to be + // recognized. + doc.createElement('canvas'); + doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); + }, + + init_: function(doc) { + // find all canvas elements + var els = doc.getElementsByTagName('canvas'); + for (var i = 0; i < els.length; i++) { + this.initElement(els[i]); + } + }, + + /** + * 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) { + if (!el.getContext) { + el.getContext = getContext; + + // Add namespaces and stylesheet to document of the element. + addNamespacesAndStylesheet(el.ownerDocument); + + // Remove fallback content. There is no way to hide text nodes so we + // just remove all childNodes. We could hide all elements and remove + // text nodes but who really cares about the fallback content. + el.innerHTML = ''; + + // 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; + }, + + // Memory Leaks patch : see http://code.google.com/p/explorercanvas/issues/detail?id=82 + uninitElement: function(el){ + if (el.getContext) { + var ctx = el.getContext(); + delete ctx.element_; + delete ctx.canvas; + el.innerHTML = ""; + //el.outerHTML = ""; + el.context_ = null; + el.getContext = null; + el.detachEvent("onpropertychange", onPropertyChange); + el.detachEvent("onresize", onResize); + } + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.getContext().clearRect(); + el.style.width = el.attributes.width.nodeValue + 'px'; + // In IE8 this does not trigger onresize. + el.firstChild.style.width = el.clientWidth + 'px'; + break; + case 'height': + el.getContext().clearRect(); + el.style.height = el.attributes.height.nodeValue + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + 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 decToHex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + decToHex[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.globalAlpha = o1.globalAlpha; + o2.font = o1.font; + o2.textAlign = o1.textAlign; + o2.textBaseline = o1.textBaseline; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + o2.lineScale_ = o1.lineScale_; + } + + var colorData = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000000', + blanchedalmond: '#FFEBCD', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#00FFFF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgreen: '#006400', + darkgrey: '#A9A9A9', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + grey: '#808080', + greenyellow: '#ADFF2F', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgreen: '#90EE90', + lightgrey: '#D3D3D3', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#FF00FF', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + oldlace: '#FDF5E6', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + whitesmoke: '#F5F5F5', + yellowgreen: '#9ACD32' + }; + + + function getRgbHslContent(styleString) { + var start = styleString.indexOf('(', 3); + var end = styleString.indexOf(')', start + 1); + var parts = styleString.substring(start + 1, end).split(','); + // add alpha if needed + if (parts.length != 4 || styleString.charAt(3) != 'a') { + parts[3] = 1; + } + return parts; + } + + function percent(s) { + return parseFloat(s) / 100; + } + + function clamp(v, min, max) { + return Math.min(max, Math.max(min, v)); + } + + function hslToRgb(parts){ + var r, g, b, h, s, l; + h = parseFloat(parts[0]) / 360 % 360; + if (h < 0) + h++; + s = clamp(percent(parts[1]), 0, 1); + l = clamp(percent(parts[2]), 0, 1); + if (s == 0) { + r = g = b = l; // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hueToRgb(p, q, h + 1 / 3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1 / 3); + } + + return '#' + decToHex[Math.floor(r * 255)] + + decToHex[Math.floor(g * 255)] + + decToHex[Math.floor(b * 255)]; + } + + function hueToRgb(m1, m2, h) { + if (h < 0) + h++; + if (h > 1) + h--; + + if (6 * h < 1) + return m1 + (m2 - m1) * 6 * h; + else if (2 * h < 1) + return m2; + else if (3 * h < 2) + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + else + return m1; + } + + var processStyleCache = {}; + + function processStyle(styleString) { + if (styleString in processStyleCache) { + return processStyleCache[styleString]; + } + + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.charAt(0) == '#') { + str = styleString; + } else if (/^rgb/.test(styleString)) { + var parts = getRgbHslContent(styleString); + var str = '#', n; + for (var i = 0; i < 3; i++) { + if (parts[i].indexOf('%') != -1) { + n = Math.floor(percent(parts[i]) * 255); + } else { + n = +parts[i]; + } + str += decToHex[clamp(n, 0, 255)]; + } + alpha = +parts[3]; + } else if (/^hsl/.test(styleString)) { + var parts = getRgbHslContent(styleString); + str = hslToRgb(parts); + alpha = parts[3]; + } else { + str = colorData[styleString] || styleString; + } + return processStyleCache[styleString] = {color: str, alpha: alpha}; + } + + var DEFAULT_STYLE = { + style: 'normal', + variant: 'normal', + weight: 'normal', + size: 10, + family: 'sans-serif' + }; + + // Internal text style cache + var fontStyleCache = {}; + + function processFontStyle(styleString) { + if (fontStyleCache[styleString]) { + return fontStyleCache[styleString]; + } + + var el = document.createElement('div'); + var style = el.style; + try { + style.font = styleString; + } catch (ex) { + // Ignore failures to set to invalid font. + } + + return fontStyleCache[styleString] = { + style: style.fontStyle || DEFAULT_STYLE.style, + variant: style.fontVariant || DEFAULT_STYLE.variant, + weight: style.fontWeight || DEFAULT_STYLE.weight, + size: style.fontSize || DEFAULT_STYLE.size, + family: style.fontFamily || DEFAULT_STYLE.family + }; + } + + function getComputedStyle(style, element) { + var computedStyle = {}; + + for (var p in style) { + computedStyle[p] = style[p]; + } + + // Compute the size + var canvasFontSize = parseFloat(element.currentStyle.fontSize), + fontSize = parseFloat(style.size); + + if (typeof style.size == 'number') { + computedStyle.size = style.size; + } else if (style.size.indexOf('px') != -1) { + computedStyle.size = fontSize; + } else if (style.size.indexOf('em') != -1) { + computedStyle.size = canvasFontSize * fontSize; + } else if(style.size.indexOf('%') != -1) { + computedStyle.size = (canvasFontSize / 100) * fontSize; + } else if (style.size.indexOf('pt') != -1) { + computedStyle.size = fontSize / .75; + } else { + computedStyle.size = canvasFontSize; + } + + // Different scaling between normal text and VML text. This was found using + // trial and error to get the same size as non VML text. + computedStyle.size *= 0.981; + + // Fix for VML handling of bare font family names. Add a '' around font family names. + computedStyle.family = "'" + computedStyle.family.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'"; + + return computedStyle; + } + + function buildStyle(style) { + return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + + style.size + 'px ' + style.family; + } + + var lineCapMap = { + 'butt': 'flat', + 'round': 'round' + }; + + function processLineCap(lineCap) { + return lineCapMap[lineCap] || 'square'; + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} canvasElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(canvasElement) { + 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.font = '10px sans-serif'; + this.textAlign = 'left'; + this.textBaseline = 'alphabetic'; + this.canvas = canvasElement; + + var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + + canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; + var el = canvasElement.ownerDocument.createElement('div'); + el.style.cssText = cssText; + canvasElement.appendChild(el); + + var overlayEl = el.cloneNode(false); + // Use a non transparent background. + overlayEl.style.backgroundColor = 'red'; + overlayEl.style.filter = 'alpha(opacity=0)'; + canvasElement.appendChild(overlayEl); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + this.lineScale_ = 1; + } + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + if (this.textMeasureEl_) { + this.textMeasureEl_.removeNode(true); + this.textMeasureEl_ = null; + } + this.element_.innerHTML = ''; + }; + + 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) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.lineTo = function(aX, aY) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); + + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + var p = getCoords(this, aX, aY); + var cp1 = getCoords(this, aCP1x, aCP1y); + var cp2 = getCoords(this, aCP2x, aCP2y); + bezierCurveTo(this, cp1, cp2, p); + }; + + // Helper function that takes the already fixed cordinates. + function bezierCurveTo(self, cp1, cp2, p) { + self.currentPath_.push({ + type: 'bezierCurveTo', + cp1x: cp1.x, + cp1y: cp1.y, + cp2x: cp2.x, + cp2y: cp2.y, + x: p.x, + y: p.y + }); + self.currentX_ = p.x; + self.currentY_ = p.y; + } + + 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 cp = getCoords(this, aCPx, aCPy); + var p = getCoords(this, aX, aY); + + var cp1 = { + x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), + y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) + }; + var cp2 = { + x: cp1.x + (p.x - this.currentX_) / 3.0, + y: cp1.y + (p.y - this.currentY_) / 3.0 + }; + + bezierCurveTo(this, cp1, cp2, p); + }; + + 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 + } + + var p = getCoords(this, aX, aY); + var pStart = getCoords(this, xStart, yStart); + var pEnd = getCoords(this, xEnd, yEnd); + + this.currentPath_.push({type: arcType, + x: p.x, + y: p.y, + radius: aRadius, + xStart: pStart.x, + yStart: pStart.y, + xEnd: pEnd.x, + yEnd: pEnd.y}); + + }; + + 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) { + var oldPath = this.currentPath_; + 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(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + 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(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_('gradient'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, aR0, + aX1, aY1, aR1) { + var gradient = new CanvasGradient_('gradientradial'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.r0_ = aR0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + gradient.r1_ = aR1; + 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 Error('Invalid number of arguments'); + } + + var d = getCoords(this, 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(' ' , + '', + ''); + + this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); + }; + + contextPrototype.stroke = function(aFill) { + var lineStr = []; + var lineOpen = false; + + var W = 10; + var H = 10; + + lineStr.push(''); + + if (!aFill) { + appendStroke(this, lineStr); + } else { + appendFill(this, lineStr, min, max); + } + + lineStr.push(''); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + function appendStroke(ctx, lineStr) { + var a = processStyle(ctx.strokeStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + var lineWidth = ctx.lineScale_ * ctx.lineWidth; + + // VML cannot correctly render a line if the width is less than 1px. + // In that case, we dilute the color to make the line look thinner. + if (lineWidth < 1) { + opacity *= lineWidth; + } + + lineStr.push( + '' + ); + } + + function appendFill(ctx, lineStr, min, max) { + var fillStyle = ctx.fillStyle; + var arcScaleX = ctx.arcScaleX_; + var arcScaleY = ctx.arcScaleY_; + var width = max.x - min.x; + var height = max.y - min.y; + if (fillStyle instanceof CanvasGradient_) { + // TODO: Gradients transformed with the transformation matrix. + var angle = 0; + var focus = {x: 0, y: 0}; + + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + + if (fillStyle.type_ == 'gradient') { + var x0 = fillStyle.x0_ / arcScaleX; + var y0 = fillStyle.y0_ / arcScaleY; + var x1 = fillStyle.x1_ / arcScaleX; + var y1 = fillStyle.y1_ / arcScaleY; + var p0 = getCoords(ctx, x0, y0); + var p1 = getCoords(ctx, x1, y1); + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); + focus = { + x: (p0.x - min.x) / width, + y: (p0.y - min.y) / height + }; + + width /= arcScaleX * Z; + height /= arcScaleY * Z; + var dimension = m.max(width, height); + shift = 2 * fillStyle.r0_ / dimension; + expansion = 2 * fillStyle.r1_ / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fillStyle.colors_; + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length = stops.length; + var color1 = stops[0].color; + var color2 = stops[length - 1].color; + var opacity1 = stops[0].alpha * ctx.globalAlpha; + var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; + + var colors = []; + for (var i = 0; i < length; i++) { + var stop = stops[i]; + colors.push(stop.offset * expansion + shift + ' ' + stop.color); + } + + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + lineStr.push(''); + } else if (fillStyle instanceof CanvasPattern_) { + if (width && height) { + var deltaLeft = -min.x; + var deltaTop = -min.y; + lineStr.push(''); + } + } else { + var a = processStyle(ctx.fillStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + lineStr.push(''); + } + } + + contextPrototype.fill = function() { + this.stroke(true); + }; + + contextPrototype.closePath = function() { + this.currentPath_.push({type: 'close'}); + }; + + function getCoords(ctx, aX, aY) { + var m = ctx.m_; + return { + x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, + y: Z * (aX * m[0][1] + aY * m[1][1] + 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() { + if (this.aStack_.length) { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + } + }; + + function matrixIsFinite(m) { + return isFinite(m[0][0]) && isFinite(m[0][1]) && + isFinite(m[1][0]) && isFinite(m[1][1]) && + isFinite(m[2][0]) && isFinite(m[2][1]); + } + + function setM(ctx, m, updateLineScale) { + if (!matrixIsFinite(m)) { + return; + } + ctx.m_ = m; + + if (updateLineScale) { + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + ctx.lineScale_ = sqrt(abs(det)); + } + } + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { + var m1 = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { + var m = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, m, true); + }; + + /** + * The text drawing function. + * The maxWidth argument isn't taken in account, since no browser supports + * it yet. + */ + contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { + var m = this.m_, + delta = 1000, + left = 0, + right = delta, + offset = {x: 0, y: 0}, + lineStr = []; + + var fontStyle = getComputedStyle(processFontStyle(this.font), this.element_); + + var fontStyleString = buildStyle(fontStyle); + + var elementStyle = this.element_.currentStyle; + var textAlign = this.textAlign.toLowerCase(); + switch (textAlign) { + case 'left': + case 'center': + case 'right': + break; + case 'end': + textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; + break; + case 'start': + textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; + break; + default: + textAlign = 'left'; + } + + // 1.75 is an arbitrary number, as there is no info about the text baseline + switch (this.textBaseline) { + case 'hanging': + case 'top': + offset.y = fontStyle.size / 1.75; + break; + case 'middle': + break; + default: + case null: + case 'alphabetic': + case 'ideographic': + case 'bottom': + offset.y = -fontStyle.size / 2.25; + break; + } + + switch(textAlign) { + case 'right': + left = delta; + right = 0.05; + break; + case 'center': + left = right = delta / 2; + break; + } + + var d = getCoords(this, x + offset.x, y + offset.y); + + lineStr.push(''); + + if (stroke) { + appendStroke(this, lineStr); + } else { + // TODO: Fix the min and max params. + appendFill(this, lineStr, {x: -left, y: 0}, + {x: right, y: fontStyle.size}); + } + + var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + + m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; + + var skewOffset = mr(d.x / Z + 1 - m[0][0]) + ',' + mr(d.y / Z - 2 * m[1][0]); + + + lineStr.push('', + '', + ''); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + contextPrototype.fillText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, false); + }; + + contextPrototype.strokeText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, true); + }; + + contextPrototype.measureText = function(text) { + if (!this.textMeasureEl_) { + var s = ''; + this.element_.insertAdjacentHTML('beforeEnd', s); + this.textMeasureEl_ = this.element_.lastChild; + } + var doc = this.element_.ownerDocument; + this.textMeasureEl_.innerHTML = ''; + this.textMeasureEl_.style.font = this.font; + // Don't use innerHTML or innerText because they allow markup/whitespace. + this.textMeasureEl_.appendChild(doc.createTextNode(text)); + return {width: this.textMeasureEl_.offsetWidth}; + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function(image, repetition) { + return new CanvasPattern_(image, repetition); + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.x0_ = 0; + this.y0_ = 0; + this.r0_ = 0; + this.x1_ = 0; + this.y1_ = 0; + this.r1_ = 0; + this.colors_ = []; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: aOffset, + color: aColor.color, + alpha: aColor.alpha}); + }; + + function CanvasPattern_(image, repetition) { + assertImageIsValid(image); + switch (repetition) { + case 'repeat': + case null: + case '': + this.repetition_ = 'repeat'; + break; + case 'repeat-x': + case 'repeat-y': + case 'no-repeat': + this.repetition_ = repetition; + break; + default: + throwException('SYNTAX_ERR'); + } + + this.src_ = image.src; + this.width_ = image.width; + this.height_ = image.height; + } + + function throwException(s) { + throw new DOMException_(s); + } + + function assertImageIsValid(img) { + if (!img || img.nodeType != 1 || img.tagName != 'IMG') { + throwException('TYPE_MISMATCH_ERR'); + } + if (img.readyState != 'complete') { + throwException('INVALID_STATE_ERR'); + } + } + + function DOMException_(s) { + this.code = this[s]; + this.message = s +': DOM Exception ' + this.code; + } + var p = DOMException_.prototype = new Error; + p.INDEX_SIZE_ERR = 1; + p.DOMSTRING_SIZE_ERR = 2; + p.HIERARCHY_REQUEST_ERR = 3; + p.WRONG_DOCUMENT_ERR = 4; + p.INVALID_CHARACTER_ERR = 5; + p.NO_DATA_ALLOWED_ERR = 6; + p.NO_MODIFICATION_ALLOWED_ERR = 7; + p.NOT_FOUND_ERR = 8; + p.NOT_SUPPORTED_ERR = 9; + p.INUSE_ATTRIBUTE_ERR = 10; + p.INVALID_STATE_ERR = 11; + p.SYNTAX_ERR = 12; + p.INVALID_MODIFICATION_ERR = 13; + p.NAMESPACE_ERR = 14; + p.INVALID_ACCESS_ERR = 15; + p.VALIDATION_ERR = 16; + p.TYPE_MISMATCH_ERR = 17; + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + DOMException = DOMException_; + G_vmlCanvasManager._version = 888; +})(); + +} // if diff --git a/AvocadoEdition/plugin/jqplot/excanvas.min.js b/AvocadoEdition/plugin/jqplot/excanvas.min.js new file mode 100644 index 0000000..e699a26 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/excanvas.min.js @@ -0,0 +1,3 @@ +/* jqPlot @VERSION | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;i.family="'"+i.family.replace(/(\'|\")/g,"").replace(/\s*,\s*/g,"', '")+"'";return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(al){var aj=[];var Z=false;var m=10;var am=10;aj.push("ak.x){ak.x=j.x}if(ag.y==null||j.yak.y){ak.y=j.y}}}aj.push(' ">');if(!al){w(this,aj)}else{G(this,aj,ag,ak)}aj.push("");this.element_.insertAdjacentHTML("beforeEnd",aj.join(""))};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d+1-ao[0][0])+","+n(aq.y/d-2*ao[1][0]);ag.push('','','');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P;G_vmlCanvasManager._version=888})()}; \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/jqplot.barRenderer.min.js b/AvocadoEdition/plugin/jqplot/jqplot.barRenderer.min.js new file mode 100644 index 0000000..6f95500 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jqplot.barRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horizontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I0&&I=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I0&&I=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][0]<0)||(this.waterfall&&this._data[I][0]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;Ib.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x0&&o
  • ');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e
    ');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;ce){e=m}}}var j=0;for(var c=0;cj){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/jqplot.pointLabels.min.js b/AvocadoEdition/plugin/jqplot/jqplot.pointLabels.min.js new file mode 100644 index 0000000..54810c1 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jqplot.pointLabels.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var b=["se","s","sw","w","nw","n","ne","e"];c.jqplot.PointLabels.init=function(j,h,f,g,i){var e=c.extend(true,{},f,g);e.pointLabels=e.pointLabels||{};if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"&&!e.pointLabels.location){e.pointLabels.location="e"}this.plugins.pointLabels=new c.jqplot.PointLabels(e.pointLabels);this.plugins.pointLabels.setLabels.call(this)};c.jqplot.PointLabels.prototype.setLabels=function(){var f=this.plugins.pointLabels;var h;if(f.seriesLabelIndex!=null){h=f.seriesLabelIndex}else{if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"){h=(this._plotData[0].length<3)?0:this._plotData[0].length-1}else{h=(this._plotData.length===0)?0:this._plotData[0].length-1}}f._labels=[];if(f.labels.length===0||f.labelsFromSeries){if(f.stackedValue){if(this._plotData.length&&this._plotData[0].length){for(var e=0;eB||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/jquery.jqplot.css b/AvocadoEdition/plugin/jqplot/jquery.jqplot.css new file mode 100644 index 0000000..db42245 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jquery.jqplot.css @@ -0,0 +1,261 @@ +/*rules for the plot target div. These will be cascaded down to all plot elements according to css rules*/ +.jqplot-target { + position: relative; + color: #666666; + font-family: "Trebuchet MS", Arial, Helvetica, sans-serif; + font-size: 1em; +/* height: 300px; + width: 400px;*/ +} + +/*rules applied to all axes*/ +.jqplot-axis { + font-size: 0.9em; +} + +.jqplot-xaxis { + margin-top: 10px; +} + +.jqplot-x2axis { + margin-bottom: 10px; +} + +.jqplot-yaxis { + margin-right: 10px; +} + +.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis, .jqplot-yMidAxis { + margin-left: 10px; + margin-right: 10px; +} + +/*rules applied to all axis tick divs*/ +.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick, .jqplot-yMidAxis-tick { + position: absolute; + white-space: pre; +} + + +.jqplot-xaxis-tick { + top: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-top: 10px;*/ + vertical-align: top; +} + +.jqplot-x2axis-tick { + bottom: 0px; + /* initial position untill tick is drawn in proper place */ + left: 15px; +/* padding-bottom: 10px;*/ + vertical-align: bottom; +} + +.jqplot-yaxis-tick { + right: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-right: 10px;*/ + text-align: right; +} + +.jqplot-yaxis-tick.jqplot-breakTick { + right: -20px; + margin-right: 0px; + padding:1px 5px 1px 5px; + /*background-color: white;*/ + z-index: 2; + font-size: 1.5em; +} + +.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick { + left: 0px; + /* initial position untill tick is drawn in proper place */ + top: 15px; +/* padding-left: 10px;*/ +/* padding-right: 15px;*/ + text-align: left; +} + +.jqplot-yMidAxis-tick { + text-align: center; + white-space: nowrap; +} + +.jqplot-xaxis-label { + margin-top: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-x2axis-label { + margin-bottom: 10px; + font-size: 11pt; + position: absolute; +} + +.jqplot-yaxis-label { + margin-right: 10px; +/* text-align: center;*/ + font-size: 11pt; + position: absolute; +} + +.jqplot-yMidAxis-label { + font-size: 11pt; + position: absolute; +} + +.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label { +/* text-align: center;*/ + font-size: 11pt; + margin-left: 10px; + position: absolute; +} + +.jqplot-meterGauge-tick { + font-size: 0.75em; + color: #999999; +} + +.jqplot-meterGauge-label { + font-size: 1em; + color: #999999; +} + +table.jqplot-table-legend { + margin-top: 12px; + margin-bottom: 12px; + margin-left: 12px; + margin-right: 12px; +} + +table.jqplot-table-legend, table.jqplot-cursor-legend { + background-color: rgba(255,255,255,0.6); + border: 1px solid #cccccc; + position: absolute; + font-size: 0.75em; +} + +td.jqplot-table-legend { + vertical-align:middle; +} + +/* +These rules could be used instead of assigning +element styles and relying on js object properties. +*/ + +/* +td.jqplot-table-legend-swatch { + padding-top: 0.5em; + text-align: center; +} + +tr.jqplot-table-legend:first td.jqplot-table-legend-swatch { + padding-top: 0px; +} +*/ + +td.jqplot-seriesToggle:hover, td.jqplot-seriesToggle:active { + cursor: pointer; +} + +.jqplot-table-legend .jqplot-series-hidden { + text-decoration: line-through; +} + +div.jqplot-table-legend-swatch-outline { + border: 1px solid #cccccc; + padding:1px; +} + +div.jqplot-table-legend-swatch { + width:0px; + height:0px; + border-top-width: 5px; + border-bottom-width: 5px; + border-left-width: 6px; + border-right-width: 6px; + border-top-style: solid; + border-bottom-style: solid; + border-left-style: solid; + border-right-style: solid; +} + +.jqplot-title { + top: 0px; + left: 0px; + padding-bottom: 0.5em; + font-size: 1.2em; +} + +table.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; +} + + +.jqplot-cursor-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-highlighter-tooltip, .jqplot-canvasOverlay-tooltip { + border: 1px solid #cccccc; + font-size: 0.75em; + white-space: nowrap; + background: rgba(208,208,208,0.5); + padding: 1px; +} + +.jqplot-point-label { + font-size: 1em; + z-index: 2; + font-weight:bold; + color:#ff670f; +} + +td.jqplot-cursor-legend-swatch { + vertical-align: middle; + text-align: center; +} + +div.jqplot-cursor-legend-swatch { + width: 1.2em; + height: 0.7em; +} + +.jqplot-error { +/* Styles added to the plot target container when there is an error go here.*/ + text-align: center; +} + +.jqplot-error-message { +/* Styling of the custom error message div goes here.*/ + position: relative; + top: 46%; + display: inline-block; +} + +div.jqplot-bubble-label { + font-size: 0.8em; +/* background: rgba(90%, 90%, 90%, 0.15);*/ + padding-left: 2px; + padding-right: 2px; + color: rgb(20%, 20%, 20%); +} + +div.jqplot-bubble-label.jqplot-bubble-label-highlight { + background: rgba(90%, 90%, 90%, 0.7); +} + +div.jqplot-noData-container { + text-align: center; + background-color: rgba(96%, 96%, 96%, 0.3); +} diff --git a/AvocadoEdition/plugin/jqplot/jquery.jqplot.js b/AvocadoEdition/plugin/jqplot/jquery.jqplot.js new file mode 100644 index 0000000..49812b7 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jquery.jqplot.js @@ -0,0 +1,11411 @@ +/** + * Title: jqPlot Charts + * + * Pure JavaScript plotting plugin for jQuery. + * + * About: Version + * + * version: 1.0.8 + * revision: 1250 + * + * About: Copyright & License + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * See and contained within this distribution for further information. + * + * The author would appreciate an email letting him know of any substantial + * use of jqPlot. You can reach the author at: chris at jqplot dot com + * or see http://www.jqplot.com/info.php. This is, of course, not required. + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php. + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + * + * About: Introduction + * + * jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.2 is included in the distribution. + * To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and optionally + * the excanvas script for IE support in your web page: + * + * > + * > + * > + * > + * + * jqPlot can be customized by overriding the defaults of any of the objects which make + * up the plot. The general usage of jqplot is: + * + * > chart = $.jqplot('targetElemId', [dataArray,...], {optionsObject}); + * + * The options available to jqplot are detailed in in the jqPlotOptions.txt file. + * + * An actual call to $.jqplot() may look like the + * examples below: + * + * > chart = $.jqplot('chartdiv', [[[1, 2],[3,5.12],[5,13.1],[7,33.6],[9,85.9],[11,219.9]]]); + * + * or + * + * > dataArray = [34,12,43,55,77]; + * > chart = $.jqplot('targetElemId', [dataArray, ...], {title:'My Plot', axes:{yaxis:{min:20, max:100}}}); + * + * For more inforrmation, see . + * + * About: Usage + * + * See + * + * About: Available Options + * + * See for a list of options available thorugh the options object (not complete yet!) + * + * About: Options Usage + * + * See + * + * About: Changes + * + * See + * + */ + +(function($) { + // make sure undefined is undefined + var undefined; + + $.fn.emptyForce = function() { + for ( var i = 0, elem; (elem = $(this)[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + $.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + if ($.jqplot.use_excanvas) { + elem.outerHTML = ""; + } + else { + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + elem = null; + } + + return $(this); + }; + + $.fn.removeChildForce = function(parent) { + while ( parent.firstChild ) { + this.removeChildForce( parent.firstChild ); + parent.removeChild( parent.firstChild ); + } + }; + + $.fn.jqplot = function() { + var datas = []; + var options = []; + // see how many data arrays we have + for (var i=0, l=arguments.length; i'+msg+'
    '); + $('#'+target).addClass('jqplot-error'); + document.getElementById(target).style.background = $.jqplot.config.errorBackground; + document.getElementById(target).style.border = $.jqplot.config.errorBorder; + document.getElementById(target).style.fontFamily = $.jqplot.config.errorFontFamily; + document.getElementById(target).style.fontSize = $.jqplot.config.errorFontSize; + document.getElementById(target).style.fontStyle = $.jqplot.config.errorFontStyle; + document.getElementById(target).style.fontWeight = $.jqplot.config.errorFontWeight; + } + } + else { + plot.init(target, _data, _options); + plot.draw(); + plot.themeEngine.init.call(plot); + return plot; + } + }; + + $.jqplot.version = "1.0.8"; + $.jqplot.revision = "1250"; + + $.jqplot.targetCounter = 1; + + // canvas manager to reuse canvases on the plot. + // Should help solve problem of canvases not being freed and + // problem of waiting forever for firefox to decide to free memory. + $.jqplot.CanvasManager = function() { + // canvases are managed globally so that they can be reused + // across plots after they have been freed + if (typeof $.jqplot.CanvasManager.canvases == 'undefined') { + $.jqplot.CanvasManager.canvases = []; + $.jqplot.CanvasManager.free = []; + } + + var myCanvases = []; + + this.getCanvas = function() { + var canvas; + var makeNew = true; + + if (!$.jqplot.use_excanvas) { + for (var i = 0, l = $.jqplot.CanvasManager.canvases.length; i < l; i++) { + if ($.jqplot.CanvasManager.free[i] === true) { + makeNew = false; + canvas = $.jqplot.CanvasManager.canvases[i]; + // $(canvas).removeClass('jqplot-canvasManager-free').addClass('jqplot-canvasManager-inuse'); + $.jqplot.CanvasManager.free[i] = false; + myCanvases.push(i); + break; + } + } + } + + if (makeNew) { + canvas = document.createElement('canvas'); + myCanvases.push($.jqplot.CanvasManager.canvases.length); + $.jqplot.CanvasManager.canvases.push(canvas); + $.jqplot.CanvasManager.free.push(false); + } + + return canvas; + }; + + // this method has to be used after settings the dimesions + // on the element returned by getCanvas() + this.initCanvas = function(canvas) { + if ($.jqplot.use_excanvas) { + return window.G_vmlCanvasManager.initElement(canvas); + } + return canvas; + }; + + this.freeAllCanvases = function() { + for (var i = 0, l=myCanvases.length; i < l; i++) { + this.freeCanvas(myCanvases[i]); + } + myCanvases = []; + }; + + this.freeCanvas = function(idx) { + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + // excanvas can't be reused, but properly unset + window.G_vmlCanvasManager.uninitElement($.jqplot.CanvasManager.canvases[idx]); + $.jqplot.CanvasManager.canvases[idx] = null; + } + else { + var canvas = $.jqplot.CanvasManager.canvases[idx]; + canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); + $(canvas).unbind().removeAttr('class').removeAttr('style'); + // Style attributes seemed to be still hanging around. wierd. Some ticks + // still retained a left: 0px attribute after reusing a canvas. + $(canvas).css({left: '', top: '', position: ''}); + // setting size to 0 may save memory of unused canvases? + canvas.width = 0; + canvas.height = 0; + $.jqplot.CanvasManager.free[idx] = true; + } + }; + + }; + + + // Convienence function that won't hang IE or FF without FireBug. + $.jqplot.log = function() { + if (window.console) { + window.console.log.apply(window.console, arguments); + } + }; + + $.jqplot.config = { + addDomReference: false, + enablePlugins:false, + defaultHeight:300, + defaultWidth:400, + UTCAdjust:false, + timezoneOffset: new Date(new Date().getTimezoneOffset() * 60000), + errorMessage: '', + errorBackground: '', + errorBorder: '', + errorFontFamily: '', + errorFontSize: '', + errorFontStyle: '', + errorFontWeight: '', + catchErrors: false, + defaultTickFormatString: "%.1f", + defaultColors: [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], + defaultNegativeColors: [ "#498991", "#C08840", "#9F9274", "#546D61", "#646C4A", "#6F6621", "#6E3F5F", "#4F64B0", "#A89050", "#C45923", "#187399", "#945381", "#959E5C", "#C7AF7B", "#478396", "#907294"], + dashLength: 4, + gapLength: 4, + dotGapLength: 2.5, + srcLocation: 'jqplot/src/', + pluginLocation: 'jqplot/src/plugins/' + }; + + + $.jqplot.arrayMax = function( array ){ + return Math.max.apply( Math, array ); + }; + + $.jqplot.arrayMin = function( array ){ + return Math.min.apply( Math, array ); + }; + + $.jqplot.enablePlugins = $.jqplot.config.enablePlugins; + + // canvas related tests taken from modernizer: + // Copyright (c) 2009 - 2010 Faruk Ates. + // http://www.modernizr.com + + $.jqplot.support_canvas = function() { + if (typeof $.jqplot.support_canvas.result == 'undefined') { + $.jqplot.support_canvas.result = !!document.createElement('canvas').getContext; + } + return $.jqplot.support_canvas.result; + }; + + $.jqplot.support_canvas_text = function() { + if (typeof $.jqplot.support_canvas_text.result == 'undefined') { + if (window.G_vmlCanvasManager !== undefined && window.G_vmlCanvasManager._version > 887) { + $.jqplot.support_canvas_text.result = true; + } + else { + $.jqplot.support_canvas_text.result = !!(document.createElement('canvas').getContext && typeof document.createElement('canvas').getContext('2d').fillText == 'function'); + } + + } + return $.jqplot.support_canvas_text.result; + }; + + $.jqplot.use_excanvas = ((!$.support.boxModel || !$.support.objectAll || !$support.leadingWhitespace) && !$.jqplot.support_canvas()) ? true : false; + + /** + * + * Hooks: jqPlot Pugin Hooks + * + * $.jqplot.preInitHooks - called before initialization. + * $.jqplot.postInitHooks - called after initialization. + * $.jqplot.preParseOptionsHooks - called before user options are parsed. + * $.jqplot.postParseOptionsHooks - called after user options are parsed. + * $.jqplot.preDrawHooks - called before plot draw. + * $.jqplot.postDrawHooks - called after plot draw. + * $.jqplot.preDrawSeriesHooks - called before each series is drawn. + * $.jqplot.postDrawSeriesHooks - called after each series is drawn. + * $.jqplot.preDrawLegendHooks - called before the legend is drawn. + * $.jqplot.addLegendRowHooks - called at the end of legend draw, so plugins + * can add rows to the legend table. + * $.jqplot.preSeriesInitHooks - called before series is initialized. + * $.jqplot.postSeriesInitHooks - called after series is initialized. + * $.jqplot.preParseSeriesOptionsHooks - called before series related options + * are parsed. + * $.jqplot.postParseSeriesOptionsHooks - called after series related options + * are parsed. + * $.jqplot.eventListenerHooks - called at the end of plot drawing, binds + * listeners to the event canvas which lays on top of the grid area. + * $.jqplot.preDrawSeriesShadowHooks - called before series shadows are drawn. + * $.jqplot.postDrawSeriesShadowHooks - called after series shadows are drawn. + * + */ + + $.jqplot.preInitHooks = []; + $.jqplot.postInitHooks = []; + $.jqplot.preParseOptionsHooks = []; + $.jqplot.postParseOptionsHooks = []; + $.jqplot.preDrawHooks = []; + $.jqplot.postDrawHooks = []; + $.jqplot.preDrawSeriesHooks = []; + $.jqplot.postDrawSeriesHooks = []; + $.jqplot.preDrawLegendHooks = []; + $.jqplot.addLegendRowHooks = []; + $.jqplot.preSeriesInitHooks = []; + $.jqplot.postSeriesInitHooks = []; + $.jqplot.preParseSeriesOptionsHooks = []; + $.jqplot.postParseSeriesOptionsHooks = []; + $.jqplot.eventListenerHooks = []; + $.jqplot.preDrawSeriesShadowHooks = []; + $.jqplot.postDrawSeriesShadowHooks = []; + + // A superclass holding some common properties and methods. + $.jqplot.ElemContainer = function() { + this._elem; + this._plotWidth; + this._plotHeight; + this._plotDimensions = {height:null, width:null}; + }; + + $.jqplot.ElemContainer.prototype.createElement = function(el, offsets, clss, cssopts, attrib) { + this._offsets = offsets; + var klass = clss || 'jqplot'; + var elem = document.createElement(el); + this._elem = $(elem); + this._elem.addClass(klass); + this._elem.css(cssopts); + this._elem.attr(attrib); + // avoid memory leak; + elem = null; + return this._elem; + }; + + $.jqplot.ElemContainer.prototype.getWidth = function() { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + return null; + } + }; + + $.jqplot.ElemContainer.prototype.getHeight = function() { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + return null; + } + }; + + $.jqplot.ElemContainer.prototype.getPosition = function() { + if (this._elem) { + return this._elem.position(); + } + else { + return {top:null, left:null, bottom:null, right:null}; + } + }; + + $.jqplot.ElemContainer.prototype.getTop = function() { + return this.getPosition().top; + }; + + $.jqplot.ElemContainer.prototype.getLeft = function() { + return this.getPosition().left; + }; + + $.jqplot.ElemContainer.prototype.getBottom = function() { + return this._elem.css('bottom'); + }; + + $.jqplot.ElemContainer.prototype.getRight = function() { + return this._elem.css('right'); + }; + + + /** + * Class: Axis + * An individual axis object. Cannot be instantiated directly, but created + * by the Plot object. Axis properties can be set or overridden by the + * options passed in from the user. + * + */ + function Axis(name) { + $.jqplot.ElemContainer.call(this); + // Group: Properties + // + // Axes options are specified within an axes object at the top level of the + // plot options like so: + // > { + // > axes: { + // > xaxis: {min: 5}, + // > yaxis: {min: 2, max: 8, numberTicks:4}, + // > x2axis: {pad: 1.5}, + // > y2axis: {ticks:[22, 44, 66, 88]} + // > } + // > } + // There are 2 x axes, 'xaxis' and 'x2axis', and + // 9 yaxes, 'yaxis', 'y2axis'. 'y3axis', ... Any or all of which may be specified. + this.name = name; + this._series = []; + // prop: show + // Wether to display the axis on the graph. + this.show = false; + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + this.tickRenderer = $.jqplot.AxisTickRenderer; + // prop: tickOptions + // Options that will be passed to the tickRenderer, see <$.jqplot.AxisTickRenderer> options. + this.tickOptions = {}; + // prop: labelRenderer + // A class of a rendering engine for creating an axis label. + this.labelRenderer = $.jqplot.AxisLabelRenderer; + // prop: labelOptions + // Options passed to the label renderer. + this.labelOptions = {}; + // prop: label + // Label for the axis + this.label = null; + // prop: showLabel + // true to show the axis label. + this.showLabel = true; + // prop: min + // minimum value of the axis (in data units, not pixels). + this.min = null; + // prop: max + // maximum value of the axis (in data units, not pixels). + this.max = null; + // prop: autoscale + // DEPRECATED + // the default scaling algorithm produces superior results. + this.autoscale = false; + // prop: pad + // Padding to extend the range above and below the data bounds. + // The data range is multiplied by this factor to determine minimum and maximum axis bounds. + // A value of 0 will be interpreted to mean no padding, and pad will be set to 1.0. + this.pad = 1.2; + // prop: padMax + // Padding to extend the range above data bounds. + // The top of the data range is multiplied by this factor to determine maximum axis bounds. + // A value of 0 will be interpreted to mean no padding, and padMax will be set to 1.0. + this.padMax = null; + // prop: padMin + // Padding to extend the range below data bounds. + // The bottom of the data range is multiplied by this factor to determine minimum axis bounds. + // A value of 0 will be interpreted to mean no padding, and padMin will be set to 1.0. + this.padMin = null; + // prop: ticks + // 1D [val, val, ...] or 2D [[val, label], [val, label], ...] array of ticks for the axis. + // If no label is specified, the value is formatted into an appropriate label. + this.ticks = []; + // prop: numberTicks + // Desired number of ticks. Default is to compute automatically. + this.numberTicks; + // prop: tickInterval + // number of units between ticks. Mutually exclusive with numberTicks. + this.tickInterval; + // prop: renderer + // A class of a rendering engine that handles tick generation, + // scaling input data to pixel grid units and drawing the axis element. + this.renderer = $.jqplot.LinearAxisRenderer; + // prop: rendererOptions + // renderer specific options. See <$.jqplot.LinearAxisRenderer> for options. + this.rendererOptions = {}; + // prop: showTicks + // Wether to show the ticks (both marks and labels) or not. + // Will not override showMark and showLabel options if specified on the ticks themselves. + this.showTicks = true; + // prop: showTickMarks + // Wether to show the tick marks (line crossing grid) or not. + // Overridden by showTicks and showMark option of tick itself. + this.showTickMarks = true; + // prop: showMinorTicks + // Wether or not to show minor ticks. This is renderer dependent. + this.showMinorTicks = true; + // prop: drawMajorGridlines + // True to draw gridlines for major axis ticks. + this.drawMajorGridlines = true; + // prop: drawMinorGridlines + // True to draw gridlines for minor ticks. + this.drawMinorGridlines = false; + // prop: drawMajorTickMarks + // True to draw tick marks for major axis ticks. + this.drawMajorTickMarks = true; + // prop: drawMinorTickMarks + // True to draw tick marks for minor ticks. This is renderer dependent. + this.drawMinorTickMarks = true; + // prop: useSeriesColor + // Use the color of the first series associated with this axis for the + // tick marks and line bordering this axis. + this.useSeriesColor = false; + // prop: borderWidth + // width of line stroked at the border of the axis. Defaults + // to the width of the grid boarder. + this.borderWidth = null; + // prop: borderColor + // color of the border adjacent to the axis. Defaults to grid border color. + this.borderColor = null; + // prop: scaleToHiddenSeries + // True to include hidden series when computing axes bounds and scaling. + this.scaleToHiddenSeries = false; + // minimum and maximum values on the axis. + this._dataBounds = {min:null, max:null}; + // statistics (min, max, mean) as well as actual data intervals for each series attached to axis. + // holds collection of {intervals:[], min:, max:, mean: } objects for each series on axis. + this._intervalStats = []; + // pixel position from the top left of the min value and max value on the axis. + this._offsets = {min:null, max:null}; + this._ticks=[]; + this._label = null; + // prop: syncTicks + // true to try and synchronize tick spacing across multiple axes so that ticks and + // grid lines line up. This has an impact on autoscaling algorithm, however. + // In general, autoscaling an individual axis will work better if it does not + // have to sync ticks. + this.syncTicks = null; + // prop: tickSpacing + // Approximate pixel spacing between ticks on graph. Used during autoscaling. + // This number will be an upper bound, actual spacing will be less. + this.tickSpacing = 75; + // Properties to hold the original values for min, max, ticks, tickInterval and numberTicks + // so they can be restored if altered by plugins. + this._min = null; + this._max = null; + this._tickInterval = null; + this._numberTicks = null; + this.__ticks = null; + // hold original user options. + this._options = {}; + } + + Axis.prototype = new $.jqplot.ElemContainer(); + Axis.prototype.constructor = Axis; + + Axis.prototype.init = function() { + if ($.isFunction(this.renderer)) { + this.renderer = new this.renderer(); + } + // set the axis name + this.tickOptions.axis = this.name; + // if showMark or showLabel tick options not specified, use value of axis option. + // showTicks overrides showTickMarks. + if (this.tickOptions.showMark == null) { + this.tickOptions.showMark = this.showTicks; + } + if (this.tickOptions.showMark == null) { + this.tickOptions.showMark = this.showTickMarks; + } + if (this.tickOptions.showLabel == null) { + this.tickOptions.showLabel = this.showTicks; + } + + if (this.label == null || this.label == '') { + this.showLabel = false; + } + else { + this.labelOptions.label = this.label; + } + if (this.showLabel == false) { + this.labelOptions.show = false; + } + // set the default padMax, padMin if not specified + // special check, if no padding desired, padding + // should be set to 1.0 + if (this.pad == 0) { + this.pad = 1.0; + } + if (this.padMax == 0) { + this.padMax = 1.0; + } + if (this.padMin == 0) { + this.padMin = 1.0; + } + if (this.padMax == null) { + this.padMax = (this.pad-1)/2 + 1; + } + if (this.padMin == null) { + this.padMin = (this.pad-1)/2 + 1; + } + // now that padMin and padMax are correctly set, reset pad in case user has supplied + // padMin and/or padMax + this.pad = this.padMax + this.padMin - 1; + if (this.min != null || this.max != null) { + this.autoscale = false; + } + // if not set, sync ticks for y axes but not x by default. + if (this.syncTicks == null && this.name.indexOf('y') > -1) { + this.syncTicks = true; + } + else if (this.syncTicks == null){ + this.syncTicks = false; + } + this.renderer.init.call(this, this.rendererOptions); + + }; + + Axis.prototype.draw = function(ctx, plot) { + // Memory Leaks patch + if (this.__ticks) { + this.__ticks = null; + } + + return this.renderer.draw.call(this, ctx, plot); + + }; + + Axis.prototype.set = function() { + this.renderer.set.call(this); + }; + + Axis.prototype.pack = function(pos, offsets) { + if (this.show) { + this.renderer.pack.call(this, pos, offsets); + } + // these properties should all be available now. + if (this._min == null) { + this._min = this.min; + this._max = this.max; + this._tickInterval = this.tickInterval; + this._numberTicks = this.numberTicks; + this.__ticks = this._ticks; + } + }; + + // reset the axis back to original values if it has been scaled, zoomed, etc. + Axis.prototype.reset = function() { + this.renderer.reset.call(this); + }; + + Axis.prototype.resetScale = function(opts) { + $.extend(true, this, {min: null, max: null, numberTicks: null, tickInterval: null, _ticks: [], ticks: []}, opts); + this.resetDataBounds(); + }; + + Axis.prototype.resetDataBounds = function() { + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + var db = this._dataBounds; + db.min = null; + db.max = null; + var l, s, d; + // check for when to force min 0 on bar series plots. + var doforce = (this.show) ? true : false; + for (var i=0; i db.max) || db.max == null) { + db.max = d[j][0]; + } + } + else { + if ((d[j][minyidx] != null && d[j][minyidx] < db.min) || db.min == null) { + db.min = d[j][minyidx]; + } + if ((d[j][maxyidx] != null && d[j][maxyidx] > db.max) || db.max == null) { + db.max = d[j][maxyidx]; + } + } + } + + // Hack to not pad out bottom of bar plots unless user has specified a padding. + // every series will have a chance to set doforce to false. once it is set to + // false, it cannot be reset to true. + // If any series attached to axis is not a bar, wont force 0. + if (doforce && s.renderer.constructor !== $.jqplot.BarRenderer) { + doforce = false; + } + + else if (doforce && this._options.hasOwnProperty('forceTickAt0') && this._options.forceTickAt0 == false) { + doforce = false; + } + + else if (doforce && s.renderer.constructor === $.jqplot.BarRenderer) { + if (s.barDirection == 'vertical' && this.name != 'xaxis' && this.name != 'x2axis') { + if (this._options.pad != null || this._options.padMin != null) { + doforce = false; + } + } + + else if (s.barDirection == 'horizontal' && (this.name == 'xaxis' || this.name == 'x2axis')) { + if (this._options.pad != null || this._options.padMin != null) { + doforce = false; + } + } + + } + } + } + + if (doforce && this.renderer.constructor === $.jqplot.LinearAxisRenderer && db.min >= 0) { + this.padMin = 1.0; + this.forceTickAt0 = true; + } + }; + + /** + * Class: Legend + * Legend object. Cannot be instantiated directly, but created + * by the Plot object. Legend properties can be set or overridden by the + * options passed in from the user. + */ + function Legend(options) { + $.jqplot.ElemContainer.call(this); + // Group: Properties + + // prop: show + // Wether to display the legend on the graph. + this.show = false; + // prop: location + // Placement of the legend. one of the compass directions: nw, n, ne, e, se, s, sw, w + this.location = 'ne'; + // prop: labels + // Array of labels to use. By default the renderer will look for labels on the series. + // Labels specified in this array will override labels specified on the series. + this.labels = []; + // prop: showLabels + // true to show the label text on the legend. + this.showLabels = true; + // prop: showSwatch + // true to show the color swatches on the legend. + this.showSwatches = true; + // prop: placement + // "insideGrid" places legend inside the grid area of the plot. + // "outsideGrid" places the legend outside the grid but inside the plot container, + // shrinking the grid to accomodate the legend. + // "inside" synonym for "insideGrid", + // "outside" places the legend ouside the grid area, but does not shrink the grid which + // can cause the legend to overflow the plot container. + this.placement = "insideGrid"; + // prop: xoffset + // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. + // properties or via CSS margin styling of the .jqplot-table-legend class. + this.xoffset = 0; + // prop: yoffset + // DEPRECATED. Set the margins on the legend using the marginTop, marginLeft, etc. + // properties or via CSS margin styling of the .jqplot-table-legend class. + this.yoffset = 0; + // prop: border + // css spec for the border around the legend box. + this.border; + // prop: background + // css spec for the background of the legend box. + this.background; + // prop: textColor + // css color spec for the legend text. + this.textColor; + // prop: fontFamily + // css font-family spec for the legend text. + this.fontFamily; + // prop: fontSize + // css font-size spec for the legend text. + this.fontSize ; + // prop: rowSpacing + // css padding-top spec for the rows in the legend. + this.rowSpacing = '0.5em'; + // renderer + // A class that will create a DOM object for the legend, + // see <$.jqplot.TableLegendRenderer>. + this.renderer = $.jqplot.TableLegendRenderer; + // prop: rendererOptions + // renderer specific options passed to the renderer. + this.rendererOptions = {}; + // prop: predraw + // Wether to draw the legend before the series or not. + // Used with series specific legend renderers for pie, donut, mekko charts, etc. + this.preDraw = false; + // prop: marginTop + // CSS margin for the legend DOM element. This will set an element + // CSS style for the margin which will override any style sheet setting. + // The default will be taken from the stylesheet. + this.marginTop = null; + // prop: marginRight + // CSS margin for the legend DOM element. This will set an element + // CSS style for the margin which will override any style sheet setting. + // The default will be taken from the stylesheet. + this.marginRight = null; + // prop: marginBottom + // CSS margin for the legend DOM element. This will set an element + // CSS style for the margin which will override any style sheet setting. + // The default will be taken from the stylesheet. + this.marginBottom = null; + // prop: marginLeft + // CSS margin for the legend DOM element. This will set an element + // CSS style for the margin which will override any style sheet setting. + // The default will be taken from the stylesheet. + this.marginLeft = null; + // prop: escapeHtml + // True to escape special characters with their html entity equivalents + // in legend text. "<" becomes < and so on, so html tags are not rendered. + this.escapeHtml = false; + this._series = []; + + $.extend(true, this, options); + } + + Legend.prototype = new $.jqplot.ElemContainer(); + Legend.prototype.constructor = Legend; + + Legend.prototype.setOptions = function(options) { + $.extend(true, this, options); + + // Try to emulate deprecated behaviour + // if user has specified xoffset or yoffset, copy these to + // the margin properties. + + if (this.placement == 'inside') { + this.placement = 'insideGrid'; + } + + if (this.xoffset >0) { + if (this.placement == 'insideGrid') { + switch (this.location) { + case 'nw': + case 'w': + case 'sw': + if (this.marginLeft == null) { + this.marginLeft = this.xoffset + 'px'; + } + this.marginRight = '0px'; + break; + case 'ne': + case 'e': + case 'se': + default: + if (this.marginRight == null) { + this.marginRight = this.xoffset + 'px'; + } + this.marginLeft = '0px'; + break; + } + } + else if (this.placement == 'outside') { + switch (this.location) { + case 'nw': + case 'w': + case 'sw': + if (this.marginRight == null) { + this.marginRight = this.xoffset + 'px'; + } + this.marginLeft = '0px'; + break; + case 'ne': + case 'e': + case 'se': + default: + if (this.marginLeft == null) { + this.marginLeft = this.xoffset + 'px'; + } + this.marginRight = '0px'; + break; + } + } + this.xoffset = 0; + } + + if (this.yoffset >0) { + if (this.placement == 'outside') { + switch (this.location) { + case 'sw': + case 's': + case 'se': + if (this.marginTop == null) { + this.marginTop = this.yoffset + 'px'; + } + this.marginBottom = '0px'; + break; + case 'ne': + case 'n': + case 'nw': + default: + if (this.marginBottom == null) { + this.marginBottom = this.yoffset + 'px'; + } + this.marginTop = '0px'; + break; + } + } + else if (this.placement == 'insideGrid') { + switch (this.location) { + case 'sw': + case 's': + case 'se': + if (this.marginBottom == null) { + this.marginBottom = this.yoffset + 'px'; + } + this.marginTop = '0px'; + break; + case 'ne': + case 'n': + case 'nw': + default: + if (this.marginTop == null) { + this.marginTop = this.yoffset + 'px'; + } + this.marginBottom = '0px'; + break; + } + } + this.yoffset = 0; + } + + // TO-DO: + // Handle case where offsets are < 0. + // + }; + + Legend.prototype.init = function() { + if ($.isFunction(this.renderer)) { + this.renderer = new this.renderer(); + } + this.renderer.init.call(this, this.rendererOptions); + }; + + Legend.prototype.draw = function(offsets, plot) { + for (var i=0; i<$.jqplot.preDrawLegendHooks.length; i++){ + $.jqplot.preDrawLegendHooks[i].call(this, offsets); + } + return this.renderer.draw.call(this, offsets, plot); + }; + + Legend.prototype.pack = function(offsets) { + this.renderer.pack.call(this, offsets); + }; + + /** + * Class: Title + * Plot Title object. Cannot be instantiated directly, but created + * by the Plot object. Title properties can be set or overridden by the + * options passed in from the user. + * + * Parameters: + * text - text of the title. + */ + function Title(text) { + $.jqplot.ElemContainer.call(this); + // Group: Properties + + // prop: text + // text of the title; + this.text = text; + // prop: show + // whether or not to show the title + this.show = true; + // prop: fontFamily + // css font-family spec for the text. + this.fontFamily; + // prop: fontSize + // css font-size spec for the text. + this.fontSize ; + // prop: textAlign + // css text-align spec for the text. + this.textAlign; + // prop: textColor + // css color spec for the text. + this.textColor; + // prop: renderer + // A class for creating a DOM element for the title, + // see <$.jqplot.DivTitleRenderer>. + this.renderer = $.jqplot.DivTitleRenderer; + // prop: rendererOptions + // renderer specific options passed to the renderer. + this.rendererOptions = {}; + // prop: escapeHtml + // True to escape special characters with their html entity equivalents + // in title text. "<" becomes < and so on, so html tags are not rendered. + this.escapeHtml = false; + } + + Title.prototype = new $.jqplot.ElemContainer(); + Title.prototype.constructor = Title; + + Title.prototype.init = function() { + if ($.isFunction(this.renderer)) { + this.renderer = new this.renderer(); + } + this.renderer.init.call(this, this.rendererOptions); + }; + + Title.prototype.draw = function(width) { + return this.renderer.draw.call(this, width); + }; + + Title.prototype.pack = function() { + this.renderer.pack.call(this); + }; + + + /** + * Class: Series + * An individual data series object. Cannot be instantiated directly, but created + * by the Plot object. Series properties can be set or overridden by the + * options passed in from the user. + */ + function Series(options) { + options = options || {}; + $.jqplot.ElemContainer.call(this); + // Group: Properties + // Properties will be assigned from a series array at the top level of the + // options. If you had two series and wanted to change the color and line + // width of the first and set the second to use the secondary y axis with + // no shadow and supply custom labels for each: + // > { + // > series:[ + // > {color: '#ff4466', lineWidth: 5, label:'good line'}, + // > {yaxis: 'y2axis', shadow: false, label:'bad line'} + // > ] + // > } + + // prop: show + // whether or not to draw the series. + this.show = true; + // prop: xaxis + // which x axis to use with this series, either 'xaxis' or 'x2axis'. + this.xaxis = 'xaxis'; + this._xaxis; + // prop: yaxis + // which y axis to use with this series, either 'yaxis' or 'y2axis'. + this.yaxis = 'yaxis'; + this._yaxis; + this.gridBorderWidth = 2.0; + // prop: renderer + // A class of a renderer which will draw the series, + // see <$.jqplot.LineRenderer>. + this.renderer = $.jqplot.LineRenderer; + // prop: rendererOptions + // Options to pass on to the renderer. + this.rendererOptions = {}; + this.data = []; + this.gridData = []; + // prop: label + // Line label to use in the legend. + this.label = ''; + // prop: showLabel + // true to show label for this series in the legend. + this.showLabel = true; + // prop: color + // css color spec for the series + this.color; + // prop: negativeColor + // css color spec used for filled (area) plots that are filled to zero and + // the "useNegativeColors" option is true. + this.negativeColor; + // prop: lineWidth + // width of the line in pixels. May have different meanings depending on renderer. + this.lineWidth = 2.5; + // prop: lineJoin + // Canvas lineJoin style between segments of series. + this.lineJoin = 'round'; + // prop: lineCap + // Canvas lineCap style at ends of line. + this.lineCap = 'round'; + // prop: linePattern + // line pattern 'dashed', 'dotted', 'solid', some combination + // of '-' and '.' characters such as '.-.' or a numerical array like + // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, + // [1, 10, 20, 10] to draw a dot-dash line, and so on. + this.linePattern = 'solid'; + this.shadow = true; + // prop: shadowAngle + // Shadow angle in degrees + this.shadowAngle = 45; + // prop: shadowOffset + // Shadow offset from line in pixels + this.shadowOffset = 1.25; + // prop: shadowDepth + // Number of times shadow is stroked, each stroke offset shadowOffset from the last. + this.shadowDepth = 3; + // prop: shadowAlpha + // Alpha channel transparency of shadow. 0 = transparent. + this.shadowAlpha = '0.1'; + // prop: breakOnNull + // Wether line segments should be be broken at null value. + // False will join point on either side of line. + this.breakOnNull = false; + // prop: markerRenderer + // A class of a renderer which will draw marker (e.g. circle, square, ...) at the data points, + // see <$.jqplot.MarkerRenderer>. + this.markerRenderer = $.jqplot.MarkerRenderer; + // prop: markerOptions + // renderer specific options to pass to the markerRenderer, + // see <$.jqplot.MarkerRenderer>. + this.markerOptions = {}; + // prop: showLine + // whether to actually draw the line or not. Series will still be renderered, even if no line is drawn. + this.showLine = true; + // prop: showMarker + // whether or not to show the markers at the data points. + this.showMarker = true; + // prop: index + // 0 based index of this series in the plot series array. + this.index; + // prop: fill + // true or false, whether to fill under lines or in bars. + // May not be implemented in all renderers. + this.fill = false; + // prop: fillColor + // CSS color spec to use for fill under line. Defaults to line color. + this.fillColor; + // prop: fillAlpha + // Alpha transparency to apply to the fill under the line. + // Use this to adjust alpha separate from fill color. + this.fillAlpha; + // prop: fillAndStroke + // If true will stroke the line (with color this.color) as well as fill under it. + // Applies only when fill is true. + this.fillAndStroke = false; + // prop: disableStack + // true to not stack this series with other series in the plot. + // To render properly, non-stacked series must come after any stacked series + // in the plot's data series array. So, the plot's data series array would look like: + // > [stackedSeries1, stackedSeries2, ..., nonStackedSeries1, nonStackedSeries2, ...] + // disableStack will put a gap in the stacking order of series, and subsequent + // stacked series will not fill down through the non-stacked series and will + // most likely not stack properly on top of the non-stacked series. + this.disableStack = false; + // _stack is set by the Plot if the plot is a stacked chart. + // will stack lines or bars on top of one another to build a "mountain" style chart. + // May not be implemented in all renderers. + this._stack = false; + // prop: neighborThreshold + // how close or far (in pixels) the cursor must be from a point marker to detect the point. + this.neighborThreshold = 4; + // prop: fillToZero + // true will force bar and filled series to fill toward zero on the fill Axis. + this.fillToZero = false; + // prop: fillToValue + // fill a filled series to this value on the fill axis. + // Works in conjunction with fillToZero, so that must be true. + this.fillToValue = 0; + // prop: fillAxis + // Either 'x' or 'y'. Which axis to fill the line toward if fillToZero is true. + // 'y' means fill up/down to 0 on the y axis for this series. + this.fillAxis = 'y'; + // prop: useNegativeColors + // true to color negative values differently in filled and bar charts. + this.useNegativeColors = true; + this._stackData = []; + // _plotData accounts for stacking. If plots not stacked, _plotData and data are same. If + // stacked, _plotData is accumulation of stacking data. + this._plotData = []; + // _plotValues hold the individual x and y values that will be plotted for this series. + this._plotValues = {x:[], y:[]}; + // statistics about the intervals between data points. Used for auto scaling. + this._intervals = {x:{}, y:{}}; + // data from the previous series, for stacked charts. + this._prevPlotData = []; + this._prevGridData = []; + this._stackAxis = 'y'; + this._primaryAxis = '_xaxis'; + // give each series a canvas to draw on. This should allow for redrawing speedups. + this.canvas = new $.jqplot.GenericCanvas(); + this.shadowCanvas = new $.jqplot.GenericCanvas(); + this.plugins = {}; + // sum of y values in this series. + this._sumy = 0; + this._sumx = 0; + this._type = ''; + } + + Series.prototype = new $.jqplot.ElemContainer(); + Series.prototype.constructor = Series; + + Series.prototype.init = function(index, gridbw, plot) { + // weed out any null values in the data. + this.index = index; + this.gridBorderWidth = gridbw; + var d = this.data; + var temp = [], i, l; + for (i=0, l=d.length; i. + this.renderer = $.jqplot.CanvasGridRenderer; + // prop: rendererOptions + // Options to pass on to the renderer, + // see <$.jqplot.CanvasGridRenderer>. + this.rendererOptions = {}; + this._offsets = {top:null, bottom:null, left:null, right:null}; + } + + Grid.prototype = new $.jqplot.ElemContainer(); + Grid.prototype.constructor = Grid; + + Grid.prototype.init = function() { + if ($.isFunction(this.renderer)) { + this.renderer = new this.renderer(); + } + this.renderer.init.call(this, this.rendererOptions); + }; + + Grid.prototype.createElement = function(offsets,plot) { + this._offsets = offsets; + return this.renderer.createElement.call(this, plot); + }; + + Grid.prototype.draw = function() { + this.renderer.draw.call(this); + }; + + $.jqplot.GenericCanvas = function() { + $.jqplot.ElemContainer.call(this); + this._ctx; + }; + + $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer(); + $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas; + + $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions, plot) { + this._offsets = offsets; + var klass = 'jqplot'; + if (clss != undefined) { + klass = clss; + } + var elem; + + elem = plot.canvasManager.getCanvas(); + + // if new plotDimensions supplied, use them. + if (plotDimensions != null) { + this._plotDimensions = plotDimensions; + } + + elem.width = this._plotDimensions.width - this._offsets.left - this._offsets.right; + elem.height = this._plotDimensions.height - this._offsets.top - this._offsets.bottom; + this._elem = $(elem); + this._elem.css({ position: 'absolute', left: this._offsets.left, top: this._offsets.top }); + + this._elem.addClass(klass); + + elem = plot.canvasManager.initCanvas(elem); + + elem = null; + return this._elem; + }; + + $.jqplot.GenericCanvas.prototype.setContext = function() { + this._ctx = this._elem.get(0).getContext("2d"); + return this._ctx; + }; + + // Memory Leaks patch + $.jqplot.GenericCanvas.prototype.resetCanvas = function() { + if (this._elem) { + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); + } + + //this._elem.remove(); + this._elem.emptyForce(); + } + + this._ctx = null; + }; + + $.jqplot.HooksManager = function () { + this.hooks =[]; + this.args = []; + }; + + $.jqplot.HooksManager.prototype.addOnce = function(fn, args) { + args = args || []; + var havehook = false; + for (var i=0, l=this.hooks.length; i { + // > axesDefaults:{min:0}, + // > series:[{color:'#6633dd'}], + // > title: 'A Plot' + // > } + // + + // prop: animate + // True to animate the series on initial plot draw (renderer dependent). + // Actual animation functionality must be supported in the renderer. + this.animate = false; + // prop: animateReplot + // True to animate series after a call to the replot() method. + // Use with caution! Replots can happen very frequently under + // certain circumstances (e.g. resizing, dragging points) and + // animation in these situations can cause problems. + this.animateReplot = false; + // prop: axes + // up to 4 axes are supported, each with its own options, + // See for axis specific options. + this.axes = {xaxis: new Axis('xaxis'), yaxis: new Axis('yaxis'), x2axis: new Axis('x2axis'), y2axis: new Axis('y2axis'), y3axis: new Axis('y3axis'), y4axis: new Axis('y4axis'), y5axis: new Axis('y5axis'), y6axis: new Axis('y6axis'), y7axis: new Axis('y7axis'), y8axis: new Axis('y8axis'), y9axis: new Axis('y9axis'), yMidAxis: new Axis('yMidAxis')}; + this.baseCanvas = new $.jqplot.GenericCanvas(); + // true to intercept right click events and fire a 'jqplotRightClick' event. + // this will also block the context menu. + this.captureRightClick = false; + // prop: data + // user's data. Data should *NOT* be specified in the options object, + // but be passed in as the second argument to the $.jqplot() function. + // The data property is described here soley for reference. + // The data should be in the form of an array of 2D or 1D arrays like + // > [ [[x1, y1], [x2, y2],...], [y1, y2, ...] ]. + this.data = []; + // prop: dataRenderer + // A callable which can be used to preprocess data passed into the plot. + // Will be called with 3 arguments: the plot data, a reference to the plot, + // and the value of dataRendererOptions. + this.dataRenderer; + // prop: dataRendererOptions + // Options that will be passed to the dataRenderer. + // Can be of any type. + this.dataRendererOptions; + this.defaults = { + // prop: axesDefaults + // default options that will be applied to all axes. + // see for axes options. + axesDefaults: {}, + axes: {xaxis:{}, yaxis:{}, x2axis:{}, y2axis:{}, y3axis:{}, y4axis:{}, y5axis:{}, y6axis:{}, y7axis:{}, y8axis:{}, y9axis:{}, yMidAxis:{}}, + // prop: seriesDefaults + // default options that will be applied to all series. + // see for series options. + seriesDefaults: {}, + series:[] + }; + // prop: defaultAxisStart + // 1-D data series are internally converted into 2-D [x,y] data point arrays + // by jqPlot. This is the default starting value for the missing x or y value. + // The added data will be a monotonically increasing series (e.g. [1, 2, 3, ...]) + // starting at this value. + this.defaultAxisStart = 1; + // this.doCustomEventBinding = true; + // prop: drawIfHidden + // True to execute the draw method even if the plot target is hidden. + // Generally, this should be false. Most plot elements will not be sized/ + // positioned correclty if renderered into a hidden container. To render into + // a hidden container, call the replot method when the container is shown. + this.drawIfHidden = false; + this.eventCanvas = new $.jqplot.GenericCanvas(); + // prop: fillBetween + // Fill between 2 line series in a plot. + // Options object: + // { + // series1: first index (0 based) of series in fill + // series2: second index (0 based) of series in fill + // color: color of fill [default fillColor of series1] + // baseSeries: fill will be drawn below this series (0 based index) + // fill: false to turn off fill [default true]. + // } + this.fillBetween = { + series1: null, + series2: null, + color: null, + baseSeries: 0, + fill: true + }; + // prop; fontFamily + // css spec for the font-family attribute. Default for the entire plot. + this.fontFamily; + // prop: fontSize + // css spec for the font-size attribute. Default for the entire plot. + this.fontSize; + // prop: grid + // See for grid specific options. + this.grid = new Grid(); + // prop: legend + // see <$.jqplot.TableLegendRenderer> + this.legend = new Legend(); + // prop: noDataIndicator + // Options to set up a mock plot with a data loading indicator if no data is specified. + this.noDataIndicator = { + show: false, + indicator: 'Loading Data...', + axes: { + xaxis: { + min: 0, + max: 10, + tickInterval: 2, + show: true + }, + yaxis: { + min: 0, + max: 12, + tickInterval: 3, + show: true + } + } + }; + // prop: negativeSeriesColors + // colors to use for portions of the line below zero. + this.negativeSeriesColors = $.jqplot.config.defaultNegativeColors; + // container to hold all of the merged options. Convienence for plugins. + this.options = {}; + this.previousSeriesStack = []; + // Namespace to hold plugins. Generally non-renderer plugins add themselves to here. + this.plugins = {}; + // prop: series + // Array of series object options. + // see for series specific options. + this.series = []; + // array of series indices. Keep track of order + // which series canvases are displayed, lowest + // to highest, back to front. + this.seriesStack = []; + // prop: seriesColors + // Ann array of CSS color specifications that will be applied, in order, + // to the series in the plot. Colors will wrap around so, if their + // are more series than colors, colors will be reused starting at the + // beginning. For pie charts, this specifies the colors of the slices. + this.seriesColors = $.jqplot.config.defaultColors; + // prop: sortData + // false to not sort the data passed in by the user. + // Many bar, stacked and other graphs as well as many plugins depend on + // having sorted data. + this.sortData = true; + // prop: stackSeries + // true or false, creates a stack or "mountain" plot. + // Not all series renderers may implement this option. + this.stackSeries = false; + // a shortcut for axis syncTicks options. Not implemented yet. + this.syncXTicks = true; + // a shortcut for axis syncTicks options. Not implemented yet. + this.syncYTicks = true; + // the jquery object for the dom target. + this.target = null; + // The id of the dom element to render the plot into + this.targetId = null; + // prop textColor + // css spec for the css color attribute. Default for the entire plot. + this.textColor; + // prop: title + // Title object. See for specific options. As a shortcut, you + // can specify the title option as just a string like: title: 'My Plot' + // and this will create a new title object with the specified text. + this.title = new Title(); + // Count how many times the draw method has been called while the plot is visible. + // Mostly used to test if plot has never been dran (=0), has been successfully drawn + // into a visible container once (=1) or draw more than once into a visible container. + // Can use this in tests to see if plot has been visibly drawn at least one time. + // After plot has been visibly drawn once, it generally doesn't need redrawing if its + // container is hidden and shown. + this._drawCount = 0; + // sum of y values for all series in plot. + // used in mekko chart. + this._sumy = 0; + this._sumx = 0; + // array to hold the cumulative stacked series data. + // used to ajust the individual series data, which won't have access to other + // series data. + this._stackData = []; + // array that holds the data to be plotted. This will be the series data + // merged with the the appropriate data from _stackData according to the stackAxis. + this._plotData = []; + this._width = null; + this._height = null; + this._plotDimensions = {height:null, width:null}; + this._gridPadding = {top:null, right:null, bottom:null, left:null}; + this._defaultGridPadding = {top:10, right:10, bottom:23, left:10}; + + this._addDomReference = $.jqplot.config.addDomReference; + + this.preInitHooks = new $.jqplot.HooksManager(); + this.postInitHooks = new $.jqplot.HooksManager(); + this.preParseOptionsHooks = new $.jqplot.HooksManager(); + this.postParseOptionsHooks = new $.jqplot.HooksManager(); + this.preDrawHooks = new $.jqplot.HooksManager(); + this.postDrawHooks = new $.jqplot.HooksManager(); + this.preDrawSeriesHooks = new $.jqplot.HooksManager(); + this.postDrawSeriesHooks = new $.jqplot.HooksManager(); + this.preDrawLegendHooks = new $.jqplot.HooksManager(); + this.addLegendRowHooks = new $.jqplot.HooksManager(); + this.preSeriesInitHooks = new $.jqplot.HooksManager(); + this.postSeriesInitHooks = new $.jqplot.HooksManager(); + this.preParseSeriesOptionsHooks = new $.jqplot.HooksManager(); + this.postParseSeriesOptionsHooks = new $.jqplot.HooksManager(); + this.eventListenerHooks = new $.jqplot.EventListenerManager(); + this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager(); + this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager(); + + this.colorGenerator = new $.jqplot.ColorGenerator(); + this.negativeColorGenerator = new $.jqplot.ColorGenerator(); + + this.canvasManager = new $.jqplot.CanvasManager(); + + this.themeEngine = new $.jqplot.ThemeEngine(); + + var seriesColorsIndex = 0; + + // Group: methods + // + // method: init + // sets the plot target, checks data and applies user + // options to plot. + this.init = function(target, data, options) { + options = options || {}; + for (var i=0; i<$.jqplot.preInitHooks.length; i++) { + $.jqplot.preInitHooks[i].call(this, target, data, options); + } + + for (var i=0; i<this.preInitHooks.hooks.length; i++) { + this.preInitHooks.hooks[i].call(this, target, data, options); + } + + this.targetId = '#'+target; + this.target = $('#'+target); + + ////// + // Add a reference to plot + ////// + if (this._addDomReference) { + this.target.data('jqplot', this); + } + // remove any error class that may be stuck on target. + this.target.removeClass('jqplot-error'); + if (!this.target.get(0)) { + throw new Error("No plot target specified"); + } + + // make sure the target is positioned by some means and set css + if (this.target.css('position') == 'static') { + this.target.css('position', 'relative'); + } + if (!this.target.hasClass('jqplot-target')) { + this.target.addClass('jqplot-target'); + } + + // if no height or width specified, use a default. + if (!this.target.height()) { + var h; + if (options && options.height) { + h = parseInt(options.height, 10); + } + else if (this.target.attr('data-height')) { + h = parseInt(this.target.attr('data-height'), 10); + } + else { + h = parseInt($.jqplot.config.defaultHeight, 10); + } + this._height = h; + this.target.css('height', h+'px'); + } + else { + this._height = h = this.target.height(); + } + if (!this.target.width()) { + var w; + if (options && options.width) { + w = parseInt(options.width, 10); + } + else if (this.target.attr('data-width')) { + w = parseInt(this.target.attr('data-width'), 10); + } + else { + w = parseInt($.jqplot.config.defaultWidth, 10); + } + this._width = w; + this.target.css('width', w+'px'); + } + else { + this._width = w = this.target.width(); + } + + for (var i=0, l=_axisNames.length; i<l; i++) { + this.axes[_axisNames[i]] = new Axis(_axisNames[i]); + } + + this._plotDimensions.height = this._height; + this._plotDimensions.width = this._width; + this.grid._plotDimensions = this._plotDimensions; + this.title._plotDimensions = this._plotDimensions; + this.baseCanvas._plotDimensions = this._plotDimensions; + this.eventCanvas._plotDimensions = this._plotDimensions; + this.legend._plotDimensions = this._plotDimensions; + if (this._height <=0 || this._width <=0 || !this._height || !this._width) { + throw new Error("Canvas dimension not set"); + } + + if (options.dataRenderer && $.isFunction(options.dataRenderer)) { + if (options.dataRendererOptions) { + this.dataRendererOptions = options.dataRendererOptions; + } + this.dataRenderer = options.dataRenderer; + data = this.dataRenderer(data, this, this.dataRendererOptions); + } + + if (options.noDataIndicator && $.isPlainObject(options.noDataIndicator)) { + $.extend(true, this.noDataIndicator, options.noDataIndicator); + } + + if (data == null || $.isArray(data) == false || data.length == 0 || $.isArray(data[0]) == false || data[0].length == 0) { + + if (this.noDataIndicator.show == false) { + throw new Error("No data specified"); + } + + else { + // have to be descructive here in order for plot to not try and render series. + // This means that $.jqplot() will have to be called again when there is data. + //delete options.series; + + for (var ax in this.noDataIndicator.axes) { + for (var prop in this.noDataIndicator.axes[ax]) { + this.axes[ax][prop] = this.noDataIndicator.axes[ax][prop]; + } + } + + this.postDrawHooks.add(function() { + var eh = this.eventCanvas.getHeight(); + var ew = this.eventCanvas.getWidth(); + var temp = $('<div class="jqplot-noData-container" style="position:absolute;"></div>'); + this.target.append(temp); + temp.height(eh); + temp.width(ew); + temp.css('top', this.eventCanvas._offsets.top); + temp.css('left', this.eventCanvas._offsets.left); + + var temp2 = $('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>'); + temp.append(temp2); + temp2.html(this.noDataIndicator.indicator); + var th = temp2.height(); + var tw = temp2.width(); + temp2.height(th); + temp2.width(tw); + temp2.css('top', (eh - th)/2 + 'px'); + }); + + } + } + + // make a copy of the data + this.data = $.extend(true, [], data); + + this.parseOptions(options); + + if (this.textColor) { + this.target.css('color', this.textColor); + } + if (this.fontFamily) { + this.target.css('font-family', this.fontFamily); + } + if (this.fontSize) { + this.target.css('font-size', this.fontSize); + } + + this.title.init(); + this.legend.init(); + this._sumy = 0; + this._sumx = 0; + this.computePlotData(); + for (var i=0; i<this.series.length; i++) { + // set default stacking order for series canvases + this.seriesStack.push(i); + this.previousSeriesStack.push(i); + this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; + this.series[i].canvas._plotDimensions = this._plotDimensions; + for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { + $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { + this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + // this.populatePlotData(this.series[i], i); + this.series[i]._plotDimensions = this._plotDimensions; + this.series[i].init(i, this.grid.borderWidth, this); + for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { + $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { + this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + this._sumy += this.series[i]._sumy; + this._sumx += this.series[i]._sumx; + } + + var name, + axis; + for (var i=0, l=_axisNames.length; i<l; i++) { + name = _axisNames[i]; + axis = this.axes[name]; + axis._plotDimensions = this._plotDimensions; + axis.init(); + if (this.axes[name].borderColor == null) { + if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) { + axis.borderColor = axis._series[0].color; + } + else { + axis.borderColor = this.grid.borderColor; + } + } + } + + if (this.sortData) { + sortData(this.series); + } + this.grid.init(); + this.grid._axes = this.axes; + + this.legend._series = this.series; + + for (var i=0; i<$.jqplot.postInitHooks.length; i++) { + $.jqplot.postInitHooks[i].call(this, target, this.data, options); + } + + for (var i=0; i<this.postInitHooks.hooks.length; i++) { + this.postInitHooks.hooks[i].call(this, target, this.data, options); + } + }; + + // method: resetAxesScale + // Reset the specified axes min, max, numberTicks and tickInterval properties to null + // or reset these properties on all axes if no list of axes is provided. + // + // Parameters: + // axes - Boolean to reset or not reset all axes or an array or object of axis names to reset. + this.resetAxesScale = function(axes, options) { + var opts = options || {}; + var ax = axes || this.axes; + if (ax === true) { + ax = this.axes; + } + if ($.isArray(ax)) { + for (var i = 0; i < ax.length; i++) { + this.axes[ax[i]].resetScale(opts[ax[i]]); + } + } + else if (typeof(ax) === 'object') { + for (var name in ax) { + this.axes[name].resetScale(opts[name]); + } + } + }; + // method: reInitialize + // reinitialize plot for replotting. + // not called directly. + this.reInitialize = function (data, opts) { + // Plot should be visible and have a height and width. + // If plot doesn't have height and width for some + // reason, set it by other means. Plot must not have + // a display:none attribute, however. + + var options = $.extend(true, {}, this.options, opts); + + var target = this.targetId.substr(1); + var tdata = (data == null) ? this.data : data; + + for (var i=0; i<$.jqplot.preInitHooks.length; i++) { + $.jqplot.preInitHooks[i].call(this, target, tdata, options); + } + + for (var i=0; i<this.preInitHooks.hooks.length; i++) { + this.preInitHooks.hooks[i].call(this, target, tdata, options); + } + + this._height = this.target.height(); + this._width = this.target.width(); + + if (this._height <=0 || this._width <=0 || !this._height || !this._width) { + throw new Error("Target dimension not set"); + } + + this._plotDimensions.height = this._height; + this._plotDimensions.width = this._width; + this.grid._plotDimensions = this._plotDimensions; + this.title._plotDimensions = this._plotDimensions; + this.baseCanvas._plotDimensions = this._plotDimensions; + this.eventCanvas._plotDimensions = this._plotDimensions; + this.legend._plotDimensions = this._plotDimensions; + + var name, + t, + j, + axis; + + for (var i=0, l=_axisNames.length; i<l; i++) { + name = _axisNames[i]; + axis = this.axes[name]; + + // Memory Leaks patch : clear ticks elements + t = axis._ticks; + for (var j = 0, tlen = t.length; j < tlen; j++) { + var el = t[j]._elem; + if (el) { + // if canvas renderer + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + window.G_vmlCanvasManager.uninitElement(el.get(0)); + } + el.emptyForce(); + el = null; + t._elem = null; + } + } + t = null; + + delete axis.ticks; + delete axis._ticks; + this.axes[name] = new Axis(name); + this.axes[name]._plotWidth = this._width; + this.axes[name]._plotHeight = this._height; + } + + if (data) { + if (options.dataRenderer && $.isFunction(options.dataRenderer)) { + if (options.dataRendererOptions) { + this.dataRendererOptions = options.dataRendererOptions; + } + this.dataRenderer = options.dataRenderer; + data = this.dataRenderer(data, this, this.dataRendererOptions); + } + + // make a copy of the data + this.data = $.extend(true, [], data); + } + + if (opts) { + this.parseOptions(options); + } + + this.title._plotWidth = this._width; + + if (this.textColor) { + this.target.css('color', this.textColor); + } + if (this.fontFamily) { + this.target.css('font-family', this.fontFamily); + } + if (this.fontSize) { + this.target.css('font-size', this.fontSize); + } + + this.title.init(); + this.legend.init(); + this._sumy = 0; + this._sumx = 0; + + this.seriesStack = []; + this.previousSeriesStack = []; + + this.computePlotData(); + for (var i=0, l=this.series.length; i<l; i++) { + // set default stacking order for series canvases + this.seriesStack.push(i); + this.previousSeriesStack.push(i); + this.series[i].shadowCanvas._plotDimensions = this._plotDimensions; + this.series[i].canvas._plotDimensions = this._plotDimensions; + for (var j=0; j<$.jqplot.preSeriesInitHooks.length; j++) { + $.jqplot.preSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + for (var j=0; j<this.preSeriesInitHooks.hooks.length; j++) { + this.preSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + // this.populatePlotData(this.series[i], i); + this.series[i]._plotDimensions = this._plotDimensions; + this.series[i].init(i, this.grid.borderWidth, this); + for (var j=0; j<$.jqplot.postSeriesInitHooks.length; j++) { + $.jqplot.postSeriesInitHooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + for (var j=0; j<this.postSeriesInitHooks.hooks.length; j++) { + this.postSeriesInitHooks.hooks[j].call(this.series[i], target, this.data, this.options.seriesDefaults, this.options.series[i], this); + } + this._sumy += this.series[i]._sumy; + this._sumx += this.series[i]._sumx; + } + + for (var i=0, l=_axisNames.length; i<l; i++) { + name = _axisNames[i]; + axis = this.axes[name]; + + axis._plotDimensions = this._plotDimensions; + axis.init(); + if (axis.borderColor == null) { + if (name.charAt(0) !== 'x' && axis.useSeriesColor === true && axis.show) { + axis.borderColor = axis._series[0].color; + } + else { + axis.borderColor = this.grid.borderColor; + } + } + } + + if (this.sortData) { + sortData(this.series); + } + this.grid.init(); + this.grid._axes = this.axes; + + this.legend._series = this.series; + + for (var i=0, l=$.jqplot.postInitHooks.length; i<l; i++) { + $.jqplot.postInitHooks[i].call(this, target, this.data, options); + } + + for (var i=0, l=this.postInitHooks.hooks.length; i<l; i++) { + this.postInitHooks.hooks[i].call(this, target, this.data, options); + } + }; + + + + // method: quickInit + // + // Quick reinitialization plot for replotting. + // Does not parse options ore recreate axes and series. + // not called directly. + this.quickInit = function () { + // Plot should be visible and have a height and width. + // If plot doesn't have height and width for some + // reason, set it by other means. Plot must not have + // a display:none attribute, however. + + this._height = this.target.height(); + this._width = this.target.width(); + + if (this._height <=0 || this._width <=0 || !this._height || !this._width) { + throw new Error("Target dimension not set"); + } + + this._plotDimensions.height = this._height; + this._plotDimensions.width = this._width; + this.grid._plotDimensions = this._plotDimensions; + this.title._plotDimensions = this._plotDimensions; + this.baseCanvas._plotDimensions = this._plotDimensions; + this.eventCanvas._plotDimensions = this._plotDimensions; + this.legend._plotDimensions = this._plotDimensions; + + for (var n in this.axes) { + this.axes[n]._plotWidth = this._width; + this.axes[n]._plotHeight = this._height; + } + + this.title._plotWidth = this._width; + + if (this.textColor) { + this.target.css('color', this.textColor); + } + if (this.fontFamily) { + this.target.css('font-family', this.fontFamily); + } + if (this.fontSize) { + this.target.css('font-size', this.fontSize); + } + + this._sumy = 0; + this._sumx = 0; + this.computePlotData(); + for (var i=0; i<this.series.length; i++) { + // this.populatePlotData(this.series[i], i); + if (this.series[i]._type === 'line' && this.series[i].renderer.bands.show) { + this.series[i].renderer.initBands.call(this.series[i], this.series[i].renderer.options, this); + } + this.series[i]._plotDimensions = this._plotDimensions; + this.series[i].canvas._plotDimensions = this._plotDimensions; + //this.series[i].init(i, this.grid.borderWidth); + this._sumy += this.series[i]._sumy; + this._sumx += this.series[i]._sumx; + } + + var name; + + for (var j=0; j<12; j++) { + name = _axisNames[j]; + // Memory Leaks patch : clear ticks elements + var t = this.axes[name]._ticks; + for (var i = 0; i < t.length; i++) { + var el = t[i]._elem; + if (el) { + // if canvas renderer + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + window.G_vmlCanvasManager.uninitElement(el.get(0)); + } + el.emptyForce(); + el = null; + t._elem = null; + } + } + t = null; + + this.axes[name]._plotDimensions = this._plotDimensions; + this.axes[name]._ticks = []; + // this.axes[name].renderer.init.call(this.axes[name], {}); + } + + if (this.sortData) { + sortData(this.series); + } + + this.grid._axes = this.axes; + + this.legend._series = this.series; + }; + + // sort the series data in increasing order. + function sortData(series) { + var d, sd, pd, ppd, ret; + for (var i=0; i<series.length; i++) { + var check; + var bat = [series[i].data, series[i]._stackData, series[i]._plotData, series[i]._prevPlotData]; + for (var n=0; n<4; n++) { + check = true; + d = bat[n]; + if (series[i]._stackAxis == 'x') { + for (var j = 0; j < d.length; j++) { + if (typeof(d[j][1]) != "number") { + check = false; + break; + } + } + if (check) { + d.sort(function(a,b) { return a[1] - b[1]; }); + } + } + else { + for (var j = 0; j < d.length; j++) { + if (typeof(d[j][0]) != "number") { + check = false; + break; + } + } + if (check) { + d.sort(function(a,b) { return a[0] - b[0]; }); + } + } + } + + } + } + + this.computePlotData = function() { + this._plotData = []; + this._stackData = []; + var series, + index, + l; + + + for (index=0, l=this.series.length; index<l; index++) { + series = this.series[index]; + this._plotData.push([]); + this._stackData.push([]); + var cd = series.data; + this._plotData[index] = $.extend(true, [], cd); + this._stackData[index] = $.extend(true, [], cd); + series._plotData = this._plotData[index]; + series._stackData = this._stackData[index]; + var plotValues = {x:[], y:[]}; + + if (this.stackSeries && !series.disableStack) { + series._stack = true; + /////////////////////////// + // have to check for nulls + /////////////////////////// + var sidx = (series._stackAxis === 'x') ? 0 : 1; + + for (var k=0, cdl=cd.length; k<cdl; k++) { + var temp = cd[k][sidx]; + if (temp == null) { + temp = 0; + } + this._plotData[index][k][sidx] = temp; + this._stackData[index][k][sidx] = temp; + + if (index > 0) { + for (var j=index; j--;) { + var prevval = this._plotData[j][k][sidx]; + // only need to sum up the stack axis column of data + // and only sum if it is of same sign. + // if previous series isn't same sign, keep looking + // at earlier series untill we find one of same sign. + if (temp * prevval >= 0) { + this._plotData[index][k][sidx] += prevval; + this._stackData[index][k][sidx] += prevval; + break; + } + } + } + } + + } + else { + for (var i=0; i<series.data.length; i++) { + plotValues.x.push(series.data[i][0]); + plotValues.y.push(series.data[i][1]); + } + this._stackData.push(series.data); + this.series[index]._stackData = series.data; + this._plotData.push(series.data); + series._plotData = series.data; + series._plotValues = plotValues; + } + if (index>0) { + series._prevPlotData = this.series[index-1]._plotData; + } + series._sumy = 0; + series._sumx = 0; + for (i=series.data.length-1; i>-1; i--) { + series._sumy += series.data[i][1]; + series._sumx += series.data[i][0]; + } + } + + }; + + // populate the _stackData and _plotData arrays for the plot and the series. + this.populatePlotData = function(series, index) { + // if a stacked chart, compute the stacked data + this._plotData = []; + this._stackData = []; + series._stackData = []; + series._plotData = []; + var plotValues = {x:[], y:[]}; + if (this.stackSeries && !series.disableStack) { + series._stack = true; + var sidx = (series._stackAxis === 'x') ? 0 : 1; + // var idx = sidx ? 0 : 1; + // push the current data into stackData + //this._stackData.push(this.series[i].data); + var temp = $.extend(true, [], series.data); + // create the data that will be plotted for this series + var plotdata = $.extend(true, [], series.data); + var tempx, tempy, dval, stackval, comparator; + // for first series, nothing to add to stackData. + for (var j=0; j<index; j++) { + var cd = this.series[j].data; + for (var k=0; k<cd.length; k++) { + dval = cd[k]; + tempx = (dval[0] != null) ? dval[0] : 0; + tempy = (dval[1] != null) ? dval[1] : 0; + temp[k][0] += tempx; + temp[k][1] += tempy; + stackval = (sidx) ? tempy : tempx; + // only need to sum up the stack axis column of data + // and only sum if it is of same sign. + if (series.data[k][sidx] * stackval >= 0) { + plotdata[k][sidx] += stackval; + } + } + } + for (var i=0; i<plotdata.length; i++) { + plotValues.x.push(plotdata[i][0]); + plotValues.y.push(plotdata[i][1]); + } + this._plotData.push(plotdata); + this._stackData.push(temp); + series._stackData = temp; + series._plotData = plotdata; + series._plotValues = plotValues; + } + else { + for (var i=0; i<series.data.length; i++) { + plotValues.x.push(series.data[i][0]); + plotValues.y.push(series.data[i][1]); + } + this._stackData.push(series.data); + this.series[index]._stackData = series.data; + this._plotData.push(series.data); + series._plotData = series.data; + series._plotValues = plotValues; + } + if (index>0) { + series._prevPlotData = this.series[index-1]._plotData; + } + series._sumy = 0; + series._sumx = 0; + for (i=series.data.length-1; i>-1; i--) { + series._sumy += series.data[i][1]; + series._sumx += series.data[i][0]; + } + }; + + // function to safely return colors from the color array and wrap around at the end. + this.getNextSeriesColor = (function(t) { + var idx = 0; + var sc = t.seriesColors; + + return function () { + if (idx < sc.length) { + return sc[idx++]; + } + else { + idx = 0; + return sc[idx++]; + } + }; + })(this); + + this.parseOptions = function(options){ + for (var i=0; i<this.preParseOptionsHooks.hooks.length; i++) { + this.preParseOptionsHooks.hooks[i].call(this, options); + } + for (var i=0; i<$.jqplot.preParseOptionsHooks.length; i++) { + $.jqplot.preParseOptionsHooks[i].call(this, options); + } + this.options = $.extend(true, {}, this.defaults, options); + var opts = this.options; + this.animate = opts.animate; + this.animateReplot = opts.animateReplot; + this.stackSeries = opts.stackSeries; + if ($.isPlainObject(opts.fillBetween)) { + + var temp = ['series1', 'series2', 'color', 'baseSeries', 'fill'], + tempi; + + for (var i=0, l=temp.length; i<l; i++) { + tempi = temp[i]; + if (opts.fillBetween[tempi] != null) { + this.fillBetween[tempi] = opts.fillBetween[tempi]; + } + } + } + + if (opts.seriesColors) { + this.seriesColors = opts.seriesColors; + } + if (opts.negativeSeriesColors) { + this.negativeSeriesColors = opts.negativeSeriesColors; + } + if (opts.captureRightClick) { + this.captureRightClick = opts.captureRightClick; + } + this.defaultAxisStart = (options && options.defaultAxisStart != null) ? options.defaultAxisStart : this.defaultAxisStart; + this.colorGenerator.setColors(this.seriesColors); + this.negativeColorGenerator.setColors(this.negativeSeriesColors); + // var cg = new this.colorGenerator(this.seriesColors); + // var ncg = new this.colorGenerator(this.negativeSeriesColors); + // this._gridPadding = this.options.gridPadding; + $.extend(true, this._gridPadding, opts.gridPadding); + this.sortData = (opts.sortData != null) ? opts.sortData : this.sortData; + for (var i=0; i<12; i++) { + var n = _axisNames[i]; + var axis = this.axes[n]; + axis._options = $.extend(true, {}, opts.axesDefaults, opts.axes[n]); + $.extend(true, axis, opts.axesDefaults, opts.axes[n]); + axis._plotWidth = this._width; + axis._plotHeight = this._height; + } + // if (this.data.length == 0) { + // this.data = []; + // for (var i=0; i<this.options.series.length; i++) { + // this.data.push(this.options.series.data); + // } + // } + + var normalizeData = function(data, dir, start) { + // return data as an array of point arrays, + // in form [[x1,y1...], [x2,y2...], ...] + var temp = []; + var i, l; + dir = dir || 'vertical'; + if (!$.isArray(data[0])) { + // we have a series of scalars. One line with just y values. + // turn the scalar list of data into a data array of form: + // [[1, data[0]], [2, data[1]], ...] + for (i=0, l=data.length; i<l; i++) { + if (dir == 'vertical') { + temp.push([start + i, data[i]]); + } + else { + temp.push([data[i], start+i]); + } + } + } + else { + // we have a properly formatted data series, copy it. + $.extend(true, temp, data); + } + return temp; + }; + + var colorIndex = 0; + this.series = []; + for (var i=0; i<this.data.length; i++) { + var sopts = $.extend(true, {index: i}, {seriesColors:this.seriesColors, negativeSeriesColors:this.negativeSeriesColors}, this.options.seriesDefaults, this.options.series[i], {rendererOptions:{animation:{show: this.animate}}}); + // pass in options in case something needs set prior to initialization. + var temp = new Series(sopts); + for (var j=0; j<$.jqplot.preParseSeriesOptionsHooks.length; j++) { + $.jqplot.preParseSeriesOptionsHooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); + } + for (var j=0; j<this.preParseSeriesOptionsHooks.hooks.length; j++) { + this.preParseSeriesOptionsHooks.hooks[j].call(temp, this.options.seriesDefaults, this.options.series[i]); + } + // Now go back and apply the options to the series. Really should just do this during initializaiton, but don't want to + // mess up preParseSeriesOptionsHooks at this point. + $.extend(true, temp, sopts); + var dir = 'vertical'; + if (temp.renderer === $.jqplot.BarRenderer && temp.rendererOptions && temp.rendererOptions.barDirection == 'horizontal') { + dir = 'horizontal'; + temp._stackAxis = 'x'; + temp._primaryAxis = '_yaxis'; + } + temp.data = normalizeData(this.data[i], dir, this.defaultAxisStart); + switch (temp.xaxis) { + case 'xaxis': + temp._xaxis = this.axes.xaxis; + break; + case 'x2axis': + temp._xaxis = this.axes.x2axis; + break; + default: + break; + } + temp._yaxis = this.axes[temp.yaxis]; + temp._xaxis._series.push(temp); + temp._yaxis._series.push(temp); + if (temp.show) { + temp._xaxis.show = true; + temp._yaxis.show = true; + } + else { + if (temp._xaxis.scaleToHiddenSeries) { + temp._xaxis.show = true; + } + if (temp._yaxis.scaleToHiddenSeries) { + temp._yaxis.show = true; + } + } + + // // parse the renderer options and apply default colors if not provided + // if (!temp.color && temp.show != false) { + // temp.color = cg.next(); + // colorIndex = cg.getIndex() - 1;; + // } + // if (!temp.negativeColor && temp.show != false) { + // temp.negativeColor = ncg.get(colorIndex); + // ncg.setIndex(colorIndex); + // } + if (!temp.label) { + temp.label = 'Series '+ (i+1).toString(); + } + // temp.rendererOptions.show = temp.show; + // $.extend(true, temp.renderer, {color:this.seriesColors[i]}, this.rendererOptions); + this.series.push(temp); + for (var j=0; j<$.jqplot.postParseSeriesOptionsHooks.length; j++) { + $.jqplot.postParseSeriesOptionsHooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); + } + for (var j=0; j<this.postParseSeriesOptionsHooks.hooks.length; j++) { + this.postParseSeriesOptionsHooks.hooks[j].call(this.series[i], this.options.seriesDefaults, this.options.series[i]); + } + } + + // copy the grid and title options into this object. + $.extend(true, this.grid, this.options.grid); + // if axis border properties aren't set, set default. + for (var i=0, l=_axisNames.length; i<l; i++) { + var n = _axisNames[i]; + var axis = this.axes[n]; + if (axis.borderWidth == null) { + axis.borderWidth =this.grid.borderWidth; + } + } + + if (typeof this.options.title == 'string') { + this.title.text = this.options.title; + } + else if (typeof this.options.title == 'object') { + $.extend(true, this.title, this.options.title); + } + this.title._plotWidth = this._width; + this.legend.setOptions(this.options.legend); + + for (var i=0; i<$.jqplot.postParseOptionsHooks.length; i++) { + $.jqplot.postParseOptionsHooks[i].call(this, options); + } + for (var i=0; i<this.postParseOptionsHooks.hooks.length; i++) { + this.postParseOptionsHooks.hooks[i].call(this, options); + } + }; + + // method: destroy + // Releases all resources occupied by the plot + this.destroy = function() { + this.canvasManager.freeAllCanvases(); + if (this.eventCanvas && this.eventCanvas._elem) { + this.eventCanvas._elem.unbind(); + } + // Couple of posts on Stack Overflow indicate that empty() doesn't + // always cear up the dom and release memory. Sometimes setting + // innerHTML property to null is needed. Particularly on IE, may + // have to directly set it to null, bypassing $. + this.target.empty(); + + this.target[0].innerHTML = ''; + }; + + // method: replot + // Does a reinitialization of the plot followed by + // a redraw. Method could be used to interactively + // change plot characteristics and then replot. + // + // Parameters: + // options - Options used for replotting. + // + // Properties: + // clear - false to not clear (empty) the plot container before replotting (default: true). + // resetAxes - true to reset all axes min, max, numberTicks and tickInterval setting so axes will rescale themselves. + // optionally pass in list of axes to reset (e.g. ['xaxis', 'y2axis']) (default: false). + this.replot = function(options) { + var opts = options || {}; + var data = opts.data || null; + var clear = (opts.clear === false) ? false : true; + var resetAxes = opts.resetAxes || false; + delete opts.data; + delete opts.clear; + delete opts.resetAxes; + + this.target.trigger('jqplotPreReplot'); + + if (clear) { + this.destroy(); + } + // if have data or other options, full reinit. + // otherwise, quickinit. + if (data || !$.isEmptyObject(opts)) { + this.reInitialize(data, opts); + } + else { + this.quickInit(); + } + + if (resetAxes) { + this.resetAxesScale(resetAxes, opts.axes); + } + this.draw(); + this.target.trigger('jqplotPostReplot'); + }; + + // method: redraw + // Empties the plot target div and redraws the plot. + // This enables plot data and properties to be changed + // and then to comletely clear the plot and redraw. + // redraw *will not* reinitialize any plot elements. + // That is, axes will not be autoscaled and defaults + // will not be reapplied to any plot elements. redraw + // is used primarily with zooming. + // + // Parameters: + // clear - false to not clear (empty) the plot container before redrawing (default: true). + this.redraw = function(clear) { + clear = (clear != null) ? clear : true; + this.target.trigger('jqplotPreRedraw'); + if (clear) { + this.canvasManager.freeAllCanvases(); + this.eventCanvas._elem.unbind(); + // Dont think I bind any events to the target, this shouldn't be necessary. + // It will remove user's events. + // this.target.unbind(); + this.target.empty(); + } + for (var ax in this.axes) { + this.axes[ax]._ticks = []; + } + this.computePlotData(); + // for (var i=0; i<this.series.length; i++) { + // this.populatePlotData(this.series[i], i); + // } + this._sumy = 0; + this._sumx = 0; + for (var i=0, tsl = this.series.length; i<tsl; i++) { + this._sumy += this.series[i]._sumy; + this._sumx += this.series[i]._sumx; + } + this.draw(); + this.target.trigger('jqplotPostRedraw'); + }; + + // method: draw + // Draws all elements of the plot into the container. + // Does not clear the container before drawing. + this.draw = function(){ + if (this.drawIfHidden || this.target.is(':visible')) { + this.target.trigger('jqplotPreDraw'); + var i, + j, + l, + tempseries; + for (i=0, l=$.jqplot.preDrawHooks.length; i<l; i++) { + $.jqplot.preDrawHooks[i].call(this); + } + for (i=0, l=this.preDrawHooks.hooks.length; i<l; i++) { + this.preDrawHooks.hooks[i].apply(this, this.preDrawSeriesHooks.args[i]); + } + // create an underlying canvas to be used for special features. + this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas', null, this)); + this.baseCanvas.setContext(); + this.target.append(this.title.draw()); + this.title.pack({top:0, left:0}); + + // make room for the legend between the grid and the edge. + // pass a dummy offsets object and a reference to the plot. + var legendElem = this.legend.draw({}, this); + + var gridPadding = {top:0, left:0, bottom:0, right:0}; + + if (this.legend.placement == "outsideGrid") { + // temporarily append the legend to get dimensions + this.target.append(legendElem); + switch (this.legend.location) { + case 'n': + gridPadding.top += this.legend.getHeight(); + break; + case 's': + gridPadding.bottom += this.legend.getHeight(); + break; + case 'ne': + case 'e': + case 'se': + gridPadding.right += this.legend.getWidth(); + break; + case 'nw': + case 'w': + case 'sw': + gridPadding.left += this.legend.getWidth(); + break; + default: // same as 'ne' + gridPadding.right += this.legend.getWidth(); + break; + } + legendElem = legendElem.detach(); + } + + var ax = this.axes; + var name; + // draw the yMidAxis first, so xaxis of pyramid chart can adjust itself if needed. + for (i=0; i<12; i++) { + name = _axisNames[i]; + this.target.append(ax[name].draw(this.baseCanvas._ctx, this)); + ax[name].set(); + } + if (ax.yaxis.show) { + gridPadding.left += ax.yaxis.getWidth(); + } + var ra = ['y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; + var rapad = [0, 0, 0, 0, 0, 0, 0, 0]; + var gpr = 0; + var n; + for (n=0; n<8; n++) { + if (ax[ra[n]].show) { + gpr += ax[ra[n]].getWidth(); + rapad[n] = gpr; + } + } + gridPadding.right += gpr; + if (ax.x2axis.show) { + gridPadding.top += ax.x2axis.getHeight(); + } + if (this.title.show) { + gridPadding.top += this.title.getHeight(); + } + if (ax.xaxis.show) { + gridPadding.bottom += ax.xaxis.getHeight(); + } + + // end of gridPadding adjustments. + + // if user passed in gridDimensions option, check against calculated gridPadding + if (this.options.gridDimensions && $.isPlainObject(this.options.gridDimensions)) { + var gdw = parseInt(this.options.gridDimensions.width, 10) || 0; + var gdh = parseInt(this.options.gridDimensions.height, 10) || 0; + var widthAdj = (this._width - gridPadding.left - gridPadding.right - gdw)/2; + var heightAdj = (this._height - gridPadding.top - gridPadding.bottom - gdh)/2; + + if (heightAdj >= 0 && widthAdj >= 0) { + gridPadding.top += heightAdj; + gridPadding.bottom += heightAdj; + gridPadding.left += widthAdj; + gridPadding.right += widthAdj; + } + } + var arr = ['top', 'bottom', 'left', 'right']; + for (var n in arr) { + if (this._gridPadding[arr[n]] == null && gridPadding[arr[n]] > 0) { + this._gridPadding[arr[n]] = gridPadding[arr[n]]; + } + else if (this._gridPadding[arr[n]] == null) { + this._gridPadding[arr[n]] = this._defaultGridPadding[arr[n]]; + } + } + + var legendPadding = this._gridPadding; + + if (this.legend.placement === 'outsideGrid') { + legendPadding = {top:this.title.getHeight(), left: 0, right: 0, bottom: 0}; + if (this.legend.location === 's') { + legendPadding.left = this._gridPadding.left; + legendPadding.right = this._gridPadding.right; + } + } + + ax.xaxis.pack({position:'absolute', bottom:this._gridPadding.bottom - ax.xaxis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); + ax.yaxis.pack({position:'absolute', top:0, left:this._gridPadding.left - ax.yaxis.getWidth(), height:this._height}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); + ax.x2axis.pack({position:'absolute', top:this._gridPadding.top - ax.x2axis.getHeight(), left:0, width:this._width}, {min:this._gridPadding.left, max:this._width - this._gridPadding.right}); + for (i=8; i>0; i--) { + ax[ra[i-1]].pack({position:'absolute', top:0, right:this._gridPadding.right - rapad[i-1]}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); + } + var ltemp = (this._width - this._gridPadding.left - this._gridPadding.right)/2.0 + this._gridPadding.left - ax.yMidAxis.getWidth()/2.0; + ax.yMidAxis.pack({position:'absolute', top:0, left:ltemp, zIndex:9, textAlign: 'center'}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top}); + + this.target.append(this.grid.createElement(this._gridPadding, this)); + this.grid.draw(); + + var series = this.series; + var seriesLength = series.length; + // put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars. + for (i=0, l=seriesLength; i<l; i++) { + // draw series in order of stacking. This affects only + // order in which canvases are added to dom. + j = this.seriesStack[i]; + this.target.append(series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas', null, this)); + series[j].shadowCanvas.setContext(); + series[j].shadowCanvas._elem.data('seriesIndex', j); + } + + for (i=0, l=seriesLength; i<l; i++) { + // draw series in order of stacking. This affects only + // order in which canvases are added to dom. + j = this.seriesStack[i]; + this.target.append(series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas', null, this)); + series[j].canvas.setContext(); + series[j].canvas._elem.data('seriesIndex', j); + } + // Need to use filled canvas to capture events in IE. + // Also, canvas seems to block selection of other elements in document on FF. + this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this)); + this.eventCanvas.setContext(); + this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)'; + this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height); + + // bind custom event handlers to regular events. + this.bindCustomEvents(); + + // draw legend before series if the series needs to know the legend dimensions. + if (this.legend.preDraw) { + this.eventCanvas._elem.before(legendElem); + this.legend.pack(legendPadding); + if (this.legend._elem) { + this.drawSeries({legendInfo:{location:this.legend.location, placement:this.legend.placement, width:this.legend.getWidth(), height:this.legend.getHeight(), xoffset:this.legend.xoffset, yoffset:this.legend.yoffset}}); + } + else { + this.drawSeries(); + } + } + else { // draw series before legend + this.drawSeries(); + if (seriesLength) { + $(series[seriesLength-1].canvas._elem).after(legendElem); + } + this.legend.pack(legendPadding); + } + + // register event listeners on the overlay canvas + for (var i=0, l=$.jqplot.eventListenerHooks.length; i<l; i++) { + // in the handler, this will refer to the eventCanvas dom element. + // make sure there are references back into plot objects. + this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); + } + + // register event listeners on the overlay canvas + for (var i=0, l=this.eventListenerHooks.hooks.length; i<l; i++) { + // in the handler, this will refer to the eventCanvas dom element. + // make sure there are references back into plot objects. + this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[i][0], {plot:this}, this.eventListenerHooks.hooks[i][1]); + } + + var fb = this.fillBetween; + if (fb.fill && fb.series1 !== fb.series2 && fb.series1 < seriesLength && fb.series2 < seriesLength && series[fb.series1]._type === 'line' && series[fb.series2]._type === 'line') { + this.doFillBetweenLines(); + } + + for (var i=0, l=$.jqplot.postDrawHooks.length; i<l; i++) { + $.jqplot.postDrawHooks[i].call(this); + } + + for (var i=0, l=this.postDrawHooks.hooks.length; i<l; i++) { + this.postDrawHooks.hooks[i].apply(this, this.postDrawHooks.args[i]); + } + + if (this.target.is(':visible')) { + this._drawCount += 1; + } + + var temps, + tempr, + sel, + _els; + // ughh. ideally would hide all series then show them. + for (i=0, l=seriesLength; i<l; i++) { + temps = series[i]; + tempr = temps.renderer; + sel = '.jqplot-point-label.jqplot-series-'+i; + if (tempr.animation && tempr.animation._supported && tempr.animation.show && (this._drawCount < 2 || this.animateReplot)) { + _els = this.target.find(sel); + _els.stop(true, true).hide(); + temps.canvas._elem.stop(true, true).hide(); + temps.shadowCanvas._elem.stop(true, true).hide(); + temps.canvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); + temps.shadowCanvas._elem.jqplotEffect('blind', {mode: 'show', direction: tempr.animation.direction}, tempr.animation.speed); + _els.fadeIn(tempr.animation.speed*0.8); + } + } + _els = null; + + this.target.trigger('jqplotPostDraw', [this]); + } + }; + + jqPlot.prototype.doFillBetweenLines = function () { + var fb = this.fillBetween; + var sid1 = fb.series1; + var sid2 = fb.series2; + // first series should always be lowest index + var id1 = (sid1 < sid2) ? sid1 : sid2; + var id2 = (sid2 > sid1) ? sid2 : sid1; + + var series1 = this.series[id1]; + var series2 = this.series[id2]; + + if (series2.renderer.smooth) { + var tempgd = series2.renderer._smoothedData.slice(0).reverse(); + } + else { + var tempgd = series2.gridData.slice(0).reverse(); + } + + if (series1.renderer.smooth) { + var gd = series1.renderer._smoothedData.concat(tempgd); + } + else { + var gd = series1.gridData.concat(tempgd); + } + + var color = (fb.color !== null) ? fb.color : this.series[sid1].fillColor; + var baseSeries = (fb.baseSeries !== null) ? fb.baseSeries : id1; + + // now apply a fill to the shape on the lower series shadow canvas, + // so it is behind both series. + var sr = this.series[baseSeries].renderer.shapeRenderer; + var opts = {fillStyle: color, fill: true, closePath: true}; + sr.draw(series1.shadowCanvas._ctx, gd, opts); + }; + + this.bindCustomEvents = function() { + this.eventCanvas._elem.bind('click', {plot:this}, this.onClick); + this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); + this.eventCanvas._elem.bind('mousedown', {plot:this}, this.onMouseDown); + this.eventCanvas._elem.bind('mousemove', {plot:this}, this.onMouseMove); + this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); + if (this.captureRightClick) { + this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onRightClick); + this.eventCanvas._elem.get(0).oncontextmenu = function() { + return false; + }; + } + else { + this.eventCanvas._elem.bind('mouseup', {plot:this}, this.onMouseUp); + } + }; + + function getEventPosition(ev) { + var plot = ev.data.plot; + var go = plot.eventCanvas._elem.offset(); + var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; + var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null}; + var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; + var ax = plot.axes; + var n, axis; + for (n=11; n>0; n--) { + axis = an[n-1]; + if (ax[axis].show) { + dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); + } + } + + return {offsets:go, gridPos:gridPos, dataPos:dataPos}; + } + + + // function to check if event location is over a area area + function checkIntersection(gridpos, plot) { + var series = plot.series; + var i, j, k, s, r, x, y, theta, sm, sa, minang, maxang; + var d0, d, p, pp, points, bw, hp; + var threshold, t; + for (k=plot.seriesStack.length-1; k>=0; k--) { + i = plot.seriesStack[k]; + s = series[i]; + hp = s._highlightThreshold; + switch (s.renderer.constructor) { + case $.jqplot.BarRenderer: + x = gridpos.x; + y = gridpos.y; + for (j=0; j<s._barPoints.length; j++) { + points = s._barPoints[j]; + p = s.gridData[j]; + if (x>points[0][0] && x<points[2][0] && y>points[2][1] && y<points[0][1]) { + return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; + } + } + break; + case $.jqplot.PyramidRenderer: + x = gridpos.x; + y = gridpos.y; + for (j=0; j<s._barPoints.length; j++) { + points = s._barPoints[j]; + p = s.gridData[j]; + if (x > points[0][0] + hp[0][0] && x < points[2][0] + hp[2][0] && y > points[2][1] && y < points[0][1]) { + return {seriesIndex:s.index, pointIndex:j, gridData:p, data:s.data[j], points:s._barPoints[j]}; + } + } + break; + + case $.jqplot.DonutRenderer: + sa = s.startAngle/180*Math.PI; + x = gridpos.x - s._center[0]; + y = gridpos.y - s._center[1]; + r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + if (x > 0 && -y >= 0) { + theta = 2*Math.PI - Math.atan(-y/x); + } + else if (x > 0 && -y < 0) { + theta = -Math.atan(-y/x); + } + else if (x < 0) { + theta = Math.PI - Math.atan(-y/x); + } + else if (x == 0 && -y > 0) { + theta = 3*Math.PI/2; + } + else if (x == 0 && -y < 0) { + theta = Math.PI/2; + } + else if (x == 0 && y == 0) { + theta = 0; + } + if (sa) { + theta -= sa; + if (theta < 0) { + theta += 2*Math.PI; + } + else if (theta > 2*Math.PI) { + theta -= 2*Math.PI; + } + } + + sm = s.sliceMargin/180*Math.PI; + if (r < s._radius && r > s._innerRadius) { + for (j=0; j<s.gridData.length; j++) { + minang = (j>0) ? s.gridData[j-1][1]+sm : sm; + maxang = s.gridData[j][1]; + if (theta > minang && theta < maxang) { + return {seriesIndex:s.index, pointIndex:j, gridData:[gridpos.x,gridpos.y], data:s.data[j]}; + } + } + } + break; + + case $.jqplot.PieRenderer: + sa = s.startAngle/180*Math.PI; + x = gridpos.x - s._center[0]; + y = gridpos.y - s._center[1]; + r = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + if (x > 0 && -y >= 0) { + theta = 2*Math.PI - Math.atan(-y/x); + } + else if (x > 0 && -y < 0) { + theta = -Math.atan(-y/x); + } + else if (x < 0) { + theta = Math.PI - Math.atan(-y/x); + } + else if (x == 0 && -y > 0) { + theta = 3*Math.PI/2; + } + else if (x == 0 && -y < 0) { + theta = Math.PI/2; + } + else if (x == 0 && y == 0) { + theta = 0; + } + if (sa) { + theta -= sa; + if (theta < 0) { + theta += 2*Math.PI; + } + else if (theta > 2*Math.PI) { + theta -= 2*Math.PI; + } + } + + sm = s.sliceMargin/180*Math.PI; + if (r < s._radius) { + for (j=0; j<s.gridData.length; j++) { + minang = (j>0) ? s.gridData[j-1][1]+sm : sm; + maxang = s.gridData[j][1]; + if (theta > minang && theta < maxang) { + return {seriesIndex:s.index, pointIndex:j, gridData:[gridpos.x,gridpos.y], data:s.data[j]}; + } + } + } + break; + + case $.jqplot.BubbleRenderer: + x = gridpos.x; + y = gridpos.y; + var ret = null; + + if (s.show) { + for (var j=0; j<s.gridData.length; j++) { + p = s.gridData[j]; + d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); + if (d <= p[2] && (d <= d0 || d0 == null)) { + d0 = d; + ret = {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + if (ret != null) { + return ret; + } + } + break; + + case $.jqplot.FunnelRenderer: + x = gridpos.x; + y = gridpos.y; + var v = s._vertices, + vfirst = v[0], + vlast = v[v.length-1], + lex, + rex, + cv; + + // equations of right and left sides, returns x, y values given height of section (y value and 2 points) + + function findedge (l, p1 , p2) { + var m = (p1[1] - p2[1])/(p1[0] - p2[0]); + var b = p1[1] - m*p1[0]; + var y = l + p1[1]; + + return [(y - b)/m, y]; + } + + // check each section + lex = findedge(y, vfirst[0], vlast[3]); + rex = findedge(y, vfirst[1], vlast[2]); + for (j=0; j<v.length; j++) { + cv = v[j]; + if (y >= cv[0][1] && y <= cv[3][1] && x >= lex[0] && x <= rex[0]) { + return {seriesIndex:s.index, pointIndex:j, gridData:null, data:s.data[j]}; + } + } + break; + + case $.jqplot.LineRenderer: + x = gridpos.x; + y = gridpos.y; + r = s.renderer; + if (s.show) { + if ((s.fill || (s.renderer.bands.show && s.renderer.bands.fill)) && (!plot.plugins.highlighter || !plot.plugins.highlighter.show)) { + // first check if it is in bounding box + var inside = false; + if (x>s._boundingBox[0][0] && x<s._boundingBox[1][0] && y>s._boundingBox[1][1] && y<s._boundingBox[0][1]) { + // now check the crossing number + + var numPoints = s._areaPoints.length; + var ii; + var j = numPoints-1; + + for(var ii=0; ii < numPoints; ii++) { + var vertex1 = [s._areaPoints[ii][0], s._areaPoints[ii][1]]; + var vertex2 = [s._areaPoints[j][0], s._areaPoints[j][1]]; + + if (vertex1[1] < y && vertex2[1] >= y || vertex2[1] < y && vertex1[1] >= y) { + if (vertex1[0] + (y - vertex1[1]) / (vertex2[1] - vertex1[1]) * (vertex2[0] - vertex1[0]) < x) { + inside = !inside; + } + } + + j = ii; + } + } + if (inside) { + return {seriesIndex:i, pointIndex:null, gridData:s.gridData, data:s.data, points:s._areaPoints}; + } + break; + + } + + else { + t = s.markerRenderer.size/2+s.neighborThreshold; + threshold = (t > 0) ? t : 0; + for (var j=0; j<s.gridData.length; j++) { + p = s.gridData[j]; + // neighbor looks different to OHLC chart. + if (r.constructor == $.jqplot.OHLCRenderer) { + if (r.candleStick) { + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + // if an open hi low close chart + else if (!r.hlc){ + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + // a hi low close chart + else { + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + + } + else if (p[0] != null && p[1] != null){ + d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); + if (d <= threshold && (d <= d0 || d0 == null)) { + d0 = d; + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + } + } + } + break; + + default: + x = gridpos.x; + y = gridpos.y; + r = s.renderer; + if (s.show) { + t = s.markerRenderer.size/2+s.neighborThreshold; + threshold = (t > 0) ? t : 0; + for (var j=0; j<s.gridData.length; j++) { + p = s.gridData[j]; + // neighbor looks different to OHLC chart. + if (r.constructor == $.jqplot.OHLCRenderer) { + if (r.candleStick) { + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._bodyWidth/2 && x <= p[0]+r._bodyWidth/2 && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + // if an open hi low close chart + else if (!r.hlc){ + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][2]) && y <= yp(s.data[j][3])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + // a hi low close chart + else { + var yp = s._yaxis.series_u2p; + if (x >= p[0]-r._tickLength && x <= p[0]+r._tickLength && y >= yp(s.data[j][1]) && y <= yp(s.data[j][2])) { + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + + } + else { + d = Math.sqrt( (x-p[0]) * (x-p[0]) + (y-p[1]) * (y-p[1]) ); + if (d <= threshold && (d <= d0 || d0 == null)) { + d0 = d; + return {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}; + } + } + } + } + break; + } + } + + return null; + } + + + + this.onClick = function(ev) { + // Event passed in is normalized and will have data attribute. + // Event passed out is unnormalized. + var positions = getEventPosition(ev); + var p = ev.data.plot; + var neighbor = checkIntersection(positions.gridPos, p); + var evt = $.Event('jqplotClick'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + }; + + this.onDblClick = function(ev) { + // Event passed in is normalized and will have data attribute. + // Event passed out is unnormalized. + var positions = getEventPosition(ev); + var p = ev.data.plot; + var neighbor = checkIntersection(positions.gridPos, p); + var evt = $.Event('jqplotDblClick'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + }; + + this.onMouseDown = function(ev) { + var positions = getEventPosition(ev); + var p = ev.data.plot; + var neighbor = checkIntersection(positions.gridPos, p); + var evt = $.Event('jqplotMouseDown'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + }; + + this.onMouseUp = function(ev) { + var positions = getEventPosition(ev); + var evt = $.Event('jqplotMouseUp'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, ev.data.plot]); + }; + + this.onRightClick = function(ev) { + var positions = getEventPosition(ev); + var p = ev.data.plot; + var neighbor = checkIntersection(positions.gridPos, p); + if (p.captureRightClick) { + if (ev.which == 3) { + var evt = $.Event('jqplotRightClick'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + } + else { + var evt = $.Event('jqplotMouseUp'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + } + } + }; + + this.onMouseMove = function(ev) { + var positions = getEventPosition(ev); + var p = ev.data.plot; + var neighbor = checkIntersection(positions.gridPos, p); + var evt = $.Event('jqplotMouseMove'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, neighbor, p]); + }; + + this.onMouseEnter = function(ev) { + var positions = getEventPosition(ev); + var p = ev.data.plot; + var evt = $.Event('jqplotMouseEnter'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + evt.relatedTarget = ev.relatedTarget; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); + }; + + this.onMouseLeave = function(ev) { + var positions = getEventPosition(ev); + var p = ev.data.plot; + var evt = $.Event('jqplotMouseLeave'); + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + evt.relatedTarget = ev.relatedTarget; + $(this).trigger(evt, [positions.gridPos, positions.dataPos, null, p]); + }; + + // method: drawSeries + // Redraws all or just one series on the plot. No axis scaling + // is performed and no other elements on the plot are redrawn. + // options is an options object to pass on to the series renderers. + // It can be an empty object {}. idx is the series index + // to redraw if only one series is to be redrawn. + this.drawSeries = function(options, idx){ + var i, series, ctx; + // if only one argument passed in and it is a number, use it ad idx. + idx = (typeof(options) === "number" && idx == null) ? options : idx; + options = (typeof(options) === "object") ? options : {}; + // draw specified series + if (idx != undefined) { + series = this.series[idx]; + ctx = series.shadowCanvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + series.drawShadow(ctx, options, this); + ctx = series.canvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + series.draw(ctx, options, this); + if (series.renderer.constructor == $.jqplot.BezierCurveRenderer) { + if (idx < this.series.length - 1) { + this.drawSeries(idx+1); + } + } + } + + else { + // if call series drawShadow method first, in case all series shadows + // should be drawn before any series. This will ensure, like for + // stacked bar plots, that shadows don't overlap series. + for (i=0; i<this.series.length; i++) { + // first clear the canvas + series = this.series[i]; + ctx = series.shadowCanvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + series.drawShadow(ctx, options, this); + ctx = series.canvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + series.draw(ctx, options, this); + } + } + options = idx = i = series = ctx = null; + }; + + // method: moveSeriesToFront + // This method requires jQuery 1.4+ + // Moves the specified series canvas in front of all other series canvases. + // This effectively "draws" the specified series on top of all other series, + // although it is performed through DOM manipulation, no redrawing is performed. + // + // Parameters: + // idx - 0 based index of the series to move. This will be the index of the series + // as it was first passed into the jqplot function. + this.moveSeriesToFront = function (idx) { + idx = parseInt(idx, 10); + var stackIndex = $.inArray(idx, this.seriesStack); + // if already in front, return + if (stackIndex == -1) { + return; + } + if (stackIndex == this.seriesStack.length -1) { + this.previousSeriesStack = this.seriesStack.slice(0); + return; + } + var opidx = this.seriesStack[this.seriesStack.length -1]; + var serelem = this.series[idx].canvas._elem.detach(); + var shadelem = this.series[idx].shadowCanvas._elem.detach(); + this.series[opidx].shadowCanvas._elem.after(shadelem); + this.series[opidx].canvas._elem.after(serelem); + this.previousSeriesStack = this.seriesStack.slice(0); + this.seriesStack.splice(stackIndex, 1); + this.seriesStack.push(idx); + }; + + // method: moveSeriesToBack + // This method requires jQuery 1.4+ + // Moves the specified series canvas behind all other series canvases. + // + // Parameters: + // idx - 0 based index of the series to move. This will be the index of the series + // as it was first passed into the jqplot function. + this.moveSeriesToBack = function (idx) { + idx = parseInt(idx, 10); + var stackIndex = $.inArray(idx, this.seriesStack); + // if already in back, return + if (stackIndex == 0 || stackIndex == -1) { + return; + } + var opidx = this.seriesStack[0]; + var serelem = this.series[idx].canvas._elem.detach(); + var shadelem = this.series[idx].shadowCanvas._elem.detach(); + this.series[opidx].shadowCanvas._elem.before(shadelem); + this.series[opidx].canvas._elem.before(serelem); + this.previousSeriesStack = this.seriesStack.slice(0); + this.seriesStack.splice(stackIndex, 1); + this.seriesStack.unshift(idx); + }; + + // method: restorePreviousSeriesOrder + // This method requires jQuery 1.4+ + // Restore the series canvas order to its previous state. + // Useful to put a series back where it belongs after moving + // it to the front. + this.restorePreviousSeriesOrder = function () { + var i, j, serelem, shadelem, temp, move, keep; + // if no change, return. + if (this.seriesStack == this.previousSeriesStack) { + return; + } + for (i=1; i<this.previousSeriesStack.length; i++) { + move = this.previousSeriesStack[i]; + keep = this.previousSeriesStack[i-1]; + serelem = this.series[move].canvas._elem.detach(); + shadelem = this.series[move].shadowCanvas._elem.detach(); + this.series[keep].shadowCanvas._elem.after(shadelem); + this.series[keep].canvas._elem.after(serelem); + } + temp = this.seriesStack.slice(0); + this.seriesStack = this.previousSeriesStack.slice(0); + this.previousSeriesStack = temp; + }; + + // method: restoreOriginalSeriesOrder + // This method requires jQuery 1.4+ + // Restore the series canvas order to its original order + // when the plot was created. + this.restoreOriginalSeriesOrder = function () { + var i, j, arr=[], serelem, shadelem; + for (i=0; i<this.series.length; i++) { + arr.push(i); + } + if (this.seriesStack == arr) { + return; + } + this.previousSeriesStack = this.seriesStack.slice(0); + this.seriesStack = arr; + for (i=1; i<this.seriesStack.length; i++) { + serelem = this.series[i].canvas._elem.detach(); + shadelem = this.series[i].shadowCanvas._elem.detach(); + this.series[i-1].shadowCanvas._elem.after(shadelem); + this.series[i-1].canvas._elem.after(serelem); + } + }; + + this.activateTheme = function (name) { + this.themeEngine.activate(this, name); + }; + } + + + // conpute a highlight color or array of highlight colors from given colors. + $.jqplot.computeHighlightColors = function(colors) { + var ret; + if ($.isArray(colors)) { + ret = []; + for (var i=0; i<colors.length; i++){ + var rgba = $.jqplot.getColorComponents(colors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; + newrgb[j] = parseInt(newrgb[j], 10); + (newrgb[j] > 255) ? 255 : newrgb[j]; + } + // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; + // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; + newrgb[3] = 0.3 + 0.35 * rgba[3]; + ret.push('rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'); + } + } + else { + var rgba = $.jqplot.getColorComponents(colors); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + // newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + // newrgb[j] = parseInt(newrgb[j], 10); + newrgb[j] = (sum > 660) ? newrgb[j] * 0.85 : 0.73 * newrgb[j] + 90; + newrgb[j] = parseInt(newrgb[j], 10); + (newrgb[j] > 255) ? 255 : newrgb[j]; + } + // newrgb[3] = (rgba[3] > 0.4) ? rgba[3] * 0.4 : rgba[3] * 1.5; + // newrgb[3] = (rgba[3] > 0.5) ? 0.8 * rgba[3] - .1 : rgba[3] + 0.2; + newrgb[3] = 0.3 + 0.35 * rgba[3]; + ret = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+newrgb[3]+')'; + } + return ret; + }; + + $.jqplot.ColorGenerator = function(colors) { + colors = colors || $.jqplot.config.defaultColors; + var idx = 0; + + this.next = function () { + if (idx < colors.length) { + return colors[idx++]; + } + else { + idx = 0; + return colors[idx++]; + } + }; + + this.previous = function () { + if (idx > 0) { + return colors[idx--]; + } + else { + idx = colors.length-1; + return colors[idx]; + } + }; + + // get a color by index without advancing pointer. + this.get = function(i) { + var idx = i - colors.length * Math.floor(i/colors.length); + return colors[idx]; + }; + + this.setColors = function(c) { + colors = c; + }; + + this.reset = function() { + idx = 0; + }; + + this.getIndex = function() { + return idx; + }; + + this.setIndex = function(index) { + idx = index; + }; + }; + + // convert a hex color string to rgb string. + // h - 3 or 6 character hex string, with or without leading # + // a - optional alpha + $.jqplot.hex2rgb = function(h, a) { + h = h.replace('#', ''); + if (h.length == 3) { + h = h.charAt(0)+h.charAt(0)+h.charAt(1)+h.charAt(1)+h.charAt(2)+h.charAt(2); + } + var rgb; + rgb = 'rgba('+parseInt(h.slice(0,2), 16)+', '+parseInt(h.slice(2,4), 16)+', '+parseInt(h.slice(4,6), 16); + if (a) { + rgb += ', '+a; + } + rgb += ')'; + return rgb; + }; + + // convert an rgb color spec to a hex spec. ignore any alpha specification. + $.jqplot.rgb2hex = function(s) { + var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/; + var m = s.match(pat); + var h = '#'; + for (var i=1; i<4; i++) { + var temp; + if (m[i].search(/%/) != -1) { + temp = parseInt(255*m[i]/100, 10).toString(16); + if (temp.length == 1) { + temp = '0'+temp; + } + } + else { + temp = parseInt(m[i], 10).toString(16); + if (temp.length == 1) { + temp = '0'+temp; + } + } + h += temp; + } + return h; + }; + + // given a css color spec, return an rgb css color spec + $.jqplot.normalize2rgb = function(s, a) { + if (s.search(/^ *rgba?\(/) != -1) { + return s; + } + else if (s.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/) != -1) { + return $.jqplot.hex2rgb(s, a); + } + else { + throw new Error('Invalid color spec'); + } + }; + + // extract the r, g, b, a color components out of a css color spec. + $.jqplot.getColorComponents = function(s) { + // check to see if a color keyword. + s = $.jqplot.colorKeywordMap[s] || s; + var rgb = $.jqplot.normalize2rgb(s); + var pat = /rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/; + var m = rgb.match(pat); + var ret = []; + for (var i=1; i<4; i++) { + if (m[i].search(/%/) != -1) { + ret[i-1] = parseInt(255*m[i]/100, 10); + } + else { + ret[i-1] = parseInt(m[i], 10); + } + } + ret[3] = parseFloat(m[4]) ? parseFloat(m[4]) : 1.0; + return ret; + }; + + $.jqplot.colorKeywordMap = { + aliceblue: 'rgb(240, 248, 255)', + antiquewhite: 'rgb(250, 235, 215)', + aqua: 'rgb( 0, 255, 255)', + aquamarine: 'rgb(127, 255, 212)', + azure: 'rgb(240, 255, 255)', + beige: 'rgb(245, 245, 220)', + bisque: 'rgb(255, 228, 196)', + black: 'rgb( 0, 0, 0)', + blanchedalmond: 'rgb(255, 235, 205)', + blue: 'rgb( 0, 0, 255)', + blueviolet: 'rgb(138, 43, 226)', + brown: 'rgb(165, 42, 42)', + burlywood: 'rgb(222, 184, 135)', + cadetblue: 'rgb( 95, 158, 160)', + chartreuse: 'rgb(127, 255, 0)', + chocolate: 'rgb(210, 105, 30)', + coral: 'rgb(255, 127, 80)', + cornflowerblue: 'rgb(100, 149, 237)', + cornsilk: 'rgb(255, 248, 220)', + crimson: 'rgb(220, 20, 60)', + cyan: 'rgb( 0, 255, 255)', + darkblue: 'rgb( 0, 0, 139)', + darkcyan: 'rgb( 0, 139, 139)', + darkgoldenrod: 'rgb(184, 134, 11)', + darkgray: 'rgb(169, 169, 169)', + darkgreen: 'rgb( 0, 100, 0)', + darkgrey: 'rgb(169, 169, 169)', + darkkhaki: 'rgb(189, 183, 107)', + darkmagenta: 'rgb(139, 0, 139)', + darkolivegreen: 'rgb( 85, 107, 47)', + darkorange: 'rgb(255, 140, 0)', + darkorchid: 'rgb(153, 50, 204)', + darkred: 'rgb(139, 0, 0)', + darksalmon: 'rgb(233, 150, 122)', + darkseagreen: 'rgb(143, 188, 143)', + darkslateblue: 'rgb( 72, 61, 139)', + darkslategray: 'rgb( 47, 79, 79)', + darkslategrey: 'rgb( 47, 79, 79)', + darkturquoise: 'rgb( 0, 206, 209)', + darkviolet: 'rgb(148, 0, 211)', + deeppink: 'rgb(255, 20, 147)', + deepskyblue: 'rgb( 0, 191, 255)', + dimgray: 'rgb(105, 105, 105)', + dimgrey: 'rgb(105, 105, 105)', + dodgerblue: 'rgb( 30, 144, 255)', + firebrick: 'rgb(178, 34, 34)', + floralwhite: 'rgb(255, 250, 240)', + forestgreen: 'rgb( 34, 139, 34)', + fuchsia: 'rgb(255, 0, 255)', + gainsboro: 'rgb(220, 220, 220)', + ghostwhite: 'rgb(248, 248, 255)', + gold: 'rgb(255, 215, 0)', + goldenrod: 'rgb(218, 165, 32)', + gray: 'rgb(128, 128, 128)', + grey: 'rgb(128, 128, 128)', + green: 'rgb( 0, 128, 0)', + greenyellow: 'rgb(173, 255, 47)', + honeydew: 'rgb(240, 255, 240)', + hotpink: 'rgb(255, 105, 180)', + indianred: 'rgb(205, 92, 92)', + indigo: 'rgb( 75, 0, 130)', + ivory: 'rgb(255, 255, 240)', + khaki: 'rgb(240, 230, 140)', + lavender: 'rgb(230, 230, 250)', + lavenderblush: 'rgb(255, 240, 245)', + lawngreen: 'rgb(124, 252, 0)', + lemonchiffon: 'rgb(255, 250, 205)', + lightblue: 'rgb(173, 216, 230)', + lightcoral: 'rgb(240, 128, 128)', + lightcyan: 'rgb(224, 255, 255)', + lightgoldenrodyellow: 'rgb(250, 250, 210)', + lightgray: 'rgb(211, 211, 211)', + lightgreen: 'rgb(144, 238, 144)', + lightgrey: 'rgb(211, 211, 211)', + lightpink: 'rgb(255, 182, 193)', + lightsalmon: 'rgb(255, 160, 122)', + lightseagreen: 'rgb( 32, 178, 170)', + lightskyblue: 'rgb(135, 206, 250)', + lightslategray: 'rgb(119, 136, 153)', + lightslategrey: 'rgb(119, 136, 153)', + lightsteelblue: 'rgb(176, 196, 222)', + lightyellow: 'rgb(255, 255, 224)', + lime: 'rgb( 0, 255, 0)', + limegreen: 'rgb( 50, 205, 50)', + linen: 'rgb(250, 240, 230)', + magenta: 'rgb(255, 0, 255)', + maroon: 'rgb(128, 0, 0)', + mediumaquamarine: 'rgb(102, 205, 170)', + mediumblue: 'rgb( 0, 0, 205)', + mediumorchid: 'rgb(186, 85, 211)', + mediumpurple: 'rgb(147, 112, 219)', + mediumseagreen: 'rgb( 60, 179, 113)', + mediumslateblue: 'rgb(123, 104, 238)', + mediumspringgreen: 'rgb( 0, 250, 154)', + mediumturquoise: 'rgb( 72, 209, 204)', + mediumvioletred: 'rgb(199, 21, 133)', + midnightblue: 'rgb( 25, 25, 112)', + mintcream: 'rgb(245, 255, 250)', + mistyrose: 'rgb(255, 228, 225)', + moccasin: 'rgb(255, 228, 181)', + navajowhite: 'rgb(255, 222, 173)', + navy: 'rgb( 0, 0, 128)', + oldlace: 'rgb(253, 245, 230)', + olive: 'rgb(128, 128, 0)', + olivedrab: 'rgb(107, 142, 35)', + orange: 'rgb(255, 165, 0)', + orangered: 'rgb(255, 69, 0)', + orchid: 'rgb(218, 112, 214)', + palegoldenrod: 'rgb(238, 232, 170)', + palegreen: 'rgb(152, 251, 152)', + paleturquoise: 'rgb(175, 238, 238)', + palevioletred: 'rgb(219, 112, 147)', + papayawhip: 'rgb(255, 239, 213)', + peachpuff: 'rgb(255, 218, 185)', + peru: 'rgb(205, 133, 63)', + pink: 'rgb(255, 192, 203)', + plum: 'rgb(221, 160, 221)', + powderblue: 'rgb(176, 224, 230)', + purple: 'rgb(128, 0, 128)', + red: 'rgb(255, 0, 0)', + rosybrown: 'rgb(188, 143, 143)', + royalblue: 'rgb( 65, 105, 225)', + saddlebrown: 'rgb(139, 69, 19)', + salmon: 'rgb(250, 128, 114)', + sandybrown: 'rgb(244, 164, 96)', + seagreen: 'rgb( 46, 139, 87)', + seashell: 'rgb(255, 245, 238)', + sienna: 'rgb(160, 82, 45)', + silver: 'rgb(192, 192, 192)', + skyblue: 'rgb(135, 206, 235)', + slateblue: 'rgb(106, 90, 205)', + slategray: 'rgb(112, 128, 144)', + slategrey: 'rgb(112, 128, 144)', + snow: 'rgb(255, 250, 250)', + springgreen: 'rgb( 0, 255, 127)', + steelblue: 'rgb( 70, 130, 180)', + tan: 'rgb(210, 180, 140)', + teal: 'rgb( 0, 128, 128)', + thistle: 'rgb(216, 191, 216)', + tomato: 'rgb(255, 99, 71)', + turquoise: 'rgb( 64, 224, 208)', + violet: 'rgb(238, 130, 238)', + wheat: 'rgb(245, 222, 179)', + white: 'rgb(255, 255, 255)', + whitesmoke: 'rgb(245, 245, 245)', + yellow: 'rgb(255, 255, 0)', + yellowgreen: 'rgb(154, 205, 50)' + }; + + + + + // class: $.jqplot.AxisLabelRenderer + // Renderer to place labels on the axes. + $.jqplot.AxisLabelRenderer = function(options) { + // Group: Properties + $.jqplot.ElemContainer.call(this); + // name of the axis associated with this tick + this.axis; + // prop: show + // whether or not to show the tick (mark and label). + this.show = true; + // prop: label + // The text or html for the label. + this.label = ''; + this.fontFamily = null; + this.fontSize = null; + this.textColor = null; + this._elem; + // prop: escapeHTML + // true to escape HTML entities in the label. + this.escapeHTML = false; + + $.extend(true, this, options); + }; + + $.jqplot.AxisLabelRenderer.prototype = new $.jqplot.ElemContainer(); + $.jqplot.AxisLabelRenderer.prototype.constructor = $.jqplot.AxisLabelRenderer; + + $.jqplot.AxisLabelRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + $.jqplot.AxisLabelRenderer.prototype.draw = function(ctx, plot) { + // Memory Leaks patch + if (this._elem) { + this._elem.emptyForce(); + this._elem = null; + } + + this._elem = $('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>'); + + if (Number(this.label)) { + this._elem.css('white-space', 'nowrap'); + } + + if (!this.escapeHTML) { + this._elem.html(this.label); + } + else { + this._elem.text(this.label); + } + if (this.fontFamily) { + this._elem.css('font-family', this.fontFamily); + } + if (this.fontSize) { + this._elem.css('font-size', this.fontSize); + } + if (this.textColor) { + this._elem.css('color', this.textColor); + } + + return this._elem; + }; + + $.jqplot.AxisLabelRenderer.prototype.pack = function() { + }; + + // class: $.jqplot.AxisTickRenderer + // A "tick" object showing the value of a tick/gridline on the plot. + $.jqplot.AxisTickRenderer = function(options) { + // Group: Properties + $.jqplot.ElemContainer.call(this); + // prop: mark + // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. + this.mark = 'outside'; + // name of the axis associated with this tick + this.axis; + // prop: showMark + // whether or not to show the mark on the axis. + this.showMark = true; + // prop: showGridline + // whether or not to draw the gridline on the grid at this tick. + this.showGridline = true; + // prop: isMinorTick + // if this is a minor tick. + this.isMinorTick = false; + // prop: size + // Length of the tick beyond the grid in pixels. + // DEPRECATED: This has been superceeded by markSize + this.size = 4; + // prop: markSize + // Length of the tick marks in pixels. For 'cross' style, length + // will be stoked above and below axis, so total length will be twice this. + this.markSize = 6; + // prop: show + // whether or not to show the tick (mark and label). + // Setting this to false requires more testing. It is recommended + // to set showLabel and showMark to false instead. + this.show = true; + // prop: showLabel + // whether or not to show the label. + this.showLabel = true; + this.label = null; + this.value = null; + this._styles = {}; + // prop: formatter + // A class of a formatter for the tick text. sprintf by default. + this.formatter = $.jqplot.DefaultTickFormatter; + // prop: prefix + // String to prepend to the tick label. + // Prefix is prepended to the formatted tick label. + this.prefix = ''; + // prop: suffix + // String to append to the tick label. + // Suffix is appended to the formatted tick label. + this.suffix = ''; + // prop: formatString + // string passed to the formatter. + this.formatString = ''; + // prop: fontFamily + // css spec for the font-family css attribute. + this.fontFamily; + // prop: fontSize + // css spec for the font-size css attribute. + this.fontSize; + // prop: textColor + // css spec for the color attribute. + this.textColor; + // prop: escapeHTML + // true to escape HTML entities in the label. + this.escapeHTML = false; + this._elem; + this._breakTick = false; + + $.extend(true, this, options); + }; + + $.jqplot.AxisTickRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + $.jqplot.AxisTickRenderer.prototype = new $.jqplot.ElemContainer(); + $.jqplot.AxisTickRenderer.prototype.constructor = $.jqplot.AxisTickRenderer; + + $.jqplot.AxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { + this.value = value; + this.axis = axisName; + if (isMinor) { + this.isMinorTick = true; + } + return this; + }; + + $.jqplot.AxisTickRenderer.prototype.draw = function() { + if (this.label === null) { + this.label = this.prefix + this.formatter(this.formatString, this.value) + this.suffix; + } + var style = {position: 'absolute'}; + if (Number(this.label)) { + style['whitSpace'] = 'nowrap'; + } + + // Memory Leaks patch + if (this._elem) { + this._elem.emptyForce(); + this._elem = null; + } + + this._elem = $(document.createElement('div')); + this._elem.addClass("jqplot-"+this.axis+"-tick"); + + if (!this.escapeHTML) { + this._elem.html(this.label); + } + else { + this._elem.text(this.label); + } + + this._elem.css(style); + + for (var s in this._styles) { + this._elem.css(s, this._styles[s]); + } + if (this.fontFamily) { + this._elem.css('font-family', this.fontFamily); + } + if (this.fontSize) { + this._elem.css('font-size', this.fontSize); + } + if (this.textColor) { + this._elem.css('color', this.textColor); + } + if (this._breakTick) { + this._elem.addClass('jqplot-breakTick'); + } + + return this._elem; + }; + + $.jqplot.DefaultTickFormatter = function (format, val) { + if (typeof val == 'number') { + if (!format) { + format = $.jqplot.config.defaultTickFormatString; + } + return $.jqplot.sprintf(format, val); + } + else { + return String(val); + } + }; + + $.jqplot.PercentTickFormatter = function (format, val) { + if (typeof val == 'number') { + val = 100 * val; + if (!format) { + format = $.jqplot.config.defaultTickFormatString; + } + return $.jqplot.sprintf(format, val); + } + else { + return String(val); + } + }; + + $.jqplot.AxisTickRenderer.prototype.pack = function() { + }; + + // Class: $.jqplot.CanvasGridRenderer + // The default jqPlot grid renderer, creating a grid on a canvas element. + // The renderer has no additional options beyond the <Grid> class. + $.jqplot.CanvasGridRenderer = function(){ + this.shadowRenderer = new $.jqplot.ShadowRenderer(); + }; + + // called with context of Grid object + $.jqplot.CanvasGridRenderer.prototype.init = function(options) { + this._ctx; + $.extend(true, this, options); + // set the shadow renderer options + var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; + this.renderer.shadowRenderer.init(sopts); + }; + + // called with context of Grid. + $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) { + var elem; + // Memory Leaks patch + if (this._elem) { + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + elem = this._elem.get(0); + window.G_vmlCanvasManager.uninitElement(elem); + elem = null; + } + + this._elem.emptyForce(); + this._elem = null; + } + + elem = plot.canvasManager.getCanvas(); + + var w = this._plotDimensions.width; + var h = this._plotDimensions.height; + elem.width = w; + elem.height = h; + this._elem = $(elem); + this._elem.addClass('jqplot-grid-canvas'); + this._elem.css({ position: 'absolute', left: 0, top: 0 }); + + elem = plot.canvasManager.initCanvas(elem); + + this._top = this._offsets.top; + this._bottom = h - this._offsets.bottom; + this._left = this._offsets.left; + this._right = w - this._offsets.right; + this._width = this._right - this._left; + this._height = this._bottom - this._top; + // avoid memory leak + elem = null; + return this._elem; + }; + + $.jqplot.CanvasGridRenderer.prototype.draw = function() { + this._ctx = this._elem.get(0).getContext("2d"); + var ctx = this._ctx; + var axes = this._axes; + // Add the grid onto the grid canvas. This is the bottom most layer. + ctx.save(); + ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); + ctx.fillStyle = this.backgroundColor || this.background; + ctx.fillRect(this._left, this._top, this._width, this._height); + + ctx.save(); + ctx.lineJoin = 'miter'; + ctx.lineCap = 'butt'; + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + var b, e, s, m; + var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis']; + for (var i=4; i>0; i--) { + var name = ax[i-1]; + var axis = axes[name]; + var ticks = axis._ticks; + var numticks = ticks.length; + if (axis.show) { + if (axis.drawBaseline) { + var bopts = {}; + if (axis.baselineWidth !== null) { + bopts.lineWidth = axis.baselineWidth; + } + if (axis.baselineColor !== null) { + bopts.strokeStyle = axis.baselineColor; + } + switch (name) { + case 'xaxis': + drawLine (this._left, this._bottom, this._right, this._bottom, bopts); + break; + case 'yaxis': + drawLine (this._left, this._bottom, this._left, this._top, bopts); + break; + case 'x2axis': + drawLine (this._left, this._bottom, this._right, this._bottom, bopts); + break; + case 'y2axis': + drawLine (this._right, this._bottom, this._right, this._top, bopts); + break; + } + } + for (var j=numticks; j>0; j--) { + var t = ticks[j-1]; + if (t.show) { + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (name) { + case 'xaxis': + // draw the grid line if we should + if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { + drawLine(pos, this._top, pos, this._bottom); + } + // draw the mark + if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._bottom; + e = this._bottom+s; + break; + case 'inside': + b = this._bottom-s; + e = this._bottom; + break; + case 'cross': + b = this._bottom-s; + e = this._bottom+s; + break; + default: + b = this._bottom; + e = this._bottom+s; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); + } + // draw the line + drawLine(pos, b, pos, e); + } + break; + case 'yaxis': + // draw the grid line + if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { + drawLine(this._right, pos, this._left, pos); + } + // draw the mark + if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._left-s; + e = this._left; + break; + case 'inside': + b = this._left; + e = this._left+s; + break; + case 'cross': + b = this._left-s; + e = this._left+s; + break; + default: + b = this._left-s; + e = this._left; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + break; + case 'x2axis': + // draw the grid line + if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { + drawLine(pos, this._bottom, pos, this._top); + } + // draw the mark + if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._top-s; + e = this._top; + break; + case 'inside': + b = this._top; + e = this._top+s; + break; + case 'cross': + b = this._top-s; + e = this._top+s; + break; + default: + b = this._top-s; + e = this._top; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); + } + drawLine(pos, b, pos, e); + } + break; + case 'y2axis': + // draw the grid line + if (t.showGridline && this.drawGridlines && ((!t.isMinorTick && axis.drawMajorGridlines) || (t.isMinorTick && axis.drawMinorGridlines)) ) { + drawLine(this._left, pos, this._right, pos); + } + // draw the mark + if (t.showMark && t.mark && ((!t.isMinorTick && axis.drawMajorTickMarks) || (t.isMinorTick && axis.drawMinorTickMarks)) ) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._right; + e = this._right+s; + break; + case 'inside': + b = this._right-s; + e = this._right; + break; + case 'cross': + b = this._right-s; + e = this._right+s; + break; + default: + b = this._right; + e = this._right+s; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + break; + default: + break; + } + } + } + t = null; + } + axis = null; + ticks = null; + } + // Now draw grid lines for additional y axes + ////// + // TO DO: handle yMidAxis + ////// + ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; + for (var i=7; i>0; i--) { + var axis = axes[ax[i-1]]; + var ticks = axis._ticks; + if (axis.show) { + var tn = ticks[axis.numberTicks-1]; + var t0 = ticks[0]; + var left = axis.getLeft(); + var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]]; + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false}); + } + // draw the line + drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth}); + // draw the tick marks + for (var j=ticks.length; j>0; j--) { + var t = ticks[j-1]; + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + if (t.showMark && t.mark) { + switch (m) { + case 'outside': + b = left; + e = left+s; + break; + case 'inside': + b = left-s; + e = left; + break; + case 'cross': + b = left-s; + e = left+s; + break; + default: + b = left; + e = left+s; + break; + } + points = [[b,pos], [e,pos]]; + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + // draw the line + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + t = null; + } + t0 = null; + } + axis = null; + ticks = null; + } + + ctx.restore(); + + function drawLine(bx, by, ex, ey, opts) { + ctx.save(); + opts = opts || {}; + if (opts.lineWidth == null || opts.lineWidth != 0){ + $.extend(true, ctx, opts); + ctx.beginPath(); + ctx.moveTo(bx, by); + ctx.lineTo(ex, ey); + ctx.stroke(); + ctx.restore(); + } + } + + if (this.shadow) { + var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; + this.renderer.shadowRenderer.draw(ctx, points); + } + // Now draw border around grid. Use axis border definitions. start at + // upper left and go clockwise. + if (this.borderWidth != 0 && this.drawBorder) { + drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); + drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); + drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); + drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); + } + // ctx.lineWidth = this.borderWidth; + // ctx.strokeStyle = this.borderColor; + // ctx.strokeRect(this._left, this._top, this._width, this._height); + + ctx.restore(); + ctx = null; + axes = null; + }; + + // Class: $.jqplot.DivTitleRenderer + // The default title renderer for jqPlot. This class has no options beyond the <Title> class. + $.jqplot.DivTitleRenderer = function() { + }; + + $.jqplot.DivTitleRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + $.jqplot.DivTitleRenderer.prototype.draw = function() { + // Memory Leaks patch + if (this._elem) { + this._elem.emptyForce(); + this._elem = null; + } + + var r = this.renderer; + var elem = document.createElement('div'); + this._elem = $(elem); + this._elem.addClass('jqplot-title'); + + if (!this.text) { + this.show = false; + this._elem.height(0); + this._elem.width(0); + } + else if (this.text) { + var color; + if (this.color) { + color = this.color; + } + else if (this.textColor) { + color = this.textColor; + } + + // don't trust that a stylesheet is present, set the position. + var styles = {position:'absolute', top:'0px', left:'0px'}; + + if (this._plotWidth) { + styles['width'] = this._plotWidth+'px'; + } + if (this.fontSize) { + styles['fontSize'] = this.fontSize; + } + if (typeof this.textAlign === 'string') { + styles['textAlign'] = this.textAlign; + } + else { + styles['textAlign'] = 'center'; + } + if (color) { + styles['color'] = color; + } + if (this.paddingBottom) { + styles['paddingBottom'] = this.paddingBottom; + } + if (this.fontFamily) { + styles['fontFamily'] = this.fontFamily; + } + + this._elem.css(styles); + if (this.escapeHtml) { + this._elem.text(this.text); + } + else { + this._elem.html(this.text); + } + + + // styletext += (this._plotWidth) ? 'width:'+this._plotWidth+'px;' : ''; + // styletext += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + // styletext += (this.textAlign) ? 'text-align:'+this.textAlign+';' : 'text-align:center;'; + // styletext += (color) ? 'color:'+color+';' : ''; + // styletext += (this.paddingBottom) ? 'padding-bottom:'+this.paddingBottom+';' : ''; + // this._elem = $('<div class="jqplot-title" style="'+styletext+'">'+this.text+'</div>'); + // if (this.fontFamily) { + // this._elem.css('font-family', this.fontFamily); + // } + } + + elem = null; + + return this._elem; + }; + + $.jqplot.DivTitleRenderer.prototype.pack = function() { + // nothing to do here + }; + + + var dotlen = 0.1; + + $.jqplot.LinePattern = function (ctx, pattern) { + + var defaultLinePatterns = { + dotted: [ dotlen, $.jqplot.config.dotGapLength ], + dashed: [ $.jqplot.config.dashLength, $.jqplot.config.gapLength ], + solid: null + }; + + if (typeof pattern === 'string') { + if (pattern[0] === '.' || pattern[0] === '-') { + var s = pattern; + pattern = []; + for (var i=0, imax=s.length; i<imax; i++) { + if (s[i] === '.') { + pattern.push( dotlen ); + } + else if (s[i] === '-') { + pattern.push( $.jqplot.config.dashLength ); + } + else { + continue; + } + pattern.push( $.jqplot.config.gapLength ); + } + } + else { + pattern = defaultLinePatterns[pattern]; + } + } + + if (!(pattern && pattern.length)) { + return ctx; + } + + var patternIndex = 0; + var patternDistance = pattern[0]; + var px = 0; + var py = 0; + var pathx0 = 0; + var pathy0 = 0; + + var moveTo = function (x, y) { + ctx.moveTo( x, y ); + px = x; + py = y; + pathx0 = x; + pathy0 = y; + }; + + var lineTo = function (x, y) { + var scale = ctx.lineWidth; + var dx = x - px; + var dy = y - py; + var dist = Math.sqrt(dx*dx+dy*dy); + if ((dist > 0) && (scale > 0)) { + dx /= dist; + dy /= dist; + while (true) { + var dp = scale * patternDistance; + if (dp < dist) { + px += dp * dx; + py += dp * dy; + if ((patternIndex & 1) == 0) { + ctx.lineTo( px, py ); + } + else { + ctx.moveTo( px, py ); + } + dist -= dp; + patternIndex++; + if (patternIndex >= pattern.length) { + patternIndex = 0; + } + patternDistance = pattern[patternIndex]; + } + else { + px = x; + py = y; + if ((patternIndex & 1) == 0) { + ctx.lineTo( px, py ); + } + else { + ctx.moveTo( px, py ); + } + patternDistance -= dist / scale; + break; + } + } + } + }; + + var beginPath = function () { + ctx.beginPath(); + }; + + var closePath = function () { + lineTo( pathx0, pathy0 ); + }; + + return { + moveTo: moveTo, + lineTo: lineTo, + beginPath: beginPath, + closePath: closePath + }; + }; + + // Class: $.jqplot.LineRenderer + // The default line renderer for jqPlot, this class has no options beyond the <Series> class. + // Draws series as a line. + $.jqplot.LineRenderer = function(){ + this.shapeRenderer = new $.jqplot.ShapeRenderer(); + this.shadowRenderer = new $.jqplot.ShadowRenderer(); + }; + + // called with scope of series. + $.jqplot.LineRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + options = options || {}; + this._type='line'; + this.renderer.animation = { + show: false, + direction: 'left', + speed: 2500, + _supported: true + }; + // prop: smooth + // True to draw a smoothed (interpolated) line through the data points + // with automatically computed number of smoothing points. + // Set to an integer number > 2 to specify number of smoothing points + // to use between each data point. + this.renderer.smooth = false; // true or a number > 2 for smoothing. + this.renderer.tension = null; // null to auto compute or a number typically > 6. Fewer points requires higher tension. + // prop: constrainSmoothing + // True to use a more accurate smoothing algorithm that will + // not overshoot any data points. False to allow overshoot but + // produce a smoother looking line. + this.renderer.constrainSmoothing = true; + // this is smoothed data in grid coordinates, like gridData + this.renderer._smoothedData = []; + // this is smoothed data in plot units (plot coordinates), like plotData. + this.renderer._smoothedPlotData = []; + this.renderer._hiBandGridData = []; + this.renderer._lowBandGridData = []; + this.renderer._hiBandSmoothedData = []; + this.renderer._lowBandSmoothedData = []; + + // prop: bandData + // Data used to draw error bands or confidence intervals above/below a line. + // + // bandData can be input in 3 forms. jqPlot will figure out which is the + // low band line and which is the high band line for all forms: + // + // A 2 dimensional array like [[yl1, yl2, ...], [yu1, yu2, ...]] where + // [yl1, yl2, ...] are y values of the lower line and + // [yu1, yu2, ...] are y values of the upper line. + // In this case there must be the same number of y data points as data points + // in the series and the bands will inherit the x values of the series. + // + // A 2 dimensional array like [[[xl1, yl1], [xl2, yl2], ...], [[xh1, yh1], [xh2, yh2], ...]] + // where [xl1, yl1] are x,y data points for the lower line and + // [xh1, yh1] are x,y data points for the high line. + // x values do not have to correspond to the x values of the series and can + // be of any arbitrary length. + // + // Can be of form [[yl1, yu1], [yl2, yu2], [yl3, yu3], ...] where + // there must be 3 or more arrays and there must be the same number of arrays + // as there are data points in the series. In this case, + // [yl1, yu1] specifies the lower and upper y values for the 1st + // data point and so on. The bands will inherit the x + // values from the series. + this.renderer.bandData = []; + + // Group: bands + // Banding around line, e.g error bands or confidence intervals. + this.renderer.bands = { + // prop: show + // true to show the bands. If bandData or interval is + // supplied, show will be set to true by default. + show: false, + hiData: [], + lowData: [], + // prop: color + // color of lines at top and bottom of bands [default: series color]. + color: this.color, + // prop: showLines + // True to show lines at top and bottom of bands [default: false]. + showLines: false, + // prop: fill + // True to fill area between bands [default: true]. + fill: true, + // prop: fillColor + // css color spec for filled area. [default: series color]. + fillColor: null, + _min: null, + _max: null, + // prop: interval + // User specified interval above and below line for bands [default: '3%'']. + // Can be a value like 3 or a string like '3%' + // or an upper/lower array like [1, -2] or ['2%', '-1.5%'] + interval: '3%' + }; + + + var lopts = {highlightMouseOver: options.highlightMouseOver, highlightMouseDown: options.highlightMouseDown, highlightColor: options.highlightColor}; + + delete (options.highlightMouseOver); + delete (options.highlightMouseDown); + delete (options.highlightColor); + + $.extend(true, this.renderer, options); + + this.renderer.options = options; + + // if we are given some band data, and bands aren't explicity set to false in options, turn them on. + if (this.renderer.bandData.length > 1 && (!options.bands || options.bands.show == null)) { + this.renderer.bands.show = true; + } + + // if we are given an interval, and bands aren't explicity set to false in options, turn them on. + else if (options.bands && options.bands.show == null && options.bands.interval != null) { + this.renderer.bands.show = true; + } + + // if plot is filled, turn off bands. + if (this.fill) { + this.renderer.bands.show = false; + } + + if (this.renderer.bands.show) { + this.renderer.initBands.call(this, this.renderer.options, plot); + } + + + // smoothing is not compatible with stacked lines, disable + if (this._stack) { + this.renderer.smooth = false; + } + + // set the shape renderer options + var opts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.fillColor, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; + this.renderer.shapeRenderer.init(opts); + + var shadow_offset = options.shadowOffset; + // set the shadow renderer options + if (shadow_offset == null) { + // scale the shadowOffset to the width of the line. + if (this.lineWidth > 2.5) { + shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); + // var shadow_offset = this.shadowOffset; + } + // for skinny lines, don't make such a big shadow. + else { + shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163; + } + } + + var sopts = {lineJoin:this.lineJoin, lineCap:this.lineCap, fill:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.lineWidth, linePattern:this.linePattern, closePath:this.fill}; + this.renderer.shadowRenderer.init(sopts); + this._areaPoints = []; + this._boundingBox = [[],[]]; + + if (!this.isTrendline && this.fill || this.renderer.bands.show) { + // Group: Properties + // + // prop: highlightMouseOver + // True to highlight area on a filled plot when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on an area on a filled plot. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over an area on a filled plot. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColor + // color to use when highlighting an area on a filled plot. + this.highlightColor = null; + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (lopts.highlightMouseDown && lopts.highlightMouseOver == null) { + lopts.highlightMouseOver = false; + } + + $.extend(true, this, {highlightMouseOver: lopts.highlightMouseOver, highlightMouseDown: lopts.highlightMouseDown, highlightColor: lopts.highlightColor}); + + if (!this.highlightColor) { + var fc = (this.renderer.bands.show) ? this.renderer.bands.fillColor : this.fillColor; + this.highlightColor = $.jqplot.computeHighlightColors(fc); + } + // turn off (disable) the highlighter plugin + if (this.highlighter) { + this.highlighter.show = false; + } + } + + if (!this.isTrendline && plot) { + plot.plugins.lineRenderer = {}; + plot.postInitHooks.addOnce(postInit); + plot.postDrawHooks.addOnce(postPlotDraw); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + } + + }; + + $.jqplot.LineRenderer.prototype.initBands = function(options, plot) { + // use bandData if no data specified in bands option + //var bd = this.renderer.bandData; + var bd = options.bandData || []; + var bands = this.renderer.bands; + bands.hiData = []; + bands.lowData = []; + var data = this.data; + bands._max = null; + bands._min = null; + // If 2 arrays, and each array greater than 2 elements, assume it is hi and low data bands of y values. + if (bd.length == 2) { + // Do we have an array of x,y values? + // like [[[1,1], [2,4], [3,3]], [[1,3], [2,6], [3,5]]] + if ($.isArray(bd[0][0])) { + // since an arbitrary array of points, spin through all of them to determine max and min lines. + + var p; + var bdminidx = 0, bdmaxidx = 0; + for (var i = 0, l = bd[0].length; i<l; i++) { + p = bd[0][i]; + if ((p[1] != null && p[1] > bands._max) || bands._max == null) { + bands._max = p[1]; + } + if ((p[1] != null && p[1] < bands._min) || bands._min == null) { + bands._min = p[1]; + } + } + for (var i = 0, l = bd[1].length; i<l; i++) { + p = bd[1][i]; + if ((p[1] != null && p[1] > bands._max) || bands._max == null) { + bands._max = p[1]; + bdmaxidx = 1; + } + if ((p[1] != null && p[1] < bands._min) || bands._min == null) { + bands._min = p[1]; + bdminidx = 1; + } + } + + if (bdmaxidx === bdminidx) { + bands.show = false; + } + + bands.hiData = bd[bdmaxidx]; + bands.lowData = bd[bdminidx]; + } + // else data is arrays of y values + // like [[1,4,3], [3,6,5]] + // must have same number of band data points as points in series + else if (bd[0].length === data.length && bd[1].length === data.length) { + var hi = (bd[0][0] > bd[1][0]) ? 0 : 1; + var low = (hi) ? 0 : 1; + for (var i=0, l=data.length; i < l; i++) { + bands.hiData.push([data[i][0], bd[hi][i]]); + bands.lowData.push([data[i][0], bd[low][i]]); + } + } + + // we don't have proper data array, don't show bands. + else { + bands.show = false; + } + } + + // if more than 2 arrays, have arrays of [ylow, yhi] values. + // note, can't distinguish case of [[ylow, yhi], [ylow, yhi]] from [[ylow, ylow], [yhi, yhi]] + // this is assumed to be of the latter form. + else if (bd.length > 2 && !$.isArray(bd[0][0])) { + var hi = (bd[0][0] > bd[0][1]) ? 0 : 1; + var low = (hi) ? 0 : 1; + for (var i=0, l=bd.length; i<l; i++) { + bands.hiData.push([data[i][0], bd[i][hi]]); + bands.lowData.push([data[i][0], bd[i][low]]); + } + } + + // don't have proper data, auto calculate + else { + var intrv = bands.interval; + var a = null; + var b = null; + var afunc = null; + var bfunc = null; + + if ($.isArray(intrv)) { + a = intrv[0]; + b = intrv[1]; + } + else { + a = intrv; + } + + if (isNaN(a)) { + // we have a string + if (a.charAt(a.length - 1) === '%') { + afunc = 'multiply'; + a = parseFloat(a)/100 + 1; + } + } + + else { + a = parseFloat(a); + afunc = 'add'; + } + + if (b !== null && isNaN(b)) { + // we have a string + if (b.charAt(b.length - 1) === '%') { + bfunc = 'multiply'; + b = parseFloat(b)/100 + 1; + } + } + + else if (b !== null) { + b = parseFloat(b); + bfunc = 'add'; + } + + if (a !== null) { + if (b === null) { + b = -a; + bfunc = afunc; + if (bfunc === 'multiply') { + b += 2; + } + } + + // make sure a always applies to hi band. + if (a < b) { + var temp = a; + a = b; + b = temp; + temp = afunc; + afunc = bfunc; + bfunc = temp; + } + + for (var i=0, l = data.length; i < l; i++) { + switch (afunc) { + case 'add': + bands.hiData.push([data[i][0], data[i][1] + a]); + break; + case 'multiply': + bands.hiData.push([data[i][0], data[i][1] * a]); + break; + } + switch (bfunc) { + case 'add': + bands.lowData.push([data[i][0], data[i][1] + b]); + break; + case 'multiply': + bands.lowData.push([data[i][0], data[i][1] * b]); + break; + } + } + } + + else { + bands.show = false; + } + } + + var hd = bands.hiData; + var ld = bands.lowData; + for (var i = 0, l = hd.length; i<l; i++) { + if ((hd[i][1] != null && hd[i][1] > bands._max) || bands._max == null) { + bands._max = hd[i][1]; + } + } + for (var i = 0, l = ld.length; i<l; i++) { + if ((ld[i][1] != null && ld[i][1] < bands._min) || bands._min == null) { + bands._min = ld[i][1]; + } + } + + // one last check for proper data + // these don't apply any more since allowing arbitrary x,y values + // if (bands.hiData.length != bands.lowData.length) { + // bands.show = false; + // } + + // if (bands.hiData.length != this.data.length) { + // bands.show = false; + // } + + if (bands.fillColor === null) { + var c = $.jqplot.getColorComponents(bands.color); + // now adjust alpha to differentiate fill + c[3] = c[3] * 0.5; + bands.fillColor = 'rgba(' + c[0] +', '+ c[1] +', '+ c[2] +', '+ c[3] + ')'; + } + }; + + function getSteps (d, f) { + return (3.4182054+f) * Math.pow(d, -0.3534992); + } + + function computeSteps (d1, d2) { + var s = Math.sqrt(Math.pow((d2[0]- d1[0]), 2) + Math.pow ((d2[1] - d1[1]), 2)); + return 5.7648 * Math.log(s) + 7.4456; + } + + function tanh (x) { + var a = (Math.exp(2*x) - 1) / (Math.exp(2*x) + 1); + return a; + } + + ////////// + // computeConstrainedSmoothedData + // An implementation of the constrained cubic spline interpolation + // method as presented in: + // + // Kruger, CJC, Constrained Cubic Spine Interpolation for Chemical Engineering Applications + // http://www.korf.co.uk/spline.pdf + // + // The implementation below borrows heavily from the sample Visual Basic + // implementation by CJC Kruger found in http://www.korf.co.uk/spline.xls + // + ///////// + + // called with scope of series + function computeConstrainedSmoothedData (gd) { + var smooth = this.renderer.smooth; + var dim = this.canvas.getWidth(); + var xp = this._xaxis.series_p2u; + var yp = this._yaxis.series_p2u; + var steps =null; + var _steps = null; + var dist = gd.length/dim; + var _smoothedData = []; + var _smoothedPlotData = []; + + if (!isNaN(parseFloat(smooth))) { + steps = parseFloat(smooth); + } + else { + steps = getSteps(dist, 0.5); + } + + var yy = []; + var xx = []; + + for (var i=0, l = gd.length; i<l; i++) { + yy.push(gd[i][1]); + xx.push(gd[i][0]); + } + + function dxx(x1, x0) { + if (x1 - x0 == 0) { + return Math.pow(10,10); + } + else { + return x1 - x0; + } + } + + var A, B, C, D; + // loop through each line segment. Have # points - 1 line segments. Nmber segments starting at 1. + var nmax = gd.length - 1; + for (var num = 1, gdl = gd.length; num<gdl; num++) { + var gxx = []; + var ggxx = []; + // point at each end of segment. + for (var j = 0; j < 2; j++) { + var i = num - 1 + j; // point number, 0 to # points. + + if (i == 0 || i == nmax) { + gxx[j] = Math.pow(10, 10); + } + else if (yy[i+1] - yy[i] == 0 || yy[i] - yy[i-1] == 0) { + gxx[j] = 0; + } + else if (((xx[i+1] - xx[i]) / (yy[i+1] - yy[i]) + (xx[i] - xx[i-1]) / (yy[i] - yy[i-1])) == 0 ) { + gxx[j] = 0; + } + else if ( (yy[i+1] - yy[i]) * (yy[i] - yy[i-1]) < 0 ) { + gxx[j] = 0; + } + + else { + gxx[j] = 2 / (dxx(xx[i + 1], xx[i]) / (yy[i + 1] - yy[i]) + dxx(xx[i], xx[i - 1]) / (yy[i] - yy[i - 1])); + } + } + + // Reset first derivative (slope) at first and last point + if (num == 1) { + // First point has 0 2nd derivative + gxx[0] = 3 / 2 * (yy[1] - yy[0]) / dxx(xx[1], xx[0]) - gxx[1] / 2; + } + else if (num == nmax) { + // Last point has 0 2nd derivative + gxx[1] = 3 / 2 * (yy[nmax] - yy[nmax - 1]) / dxx(xx[nmax], xx[nmax - 1]) - gxx[0] / 2; + } + + // Calc second derivative at points + ggxx[0] = -2 * (gxx[1] + 2 * gxx[0]) / dxx(xx[num], xx[num - 1]) + 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); + ggxx[1] = 2 * (2 * gxx[1] + gxx[0]) / dxx(xx[num], xx[num - 1]) - 6 * (yy[num] - yy[num - 1]) / Math.pow(dxx(xx[num], xx[num - 1]), 2); + + // Calc constants for cubic interpolation + D = 1 / 6 * (ggxx[1] - ggxx[0]) / dxx(xx[num], xx[num - 1]); + C = 1 / 2 * (xx[num] * ggxx[0] - xx[num - 1] * ggxx[1]) / dxx(xx[num], xx[num - 1]); + B = (yy[num] - yy[num - 1] - C * (Math.pow(xx[num], 2) - Math.pow(xx[num - 1], 2)) - D * (Math.pow(xx[num], 3) - Math.pow(xx[num - 1], 3))) / dxx(xx[num], xx[num - 1]); + A = yy[num - 1] - B * xx[num - 1] - C * Math.pow(xx[num - 1], 2) - D * Math.pow(xx[num - 1], 3); + + var increment = (xx[num] - xx[num - 1]) / steps; + var temp, tempx; + + for (var j = 0, l = steps; j < l; j++) { + temp = []; + tempx = xx[num - 1] + j * increment; + temp.push(tempx); + temp.push(A + B * tempx + C * Math.pow(tempx, 2) + D * Math.pow(tempx, 3)); + _smoothedData.push(temp); + _smoothedPlotData.push([xp(temp[0]), yp(temp[1])]); + } + } + + _smoothedData.push(gd[i]); + _smoothedPlotData.push([xp(gd[i][0]), yp(gd[i][1])]); + + return [_smoothedData, _smoothedPlotData]; + } + + /////// + // computeHermiteSmoothedData + // A hermite spline smoothing of the plot data. + // This implementation is derived from the one posted + // by krypin on the jqplot-users mailing list: + // + // http://groups.google.com/group/jqplot-users/browse_thread/thread/748be6a445723cea?pli=1 + // + // with a blog post: + // + // http://blog.statscollector.com/a-plugin-renderer-for-jqplot-to-draw-a-hermite-spline/ + // + // and download of the original plugin: + // + // http://blog.statscollector.com/wp-content/uploads/2010/02/jqplot.hermiteSplineRenderer.js + ////////// + + // called with scope of series + function computeHermiteSmoothedData (gd) { + var smooth = this.renderer.smooth; + var tension = this.renderer.tension; + var dim = this.canvas.getWidth(); + var xp = this._xaxis.series_p2u; + var yp = this._yaxis.series_p2u; + var steps =null; + var _steps = null; + var a = null; + var a1 = null; + var a2 = null; + var slope = null; + var slope2 = null; + var temp = null; + var t, s, h1, h2, h3, h4; + var TiX, TiY, Ti1X, Ti1Y; + var pX, pY, p; + var sd = []; + var spd = []; + var dist = gd.length/dim; + var min, max, stretch, scale, shift; + var _smoothedData = []; + var _smoothedPlotData = []; + if (!isNaN(parseFloat(smooth))) { + steps = parseFloat(smooth); + } + else { + steps = getSteps(dist, 0.5); + } + if (!isNaN(parseFloat(tension))) { + tension = parseFloat(tension); + } + + for (var i=0, l = gd.length-1; i < l; i++) { + + if (tension === null) { + slope = Math.abs((gd[i+1][1] - gd[i][1]) / (gd[i+1][0] - gd[i][0])); + + min = 0.3; + max = 0.6; + stretch = (max - min)/2.0; + scale = 2.5; + shift = -1.4; + + temp = slope/scale + shift; + + a1 = stretch * tanh(temp) - stretch * tanh(shift) + min; + + // if have both left and right line segments, will use minimum tension. + if (i > 0) { + slope2 = Math.abs((gd[i][1] - gd[i-1][1]) / (gd[i][0] - gd[i-1][0])); + } + temp = slope2/scale + shift; + + a2 = stretch * tanh(temp) - stretch * tanh(shift) + min; + + a = (a1 + a2)/2.0; + + } + else { + a = tension; + } + for (t=0; t < steps; t++) { + s = t / steps; + h1 = (1 + 2*s)*Math.pow((1-s),2); + h2 = s*Math.pow((1-s),2); + h3 = Math.pow(s,2)*(3-2*s); + h4 = Math.pow(s,2)*(s-1); + + if (gd[i-1]) { + TiX = a * (gd[i+1][0] - gd[i-1][0]); + TiY = a * (gd[i+1][1] - gd[i-1][1]); + } else { + TiX = a * (gd[i+1][0] - gd[i][0]); + TiY = a * (gd[i+1][1] - gd[i][1]); + } + if (gd[i+2]) { + Ti1X = a * (gd[i+2][0] - gd[i][0]); + Ti1Y = a * (gd[i+2][1] - gd[i][1]); + } else { + Ti1X = a * (gd[i+1][0] - gd[i][0]); + Ti1Y = a * (gd[i+1][1] - gd[i][1]); + } + + pX = h1*gd[i][0] + h3*gd[i+1][0] + h2*TiX + h4*Ti1X; + pY = h1*gd[i][1] + h3*gd[i+1][1] + h2*TiY + h4*Ti1Y; + p = [pX, pY]; + + _smoothedData.push(p); + _smoothedPlotData.push([xp(pX), yp(pY)]); + } + } + _smoothedData.push(gd[l]); + _smoothedPlotData.push([xp(gd[l][0]), yp(gd[l][1])]); + + return [_smoothedData, _smoothedPlotData]; + } + + // setGridData + // converts the user data values to grid coordinates and stores them + // in the gridData array. + // Called with scope of a series. + $.jqplot.LineRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var data = this._plotData; + var pdata = this._prevPlotData; + this.gridData = []; + this._prevGridData = []; + this.renderer._smoothedData = []; + this.renderer._smoothedPlotData = []; + this.renderer._hiBandGridData = []; + this.renderer._lowBandGridData = []; + this.renderer._hiBandSmoothedData = []; + this.renderer._lowBandSmoothedData = []; + var bands = this.renderer.bands; + var hasNull = false; + for (var i=0, l=data.length; i < l; i++) { + // if not a line series or if no nulls in data, push the converted point onto the array. + if (data[i][0] != null && data[i][1] != null) { + this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); + } + // else if there is a null, preserve it. + else if (data[i][0] == null) { + hasNull = true; + this.gridData.push([null, yp.call(this._yaxis, data[i][1])]); + } + else if (data[i][1] == null) { + hasNull = true; + this.gridData.push([xp.call(this._xaxis, data[i][0]), null]); + } + // if not a line series or if no nulls in data, push the converted point onto the array. + if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] != null) { + this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), yp.call(this._yaxis, pdata[i][1])]); + } + // else if there is a null, preserve it. + else if (pdata[i] != null && pdata[i][0] == null) { + this._prevGridData.push([null, yp.call(this._yaxis, pdata[i][1])]); + } + else if (pdata[i] != null && pdata[i][0] != null && pdata[i][1] == null) { + this._prevGridData.push([xp.call(this._xaxis, pdata[i][0]), null]); + } + } + + // don't do smoothing or bands on broken lines. + if (hasNull) { + this.renderer.smooth = false; + if (this._type === 'line') { + bands.show = false; + } + } + + if (this._type === 'line' && bands.show) { + for (var i=0, l=bands.hiData.length; i<l; i++) { + this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); + } + for (var i=0, l=bands.lowData.length; i<l; i++) { + this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); + } + } + + // calculate smoothed data if enough points and no nulls + if (this._type === 'line' && this.renderer.smooth && this.gridData.length > 2) { + var ret; + if (this.renderer.constrainSmoothing) { + ret = computeConstrainedSmoothedData.call(this, this.gridData); + this.renderer._smoothedData = ret[0]; + this.renderer._smoothedPlotData = ret[1]; + + if (bands.show) { + ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); + this.renderer._hiBandSmoothedData = ret[0]; + ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); + this.renderer._lowBandSmoothedData = ret[0]; + } + + ret = null; + } + else { + ret = computeHermiteSmoothedData.call(this, this.gridData); + this.renderer._smoothedData = ret[0]; + this.renderer._smoothedPlotData = ret[1]; + + if (bands.show) { + ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); + this.renderer._hiBandSmoothedData = ret[0]; + ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); + this.renderer._lowBandSmoothedData = ret[0]; + } + + ret = null; + } + } + }; + + // makeGridData + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.LineRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var gd = []; + var pgd = []; + this.renderer._smoothedData = []; + this.renderer._smoothedPlotData = []; + this.renderer._hiBandGridData = []; + this.renderer._lowBandGridData = []; + this.renderer._hiBandSmoothedData = []; + this.renderer._lowBandSmoothedData = []; + var bands = this.renderer.bands; + var hasNull = false; + for (var i=0; i<data.length; i++) { + // if not a line series or if no nulls in data, push the converted point onto the array. + if (data[i][0] != null && data[i][1] != null) { + gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1])]); + } + // else if there is a null, preserve it. + else if (data[i][0] == null) { + hasNull = true; + gd.push([null, yp.call(this._yaxis, data[i][1])]); + } + else if (data[i][1] == null) { + hasNull = true; + gd.push([xp.call(this._xaxis, data[i][0]), null]); + } + } + + // don't do smoothing or bands on broken lines. + if (hasNull) { + this.renderer.smooth = false; + if (this._type === 'line') { + bands.show = false; + } + } + + if (this._type === 'line' && bands.show) { + for (var i=0, l=bands.hiData.length; i<l; i++) { + this.renderer._hiBandGridData.push([xp.call(this._xaxis, bands.hiData[i][0]), yp.call(this._yaxis, bands.hiData[i][1])]); + } + for (var i=0, l=bands.lowData.length; i<l; i++) { + this.renderer._lowBandGridData.push([xp.call(this._xaxis, bands.lowData[i][0]), yp.call(this._yaxis, bands.lowData[i][1])]); + } + } + + if (this._type === 'line' && this.renderer.smooth && gd.length > 2) { + var ret; + if (this.renderer.constrainSmoothing) { + ret = computeConstrainedSmoothedData.call(this, gd); + this.renderer._smoothedData = ret[0]; + this.renderer._smoothedPlotData = ret[1]; + + if (bands.show) { + ret = computeConstrainedSmoothedData.call(this, this.renderer._hiBandGridData); + this.renderer._hiBandSmoothedData = ret[0]; + ret = computeConstrainedSmoothedData.call(this, this.renderer._lowBandGridData); + this.renderer._lowBandSmoothedData = ret[0]; + } + + ret = null; + } + else { + ret = computeHermiteSmoothedData.call(this, gd); + this.renderer._smoothedData = ret[0]; + this.renderer._smoothedPlotData = ret[1]; + + if (bands.show) { + ret = computeHermiteSmoothedData.call(this, this.renderer._hiBandGridData); + this.renderer._hiBandSmoothedData = ret[0]; + ret = computeHermiteSmoothedData.call(this, this.renderer._lowBandGridData); + this.renderer._lowBandSmoothedData = ret[0]; + } + + ret = null; + } + } + return gd; + }; + + + // called within scope of series. + $.jqplot.LineRenderer.prototype.draw = function(ctx, gd, options, plot) { + var i; + // get a copy of the options, so we don't modify the original object. + var opts = $.extend(true, {}, options); + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; + var xmin, ymin, xmax, ymax; + ctx.save(); + if (gd.length) { + if (showLine) { + // if we fill, we'll have to add points to close the curve. + if (fill) { + if (this.fillToZero) { + // have to break line up into shapes at axis crossings + var negativeColor = this.negativeColor; + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var isnegative = false; + var posfs = opts.fillStyle; + + // if stoking line as well as filling, get a copy of line data. + if (fillAndStroke) { + var fasgd = gd.slice(0); + } + // if not stacked, fill down to axis + if (this.index == 0 || !this._stack) { + + var tempgd = []; + var pd = (this.renderer.smooth) ? this.renderer._smoothedPlotData : this._plotData; + this._areaPoints = []; + var pyzero = this._yaxis.series_u2p(this.fillToValue); + var pxzero = this._xaxis.series_u2p(this.fillToValue); + + opts.closePath = true; + + if (this.fillAxis == 'y') { + tempgd.push([gd[0][0], pyzero]); + this._areaPoints.push([gd[0][0], pyzero]); + + for (var i=0; i<gd.length-1; i++) { + tempgd.push(gd[i]); + this._areaPoints.push(gd[i]); + // do we have an axis crossing? + if (pd[i][1] * pd[i+1][1] <= 0) { + if (pd[i][1] < 0) { + isnegative = true; + opts.fillStyle = negativeColor; + } + else { + isnegative = false; + opts.fillStyle = posfs; + } + + var xintercept = gd[i][0] + (gd[i+1][0] - gd[i][0]) * (pyzero-gd[i][1])/(gd[i+1][1] - gd[i][1]); + tempgd.push([xintercept, pyzero]); + this._areaPoints.push([xintercept, pyzero]); + // now draw this shape and shadow. + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, tempgd, opts); + } + this.renderer.shapeRenderer.draw(ctx, tempgd, opts); + // now empty temp array and continue + tempgd = [[xintercept, pyzero]]; + // this._areaPoints = [[xintercept, pyzero]]; + } + } + if (pd[gd.length-1][1] < 0) { + isnegative = true; + opts.fillStyle = negativeColor; + } + else { + isnegative = false; + opts.fillStyle = posfs; + } + tempgd.push(gd[gd.length-1]); + this._areaPoints.push(gd[gd.length-1]); + tempgd.push([gd[gd.length-1][0], pyzero]); + this._areaPoints.push([gd[gd.length-1][0], pyzero]); + } + // now draw the last area. + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, tempgd, opts); + } + this.renderer.shapeRenderer.draw(ctx, tempgd, opts); + + + // var gridymin = this._yaxis.series_u2p(0); + // // IE doesn't return new length on unshift + // gd.unshift([gd[0][0], gridymin]); + // len = gd.length; + // gd.push([gd[len - 1][0], gridymin]); + } + // if stacked, fill to line below + else { + var prev = this._prevGridData; + for (var i=prev.length; i>0; i--) { + gd.push(prev[i-1]); + // this._areaPoints.push(prev[i-1]); + } + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, gd, opts); + } + this._areaPoints = gd; + this.renderer.shapeRenderer.draw(ctx, gd, opts); + } + } + ///////////////////////// + // Not filled to zero + //////////////////////// + else { + // if stoking line as well as filling, get a copy of line data. + if (fillAndStroke) { + var fasgd = gd.slice(0); + } + // if not stacked, fill down to axis + if (this.index == 0 || !this._stack) { + // var gridymin = this._yaxis.series_u2p(this._yaxis.min) - this.gridBorderWidth / 2; + var gridymin = ctx.canvas.height; + // IE doesn't return new length on unshift + gd.unshift([gd[0][0], gridymin]); + var len = gd.length; + gd.push([gd[len - 1][0], gridymin]); + } + // if stacked, fill to line below + else { + var prev = this._prevGridData; + for (var i=prev.length; i>0; i--) { + gd.push(prev[i-1]); + } + } + this._areaPoints = gd; + + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, gd, opts); + } + + this.renderer.shapeRenderer.draw(ctx, gd, opts); + } + if (fillAndStroke) { + var fasopts = $.extend(true, {}, opts, {fill:false, closePath:false}); + this.renderer.shapeRenderer.draw(ctx, fasgd, fasopts); + ////////// + // TODO: figure out some way to do shadows nicely + // if (shadow) { + // this.renderer.shadowRenderer.draw(ctx, fasgd, fasopts); + // } + // now draw the markers + if (this.markerRenderer.show) { + if (this.renderer.smooth) { + fasgd = this.gridData; + } + for (i=0; i<fasgd.length; i++) { + this.markerRenderer.draw(fasgd[i][0], fasgd[i][1], ctx, opts.markerOptions); + } + } + } + } + else { + + if (this.renderer.bands.show) { + var bdat; + var bopts = $.extend(true, {}, opts); + if (this.renderer.bands.showLines) { + bdat = (this.renderer.smooth) ? this.renderer._hiBandSmoothedData : this.renderer._hiBandGridData; + this.renderer.shapeRenderer.draw(ctx, bdat, opts); + bdat = (this.renderer.smooth) ? this.renderer._lowBandSmoothedData : this.renderer._lowBandGridData; + this.renderer.shapeRenderer.draw(ctx, bdat, bopts); + } + + if (this.renderer.bands.fill) { + if (this.renderer.smooth) { + bdat = this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse()); + } + else { + bdat = this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse()); + } + this._areaPoints = bdat; + bopts.closePath = true; + bopts.fill = true; + bopts.fillStyle = this.renderer.bands.fillColor; + this.renderer.shapeRenderer.draw(ctx, bdat, bopts); + } + } + + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, gd, opts); + } + + this.renderer.shapeRenderer.draw(ctx, gd, opts); + } + } + // calculate the bounding box + var xmin = xmax = ymin = ymax = null; + for (i=0; i<this._areaPoints.length; i++) { + var p = this._areaPoints[i]; + if (xmin > p[0] || xmin == null) { + xmin = p[0]; + } + if (ymax < p[1] || ymax == null) { + ymax = p[1]; + } + if (xmax < p[0] || xmax == null) { + xmax = p[0]; + } + if (ymin > p[1] || ymin == null) { + ymin = p[1]; + } + } + + if (this.type === 'line' && this.renderer.bands.show) { + ymax = this._yaxis.series_u2p(this.renderer.bands._min); + ymin = this._yaxis.series_u2p(this.renderer.bands._max); + } + + this._boundingBox = [[xmin, ymax], [xmax, ymin]]; + + // now draw the markers + if (this.markerRenderer.show && !fill) { + if (this.renderer.smooth) { + gd = this.gridData; + } + for (i=0; i<gd.length; i++) { + if (gd[i][0] != null && gd[i][1] != null) { + this.markerRenderer.draw(gd[i][0], gd[i][1], ctx, opts.markerOptions); + } + } + } + } + + ctx.restore(); + }; + + $.jqplot.LineRenderer.prototype.drawShadow = function(ctx, gd, options) { + // This is a no-op, shadows drawn with lines. + }; + + // called with scope of plot. + // make sure to not leave anything highlighted. + function postInit(target, data, options) { + for (var i=0; i<this.series.length; i++) { + if (this.series[i].renderer.constructor == $.jqplot.LineRenderer) { + // don't allow mouseover and mousedown at same time. + if (this.series[i].highlightMouseOver) { + this.series[i].highlightMouseDown = false; + } + } + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.lineRenderer && this.plugins.lineRenderer.highlightCanvas) { + this.plugins.lineRenderer.highlightCanvas.resetCanvas(); + this.plugins.lineRenderer.highlightCanvas = null; + } + + this.plugins.lineRenderer.highlightedSeriesIndex = null; + this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions, this)); + this.plugins.lineRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + function highlight (plot, sidx, pidx, points) { + var s = plot.series[sidx]; + var canvas = plot.plugins.lineRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.lineRenderer.highlightedSeriesIndex = sidx; + var opts = {fillStyle: s.highlightColor}; + if (s.type === 'line' && s.renderer.bands.show) { + opts.fill = true; + opts.closePath = true; + } + s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); + canvas = null; + } + + function unhighlight (plot) { + var canvas = plot.plugins.lineRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.lineRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + canvas = null; + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.lineRenderer.highlightedSeriesIndex)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var idx = plot.plugins.lineRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + + // class: $.jqplot.LinearAxisRenderer + // The default jqPlot axis renderer, creating a numeric axis. + $.jqplot.LinearAxisRenderer = function() { + }; + + // called with scope of axis object. + $.jqplot.LinearAxisRenderer.prototype.init = function(options){ + // prop: breakPoints + // EXPERIMENTAL!! Use at your own risk! + // Works only with linear axes and the default tick renderer. + // Array of [start, stop] points to create a broken axis. + // Broken axes have a "jump" in them, which is an immediate + // transition from a smaller value to a larger value. + // Currently, axis ticks MUST be manually assigned if using breakPoints + // by using the axis ticks array option. + this.breakPoints = null; + // prop: breakTickLabel + // Label to use at the axis break if breakPoints are specified. + this.breakTickLabel = "≈"; + // prop: drawBaseline + // True to draw the axis baseline. + this.drawBaseline = true; + // prop: baselineWidth + // width of the baseline in pixels. + this.baselineWidth = null; + // prop: baselineColor + // CSS color spec for the baseline. + this.baselineColor = null; + // prop: forceTickAt0 + // This will ensure that there is always a tick mark at 0. + // If data range is strictly positive or negative, + // this will force 0 to be inside the axis bounds unless + // the appropriate axis pad (pad, padMin or padMax) is set + // to 0, then this will force an axis min or max value at 0. + // This has know effect when any of the following options + // are set: autoscale, min, max, numberTicks or tickInterval. + this.forceTickAt0 = false; + // prop: forceTickAt100 + // This will ensure that there is always a tick mark at 100. + // If data range is strictly above or below 100, + // this will force 100 to be inside the axis bounds unless + // the appropriate axis pad (pad, padMin or padMax) is set + // to 0, then this will force an axis min or max value at 100. + // This has know effect when any of the following options + // are set: autoscale, min, max, numberTicks or tickInterval. + this.forceTickAt100 = false; + // prop: tickInset + // Controls the amount to inset the first and last ticks from + // the edges of the grid, in multiples of the tick interval. + // 0 is no inset, 0.5 is one half a tick interval, 1 is a full + // tick interval, etc. + this.tickInset = 0; + // prop: minorTicks + // Number of ticks to add between "major" ticks. + // Major ticks are ticks supplied by user or auto computed. + // Minor ticks cannot be created by user. + this.minorTicks = 0; + // prop: alignTicks + // true to align tick marks across opposed axes + // such as from the y2axis to yaxis. + this.alignTicks = false; + this._autoFormatString = ''; + this._overrideFormatString = false; + this._scalefact = 1.0; + $.extend(true, this, options); + if (this.breakPoints) { + if (!$.isArray(this.breakPoints)) { + this.breakPoints = null; + } + else if (this.breakPoints.length < 2 || this.breakPoints[1] <= this.breakPoints[0]) { + this.breakPoints = null; + } + } + if (this.numberTicks != null && this.numberTicks < 2) { + this.numberTicks = 2; + } + this.resetDataBounds(); + }; + + // called with scope of axis + $.jqplot.LinearAxisRenderer.prototype.draw = function(ctx, plot) { + if (this.show) { + // populate the axis label and value properties. + // createTicks is a method on the renderer, but + // call it within the scope of the axis. + this.renderer.createTicks.call(this, plot); + // fill a div with axes labels in the right direction. + // Need to pregenerate each axis to get its bounds and + // position it and the labels correctly on the plot. + var dim=0; + var temp; + // Added for theming. + if (this._elem) { + // Memory Leaks patch + //this._elem.empty(); + this._elem.emptyForce(); + this._elem = null; + } + + this._elem = $(document.createElement('div')); + this._elem.addClass('jqplot-axis jqplot-'+this.name); + this._elem.css('position', 'absolute'); + + + if (this.name == 'xaxis' || this.name == 'x2axis') { + this._elem.width(this._plotDimensions.width); + } + else { + this._elem.height(this._plotDimensions.height); + } + + // create a _label object. + this.labelOptions.axis = this.name; + this._label = new this.labelRenderer(this.labelOptions); + if (this._label.show) { + var elem = this._label.draw(ctx, plot); + elem.appendTo(this._elem); + elem = null; + } + + var t = this._ticks; + var tick; + for (var i=0; i<t.length; i++) { + tick = t[i]; + if (tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + this._elem.append(tick.draw(ctx, plot)); + } + } + tick = null; + t = null; + } + return this._elem; + }; + + // called with scope of an axis + $.jqplot.LinearAxisRenderer.prototype.reset = function() { + this.min = this._options.min; + this.max = this._options.max; + this.tickInterval = this._options.tickInterval; + this.numberTicks = this._options.numberTicks; + this._autoFormatString = ''; + if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) { + this.tickOptions.formatString = ''; + } + + // this._ticks = this.__ticks; + }; + + // called with scope of axis + $.jqplot.LinearAxisRenderer.prototype.set = function() { + var dim = 0; + var temp; + var w = 0; + var h = 0; + var lshow = (this._label == null) ? false : this._label.show; + if (this.show) { + var t = this._ticks; + var tick; + for (var i=0; i<t.length; i++) { + tick = t[i]; + if (!tick._breakTick && tick.show && tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + temp = tick._elem.outerHeight(true); + } + else { + temp = tick._elem.outerWidth(true); + } + if (temp > dim) { + dim = temp; + } + } + } + tick = null; + t = null; + + if (lshow) { + w = this._label._elem.outerWidth(true); + h = this._label._elem.outerHeight(true); + } + if (this.name == 'xaxis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); + } + else if (this.name == 'x2axis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); + } + else if (this.name == 'yaxis') { + dim = dim + w; + this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + else { + dim = dim + w; + this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + } + }; + + // called with scope of axis + $.jqplot.LinearAxisRenderer.prototype.createTicks = function(plot) { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; + var interval; + var min, max; + var pos1, pos2; + var tt, i; + // get a copy of user's settings for min/max. + var userMin = this.min; + var userMax = this.max; + var userNT = this.numberTicks; + var userTI = this.tickInterval; + + var threshold = 30; + this._scalefact = (Math.max(dim, threshold+1) - threshold)/300.0; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i<userTicks.length; i++){ + var ut = userTicks[i]; + var t = new this.tickRenderer(this.tickOptions); + if ($.isArray(ut)) { + t.value = ut[0]; + if (this.breakPoints) { + if (ut[0] == this.breakPoints[0]) { + t.label = this.breakTickLabel; + t._breakTick = true; + t.showGridline = false; + t.showMark = false; + } + else if (ut[0] > this.breakPoints[0] && ut[0] <= this.breakPoints[1]) { + t.show = false; + t.showGridline = false; + t.label = ut[1]; + } + else { + t.label = ut[1]; + } + } + else { + t.label = ut[1]; + } + t.setTick(ut[0], this.name); + this._ticks.push(t); + } + + else if ($.isPlainObject(ut)) { + $.extend(true, t, ut); + t.axis = this.name; + this._ticks.push(t); + } + + else { + t.value = ut; + if (this.breakPoints) { + if (ut == this.breakPoints[0]) { + t.label = this.breakTickLabel; + t._breakTick = true; + t.showGridline = false; + t.showMark = false; + } + else if (ut > this.breakPoints[0] && ut <= this.breakPoints[1]) { + t.show = false; + t.showGridline = false; + } + } + t.setTick(ut, this.name); + this._ticks.push(t); + } + } + this.numberTicks = userTicks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this.numberTicks-1].value; + this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); + } + + // we don't have any ticks yet, let's make some! + else { + if (name == 'xaxis' || name == 'x2axis') { + dim = this._plotDimensions.width; + } + else { + dim = this._plotDimensions.height; + } + + var _numberTicks = this.numberTicks; + + // if aligning this axis, use number of ticks from previous axis. + // Do I need to reset somehow if alignTicks is changed and then graph is replotted?? + if (this.alignTicks) { + if (this.name === 'x2axis' && plot.axes.xaxis.show) { + _numberTicks = plot.axes.xaxis.numberTicks; + } + else if (this.name.charAt(0) === 'y' && this.name !== 'yaxis' && this.name !== 'yMidAxis' && plot.axes.yaxis.show) { + _numberTicks = plot.axes.yaxis.numberTicks; + } + } + + min = ((this.min != null) ? this.min : db.min); + max = ((this.max != null) ? this.max : db.max); + + var range = max - min; + var rmin, rmax; + var temp; + + if (this.tickOptions == null || !this.tickOptions.formatString) { + this._overrideFormatString = true; + } + + // Doing complete autoscaling + if (this.min == null || this.max == null && this.tickInterval == null && !this.autoscale) { + // Check if user must have tick at 0 or 100 and ensure they are in range. + // The autoscaling algorithm will always place ticks at 0 and 100 if they are in range. + if (this.forceTickAt0) { + if (min > 0) { + min = 0; + } + if (max < 0) { + max = 0; + } + } + + if (this.forceTickAt100) { + if (min > 100) { + min = 100; + } + if (max < 100) { + max = 100; + } + } + + var keepMin = false, + keepMax = false; + + if (this.min != null) { + keepMin = true; + } + + else if (this.max != null) { + keepMax = true; + } + + // var threshold = 30; + // var tdim = Math.max(dim, threshold+1); + // this._scalefact = (tdim-threshold)/300.0; + var ret = $.jqplot.LinearTickGenerator(min, max, this._scalefact, _numberTicks, keepMin, keepMax); + // calculate a padded max and min, points should be less than these + // so that they aren't too close to the edges of the plot. + // User can adjust how much padding is allowed with pad, padMin and PadMax options. + // If min or max is set, don't pad that end of axis. + var tumin = (this.min != null) ? min : min + range*(this.padMin - 1); + var tumax = (this.max != null) ? max : max - range*(this.padMax - 1); + + // if they're equal, we shouldn't have to do anything, right? + // if (min <=tumin || max >= tumax) { + if (min <tumin || max > tumax) { + tumin = (this.min != null) ? min : min - range*(this.padMin - 1); + tumax = (this.max != null) ? max : max + range*(this.padMax - 1); + ret = $.jqplot.LinearTickGenerator(tumin, tumax, this._scalefact, _numberTicks, keepMin, keepMax); + } + + this.min = ret[0]; + this.max = ret[1]; + // if numberTicks specified, it should return the same. + this.numberTicks = ret[2]; + this._autoFormatString = ret[3]; + this.tickInterval = ret[4]; + } + + // User has specified some axis scale related option, can use auto algorithm + else { + + // if min and max are same, space them out a bit + if (min == max) { + var adj = 0.05; + if (min > 0) { + adj = Math.max(Math.log(min)/Math.LN10, 0.05); + } + min -= adj; + max += adj; + } + + // autoscale. Can't autoscale if min or max is supplied. + // Will use numberTicks and tickInterval if supplied. Ticks + // across multiple axes may not line up depending on how + // bars are to be plotted. + if (this.autoscale && this.min == null && this.max == null) { + var rrange, ti, margin; + var forceMinZero = false; + var forceZeroLine = false; + var intervals = {min:null, max:null, average:null, stddev:null}; + // if any series are bars, or if any are fill to zero, and if this + // is the axis to fill toward, check to see if we can start axis at zero. + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + var faname = (s.fillAxis == 'x') ? s._xaxis.name : s._yaxis.name; + // check to see if this is the fill axis + if (this.name == faname) { + var vals = s._plotValues[s.fillAxis]; + var vmin = vals[0]; + var vmax = vals[0]; + for (var j=1; j<vals.length; j++) { + if (vals[j] < vmin) { + vmin = vals[j]; + } + else if (vals[j] > vmax) { + vmax = vals[j]; + } + } + var dp = (vmax - vmin) / vmax; + // is this sries a bar? + if (s.renderer.constructor == $.jqplot.BarRenderer) { + // if no negative values and could also check range. + if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { + forceMinZero = true; + } + else { + forceMinZero = false; + if (s.fill && s.fillToZero && vmin < 0 && vmax > 0) { + forceZeroLine = true; + } + else { + forceZeroLine = false; + } + } + } + + // if not a bar and filling, use appropriate method. + else if (s.fill) { + if (vmin >= 0 && (s.fillToZero || dp > 0.1)) { + forceMinZero = true; + } + else if (vmin < 0 && vmax > 0 && s.fillToZero) { + forceMinZero = false; + forceZeroLine = true; + } + else { + forceMinZero = false; + forceZeroLine = false; + } + } + + // if not a bar and not filling, only change existing state + // if it doesn't make sense + else if (vmin < 0) { + forceMinZero = false; + } + } + } + + // check if we need make axis min at 0. + if (forceMinZero) { + // compute number of ticks + this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); + this.min = 0; + userMin = 0; + // what order is this range? + // what tick interval does that give us? + ti = max/(this.numberTicks-1); + temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); + if (ti/temp == parseInt(ti/temp, 10)) { + ti += temp; + } + this.tickInterval = Math.ceil(ti/temp) * temp; + this.max = this.tickInterval * (this.numberTicks - 1); + } + + // check if we need to make sure there is a tick at 0. + else if (forceZeroLine) { + // compute number of ticks + this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); + var ntmin = Math.ceil(Math.abs(min)/range*(this.numberTicks-1)); + var ntmax = this.numberTicks - 1 - ntmin; + ti = Math.max(Math.abs(min/ntmin), Math.abs(max/ntmax)); + temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); + this.tickInterval = Math.ceil(ti/temp) * temp; + this.max = this.tickInterval * ntmax; + this.min = -this.tickInterval * ntmin; + } + + // if nothing else, do autoscaling which will try to line up ticks across axes. + else { + if (this.numberTicks == null){ + if (this.tickInterval) { + this.numberTicks = 3 + Math.ceil(range / this.tickInterval); + } + else { + this.numberTicks = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); + } + } + + if (this.tickInterval == null) { + // get a tick interval + ti = range/(this.numberTicks - 1); + + if (ti < 1) { + temp = Math.pow(10, Math.abs(Math.floor(Math.log(ti)/Math.LN10))); + } + else { + temp = 1; + } + this.tickInterval = Math.ceil(ti*temp*this.pad)/temp; + } + else { + temp = 1 / this.tickInterval; + } + + // try to compute a nicer, more even tick interval + // temp = Math.pow(10, Math.floor(Math.log(ti)/Math.LN10)); + // this.tickInterval = Math.ceil(ti/temp) * temp; + rrange = this.tickInterval * (this.numberTicks - 1); + margin = (rrange - range)/2; + + if (this.min == null) { + this.min = Math.floor(temp*(min-margin))/temp; + } + if (this.max == null) { + this.max = this.min + rrange; + } + } + + // Compute a somewhat decent format string if it is needed. + // get precision of interval and determine a format string. + var sf = $.jqplot.getSignificantFigures(this.tickInterval); + + var fstr; + + // if we have only a whole number, use integer formatting + if (sf.digitsLeft >= sf.significantDigits) { + fstr = '%d'; + } + + else { + var temp = Math.max(0, 5 - sf.digitsLeft); + temp = Math.min(temp, sf.digitsRight); + fstr = '%.'+ temp + 'f'; + } + + this._autoFormatString = fstr; + } + + // Use the default algorithm which pads each axis to make the chart + // centered nicely on the grid. + else { + + rmin = (this.min != null) ? this.min : min - range*(this.padMin - 1); + rmax = (this.max != null) ? this.max : max + range*(this.padMax - 1); + range = rmax - rmin; + + if (this.numberTicks == null){ + // if tickInterval is specified by user, we will ignore computed maximum. + // max will be equal or greater to fit even # of ticks. + if (this.tickInterval != null) { + this.numberTicks = Math.ceil((rmax - rmin)/this.tickInterval)+1; + } + else if (dim > 100) { + this.numberTicks = parseInt(3+(dim-100)/75, 10); + } + else { + this.numberTicks = 2; + } + } + + if (this.tickInterval == null) { + this.tickInterval = range / (this.numberTicks-1); + } + + if (this.max == null) { + rmax = rmin + this.tickInterval*(this.numberTicks - 1); + } + if (this.min == null) { + rmin = rmax - this.tickInterval*(this.numberTicks - 1); + } + + // get precision of interval and determine a format string. + var sf = $.jqplot.getSignificantFigures(this.tickInterval); + + var fstr; + + // if we have only a whole number, use integer formatting + if (sf.digitsLeft >= sf.significantDigits) { + fstr = '%d'; + } + + else { + var temp = Math.max(0, 5 - sf.digitsLeft); + temp = Math.min(temp, sf.digitsRight); + fstr = '%.'+ temp + 'f'; + } + + + this._autoFormatString = fstr; + + this.min = rmin; + this.max = rmax; + } + + if (this.renderer.constructor == $.jqplot.LinearAxisRenderer && this._autoFormatString == '') { + // fix for misleading tick display with small range and low precision. + range = this.max - this.min; + // figure out precision + var temptick = new this.tickRenderer(this.tickOptions); + // use the tick formatString or, the default. + var fs = temptick.formatString || $.jqplot.config.defaultTickFormatString; + var fs = fs.match($.jqplot.sprintf.regex)[0]; + var precision = 0; + if (fs) { + if (fs.search(/[fFeEgGpP]/) > -1) { + var m = fs.match(/\%\.(\d{0,})?[eEfFgGpP]/); + if (m) { + precision = parseInt(m[1], 10); + } + else { + precision = 6; + } + } + else if (fs.search(/[di]/) > -1) { + precision = 0; + } + // fact will be <= 1; + var fact = Math.pow(10, -precision); + if (this.tickInterval < fact) { + // need to correct underrange + if (userNT == null && userTI == null) { + this.tickInterval = fact; + if (userMax == null && userMin == null) { + // this.min = Math.floor((this._dataBounds.min - this.tickInterval)/fact) * fact; + this.min = Math.floor(this._dataBounds.min/fact) * fact; + if (this.min == this._dataBounds.min) { + this.min = this._dataBounds.min - this.tickInterval; + } + // this.max = Math.ceil((this._dataBounds.max + this.tickInterval)/fact) * fact; + this.max = Math.ceil(this._dataBounds.max/fact) * fact; + if (this.max == this._dataBounds.max) { + this.max = this._dataBounds.max + this.tickInterval; + } + var n = (this.max - this.min)/this.tickInterval; + n = n.toFixed(11); + n = Math.ceil(n); + this.numberTicks = n + 1; + } + else if (userMax == null) { + // add one tick for top of range. + var n = (this._dataBounds.max - this.min) / this.tickInterval; + n = n.toFixed(11); + this.numberTicks = Math.ceil(n) + 2; + this.max = this.min + this.tickInterval * (this.numberTicks-1); + } + else if (userMin == null) { + // add one tick for bottom of range. + var n = (this.max - this._dataBounds.min) / this.tickInterval; + n = n.toFixed(11); + this.numberTicks = Math.ceil(n) + 2; + this.min = this.max - this.tickInterval * (this.numberTicks-1); + } + else { + // calculate a number of ticks so max is within axis scale + this.numberTicks = Math.ceil((userMax - userMin)/this.tickInterval) + 1; + // if user's min and max don't fit evenly in ticks, adjust. + // This takes care of cases such as user min set to 0, max set to 3.5 but tick + // format string set to %d (integer ticks) + this.min = Math.floor(userMin*Math.pow(10, precision))/Math.pow(10, precision); + this.max = Math.ceil(userMax*Math.pow(10, precision))/Math.pow(10, precision); + // this.max = this.min + this.tickInterval*(this.numberTicks-1); + this.numberTicks = Math.ceil((this.max - this.min)/this.tickInterval) + 1; + } + } + } + } + } + + } + + if (this._overrideFormatString && this._autoFormatString != '') { + this.tickOptions = this.tickOptions || {}; + this.tickOptions.formatString = this._autoFormatString; + } + + var t, to; + for (var i=0; i<this.numberTicks; i++){ + tt = this.min + i * this.tickInterval; + t = new this.tickRenderer(this.tickOptions); + // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); + + t.setTick(tt, this.name); + this._ticks.push(t); + + if (i < this.numberTicks - 1) { + for (var j=0; j<this.minorTicks; j++) { + tt += this.tickInterval/(this.minorTicks+1); + to = $.extend(true, {}, this.tickOptions, {name:this.name, value:tt, label:'', isMinorTick:true}); + t = new this.tickRenderer(to); + this._ticks.push(t); + } + } + t = null; + } + } + + if (this.tickInset) { + this.min = this.min - this.tickInset * this.tickInterval; + this.max = this.max + this.tickInset * this.tickInterval; + } + + ticks = null; + }; + + // Used to reset just the values of the ticks and then repack, which will + // recalculate the positioning functions. It is assuemd that the + // number of ticks is the same and the values of the new array are at the + // proper interval. + // This method needs to be called with the scope of an axis object, like: + // + // > plot.axes.yaxis.renderer.resetTickValues.call(plot.axes.yaxis, yarr); + // + $.jqplot.LinearAxisRenderer.prototype.resetTickValues = function(opts) { + if ($.isArray(opts) && opts.length == this._ticks.length) { + var t; + for (var i=0; i<opts.length; i++) { + t = this._ticks[i]; + t.value = opts[i]; + t.label = t.formatter(t.formatString, opts[i]); + t.label = t.prefix + t.label; + t._elem.html(t.label); + } + t = null; + this.min = $.jqplot.arrayMin(opts); + this.max = $.jqplot.arrayMax(opts); + this.pack(); + } + // Not implemented yet. + // else if ($.isPlainObject(opts)) { + // + // } + }; + + // called with scope of axis + $.jqplot.LinearAxisRenderer.prototype.pack = function(pos, offsets) { + // Add defaults for repacking from resetTickValues function. + pos = pos || {}; + offsets = offsets || this._offsets; + + var ticks = this._ticks; + var max = this.max; + var min = this.min; + var offmax = offsets.max; + var offmin = offsets.min; + var lshow = (this._label == null) ? false : this._label.show; + + for (var p in pos) { + this._elem.css(p, pos[p]); + } + + this._offsets = offsets; + // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. + var pixellength = offmax - offmin; + var unitlength = max - min; + + // point to unit and unit to point conversions references to Plot DOM element top left corner. + if (this.breakPoints) { + unitlength = unitlength - this.breakPoints[1] + this.breakPoints[0]; + + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + this.u2p = function(u){ + if (u > this.breakPoints[0] && u < this.breakPoints[1]){ + u = this.breakPoints[0]; + } + if (u <= this.breakPoints[0]) { + return (u - min) * pixellength / unitlength + offmin; + } + else { + return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength + offmin; + } + }; + + if (this.name.charAt(0) == 'x'){ + this.series_u2p = function(u){ + if (u > this.breakPoints[0] && u < this.breakPoints[1]){ + u = this.breakPoints[0]; + } + if (u <= this.breakPoints[0]) { + return (u - min) * pixellength / unitlength; + } + else { + return (u - this.breakPoints[1] + this.breakPoints[0] - min) * pixellength / unitlength; + } + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + else { + this.series_u2p = function(u){ + if (u > this.breakPoints[0] && u < this.breakPoints[1]){ + u = this.breakPoints[0]; + } + if (u >= this.breakPoints[1]) { + return (u - max) * pixellength / unitlength; + } + else { + return (u + this.breakPoints[1] - this.breakPoints[0] - max) * pixellength / unitlength; + } + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + } + else { + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + this.u2p = function(u){ + return (u - min) * pixellength / unitlength + offmin; + }; + + if (this.name == 'xaxis' || this.name == 'x2axis'){ + this.series_u2p = function(u){ + return (u - min) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + else { + this.series_u2p = function(u){ + return (u - max) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + } + + if (this.show) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'xaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + if (temp * t.angle < 0) { + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + } + // position at start + else { + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + } + break; + case 'end': + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + case 'start': + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + break; + case 'middle': + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + default: + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + } + } + else { + shim = -t.getWidth()/2; + } + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('left', val); + t.pack(); + } + } + if (lshow) { + var w = this._label._elem.outerWidth(true); + this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); + if (this.name == 'xaxis') { + this._label._elem.css('bottom', '0px'); + } + else { + this._label._elem.css('top', '0px'); + } + this._label.pack(); + } + } + else { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'yaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + case 'end': + if (temp * t.angle < 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'start': + if (t.angle > 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'middle': + // if (t.angle > 0) { + // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + // } + // else { + // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + // } + shim = -t.getHeight()/2; + break; + default: + shim = -t.getHeight()/2; + break; + } + } + else { + shim = -t.getHeight()/2; + } + + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('top', val); + t.pack(); + } + } + if (lshow) { + var h = this._label._elem.outerHeight(true); + this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); + if (this.name == 'yaxis') { + this._label._elem.css('left', '0px'); + } + else { + this._label._elem.css('right', '0px'); + } + this._label.pack(); + } + } + } + + ticks = null; + }; + + + /** + * The following code was generaously given to me a while back by Scott Prahl. + * He did a good job at computing axes min, max and number of ticks for the + * case where the user has not set any scale related parameters (tickInterval, + * numberTicks, min or max). I had ignored this use case for a long time, + * focusing on the more difficult case where user has set some option controlling + * tick generation. Anyway, about time I got this into jqPlot. + * Thanks Scott!! + */ + + /** + * Copyright (c) 2010 Scott Prahl + * The next three routines are currently available for use in all personal + * or commercial projects under both the MIT and GPL version 2.0 licenses. + * This means that you can choose the license that best suits your project + * and use it accordingly. + */ + + // A good format string depends on the interval. If the interval is greater + // than 1 then there is no need to show any decimal digits. If it is < 1.0, then + // use the magnitude of the interval to determine the number of digits to show. + function bestFormatString (interval) + { + var fstr; + interval = Math.abs(interval); + if (interval >= 10) { + fstr = '%d'; + } + + else if (interval > 1) { + if (interval === parseInt(interval, 10)) { + fstr = '%d'; + } + else { + fstr = '%.1f'; + } + } + + else { + var expv = -Math.floor(Math.log(interval)/Math.LN10); + fstr = '%.' + expv + 'f'; + } + + return fstr; + } + + var _factors = [0.1, 0.2, 0.3, 0.4, 0.5, 0.8, 1, 2, 3, 4, 5]; + + var _getLowerFactor = function(f) { + var i = _factors.indexOf(f); + if (i > 0) { + return _factors[i-1]; + } + else { + return _factors[_factors.length - 1] / 100; + } + }; + + var _getHigherFactor = function(f) { + var i = _factors.indexOf(f); + if (i < _factors.length-1) { + return _factors[i+1]; + } + else { + return _factors[0] * 100; + } + }; + + // Given a fixed minimum and maximum and a target number ot ticks + // figure out the best interval and + // return min, max, number ticks, format string and tick interval + function bestConstrainedInterval(min, max, nttarget) { + // run through possible number to ticks and see which interval is best + var low = Math.floor(nttarget/2); + var hi = Math.ceil(nttarget*1.5); + var badness = Number.MAX_VALUE; + var r = (max - min); + var temp; + var sd; + var bestNT; + var gsf = $.jqplot.getSignificantFigures; + var fsd; + var fs; + var currentNT; + var bestPrec; + + for (var i=0, l=hi-low+1; i<l; i++) { + currentNT = low + i; + temp = r/(currentNT-1); + sd = gsf(temp); + + temp = Math.abs(nttarget - currentNT) + sd.digitsRight; + if (temp < badness) { + badness = temp; + bestNT = currentNT; + bestPrec = sd.digitsRight; + } + else if (temp === badness) { + // let nicer ticks trump number ot ticks + if (sd.digitsRight < bestPrec) { + bestNT = currentNT; + bestPrec = sd.digitsRight; + } + } + + } + + fsd = Math.max(bestPrec, Math.max(gsf(min).digitsRight, gsf(max).digitsRight)); + if (fsd === 0) { + fs = '%d'; + } + else { + fs = '%.' + fsd + 'f'; + } + temp = r / (bestNT - 1); + // min, max, number ticks, format string, tick interval + return [min, max, bestNT, fs, temp]; + } + + // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n + // it is based soley on the range and number of ticks. So if user specifies + // number of ticks, use this. + function bestInterval(range, numberTicks) { + numberTicks = numberTicks || 7; + var minimum = range / (numberTicks - 1); + var magnitude = Math.pow(10, Math.floor(Math.log(minimum) / Math.LN10)); + var residual = minimum / magnitude; + var interval; + // "nicest" ranges are 1, 2, 5 or powers of these. + // for magnitudes below 1, only allow these. + if (magnitude < 1) { + if (residual > 5) { + interval = 10 * magnitude; + } + else if (residual > 2) { + interval = 5 * magnitude; + } + else if (residual > 1) { + interval = 2 * magnitude; + } + else { + interval = magnitude; + } + } + // for large ranges (whole integers), allow intervals like 3, 4 or powers of these. + // this helps a lot with poor choices for number of ticks. + else { + if (residual > 5) { + interval = 10 * magnitude; + } + else if (residual > 4) { + interval = 5 * magnitude; + } + else if (residual > 3) { + interval = 4 * magnitude; + } + else if (residual > 2) { + interval = 3 * magnitude; + } + else if (residual > 1) { + interval = 2 * magnitude; + } + else { + interval = magnitude; + } + } + + return interval; + } + + // This will return an interval of form 2 * 10^n, 5 * 10^n or 10 * 10^n + // it is based soley on the range of data, number of ticks must be computed later. + function bestLinearInterval(range, scalefact) { + scalefact = scalefact || 1; + var expv = Math.floor(Math.log(range)/Math.LN10); + var magnitude = Math.pow(10, expv); + // 0 < f < 10 + var f = range / magnitude; + var fact; + // for large plots, scalefact will decrease f and increase number of ticks. + // for small plots, scalefact will increase f and decrease number of ticks. + f = f/scalefact; + + // for large plots, smaller interval, more ticks. + if (f<=0.38) { + fact = 0.1; + } + else if (f<=1.6) { + fact = 0.2; + } + else if (f<=4.0) { + fact = 0.5; + } + else if (f<=8.0) { + fact = 1.0; + } + // for very small plots, larger interval, less ticks in number ticks + else if (f<=16.0) { + fact = 2; + } + else { + fact = 5; + } + + return fact*magnitude; + } + + function bestLinearComponents(range, scalefact) { + var expv = Math.floor(Math.log(range)/Math.LN10); + var magnitude = Math.pow(10, expv); + // 0 < f < 10 + var f = range / magnitude; + var interval; + var fact; + // for large plots, scalefact will decrease f and increase number of ticks. + // for small plots, scalefact will increase f and decrease number of ticks. + f = f/scalefact; + + // for large plots, smaller interval, more ticks. + if (f<=0.38) { + fact = 0.1; + } + else if (f<=1.6) { + fact = 0.2; + } + else if (f<=4.0) { + fact = 0.5; + } + else if (f<=8.0) { + fact = 1.0; + } + // for very small plots, larger interval, less ticks in number ticks + else if (f<=16.0) { + fact = 2; + } + // else if (f<=20.0) { + // fact = 3; + // } + // else if (f<=24.0) { + // fact = 4; + // } + else { + fact = 5; + } + + interval = fact * magnitude; + + return [interval, fact, magnitude]; + } + + // Given the min and max for a dataset, return suitable endpoints + // for the graphing, a good number for the number of ticks, and a + // format string so that extraneous digits are not displayed. + // returned is an array containing [min, max, nTicks, format] + $.jqplot.LinearTickGenerator = function(axis_min, axis_max, scalefact, numberTicks, keepMin, keepMax) { + // Set to preserve EITHER min OR max. + // If min is preserved, max must be free. + keepMin = (keepMin === null) ? false : keepMin; + keepMax = (keepMax === null || keepMin) ? false : keepMax; + // if endpoints are equal try to include zero otherwise include one + if (axis_min === axis_max) { + axis_max = (axis_max) ? 0 : 1; + } + + scalefact = scalefact || 1.0; + + // make sure range is positive + if (axis_max < axis_min) { + var a = axis_max; + axis_max = axis_min; + axis_min = a; + } + + var r = []; + var ss = bestLinearInterval(axis_max - axis_min, scalefact); + + var gsf = $.jqplot.getSignificantFigures; + + if (numberTicks == null) { + + // Figure out the axis min, max and number of ticks + // the min and max will be some multiple of the tick interval, + // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the + // axis min is negative, 0 will be a tick. + if (!keepMin && !keepMax) { + r[0] = Math.floor(axis_min / ss) * ss; // min + r[1] = Math.ceil(axis_max / ss) * ss; // max + r[2] = Math.round((r[1]-r[0])/ss+1.0); // number of ticks + r[3] = bestFormatString(ss); // format string + r[4] = ss; // tick Interval + } + + else if (keepMin) { + r[0] = axis_min; // min + r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks + r[1] = axis_min + (r[2] - 1) * ss; // max + var digitsMin = gsf(axis_min).digitsRight; + var digitsSS = gsf(ss).digitsRight; + if (digitsMin < digitsSS) { + r[3] = bestFormatString(ss); // format string + } + else { + r[3] = '%.' + digitsMin + 'f'; + } + r[4] = ss; // tick Interval + } + + else if (keepMax) { + r[1] = axis_max; // max + r[2] = Math.ceil((axis_max - axis_min) / ss + 1.0); // number of ticks + r[0] = axis_max - (r[2] - 1) * ss; // min + var digitsMax = gsf(axis_max).digitsRight; + var digitsSS = gsf(ss).digitsRight; + if (digitsMax < digitsSS) { + r[3] = bestFormatString(ss); // format string + } + else { + r[3] = '%.' + digitsMax + 'f'; + } + r[4] = ss; // tick Interval + } + } + + else { + var tempr = []; + + // Figure out the axis min, max and number of ticks + // the min and max will be some multiple of the tick interval, + // 1*10^n, 2*10^n or 5*10^n. This gaurantees that, if the + // axis min is negative, 0 will be a tick. + tempr[0] = Math.floor(axis_min / ss) * ss; // min + tempr[1] = Math.ceil(axis_max / ss) * ss; // max + tempr[2] = Math.round((tempr[1]-tempr[0])/ss+1.0); // number of ticks + tempr[3] = bestFormatString(ss); // format string + tempr[4] = ss; // tick Interval + + // first, see if we happen to get the right number of ticks + if (tempr[2] === numberTicks) { + r = tempr; + } + + else { + + var newti = bestInterval(tempr[1] - tempr[0], numberTicks); + + r[0] = tempr[0]; // min + r[2] = numberTicks; // number of ticks + r[4] = newti; // tick interval + r[3] = bestFormatString(newti); // format string + r[1] = r[0] + (r[2] - 1) * r[4]; // max + } + } + + return r; + }; + + $.jqplot.LinearTickGenerator.bestLinearInterval = bestLinearInterval; + $.jqplot.LinearTickGenerator.bestInterval = bestInterval; + $.jqplot.LinearTickGenerator.bestLinearComponents = bestLinearComponents; + $.jqplot.LinearTickGenerator.bestConstrainedInterval = bestConstrainedInterval; + + + // class: $.jqplot.MarkerRenderer + // The default jqPlot marker renderer, rendering the points on the line. + $.jqplot.MarkerRenderer = function(options){ + // Group: Properties + + // prop: show + // whether or not to show the marker. + this.show = true; + // prop: style + // One of diamond, circle, square, x, plus, dash, filledDiamond, filledCircle, filledSquare + this.style = 'filledCircle'; + // prop: lineWidth + // size of the line for non-filled markers. + this.lineWidth = 2; + // prop: size + // Size of the marker (diameter or circle, length of edge of square, etc.) + this.size = 9.0; + // prop: color + // color of marker. Will be set to color of series by default on init. + this.color = '#666666'; + // prop: shadow + // whether or not to draw a shadow on the line + this.shadow = true; + // prop: shadowAngle + // Shadow angle in degrees + this.shadowAngle = 45; + // prop: shadowOffset + // Shadow offset from line in pixels + this.shadowOffset = 1; + // prop: shadowDepth + // Number of times shadow is stroked, each stroke offset shadowOffset from the last. + this.shadowDepth = 3; + // prop: shadowAlpha + // Alpha channel transparency of shadow. 0 = transparent. + this.shadowAlpha = '0.07'; + // prop: shadowRenderer + // Renderer that will draws the shadows on the marker. + this.shadowRenderer = new $.jqplot.ShadowRenderer(); + // prop: shapeRenderer + // Renderer that will draw the marker. + this.shapeRenderer = new $.jqplot.ShapeRenderer(); + + $.extend(true, this, options); + }; + + $.jqplot.MarkerRenderer.prototype.init = function(options) { + $.extend(true, this, options); + var sdopt = {angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, lineWidth:this.lineWidth, depth:this.shadowDepth, closePath:true}; + if (this.style.indexOf('filled') != -1) { + sdopt.fill = true; + } + if (this.style.indexOf('ircle') != -1) { + sdopt.isarc = true; + sdopt.closePath = false; + } + this.shadowRenderer.init(sdopt); + + var shopt = {fill:false, isarc:false, strokeStyle:this.color, fillStyle:this.color, lineWidth:this.lineWidth, closePath:true}; + if (this.style.indexOf('filled') != -1) { + shopt.fill = true; + } + if (this.style.indexOf('ircle') != -1) { + shopt.isarc = true; + shopt.closePath = false; + } + this.shapeRenderer.init(shopt); + }; + + $.jqplot.MarkerRenderer.prototype.drawDiamond = function(x, y, ctx, fill, options) { + var stretch = 1.2; + var dx = this.size/2/stretch; + var dy = this.size/2*stretch; + var points = [[x-dx, y], [x, y+dy], [x+dx, y], [x, y-dy]]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points); + } + this.shapeRenderer.draw(ctx, points, options); + }; + + $.jqplot.MarkerRenderer.prototype.drawPlus = function(x, y, ctx, fill, options) { + var stretch = 1.0; + var dx = this.size/2*stretch; + var dy = this.size/2*stretch; + var points1 = [[x, y-dy], [x, y+dy]]; + var points2 = [[x+dx, y], [x-dx, y]]; + var opts = $.extend(true, {}, this.options, {closePath:false}); + if (this.shadow) { + this.shadowRenderer.draw(ctx, points1, {closePath:false}); + this.shadowRenderer.draw(ctx, points2, {closePath:false}); + } + this.shapeRenderer.draw(ctx, points1, opts); + this.shapeRenderer.draw(ctx, points2, opts); + }; + + $.jqplot.MarkerRenderer.prototype.drawX = function(x, y, ctx, fill, options) { + var stretch = 1.0; + var dx = this.size/2*stretch; + var dy = this.size/2*stretch; + var opts = $.extend(true, {}, this.options, {closePath:false}); + var points1 = [[x-dx, y-dy], [x+dx, y+dy]]; + var points2 = [[x-dx, y+dy], [x+dx, y-dy]]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points1, {closePath:false}); + this.shadowRenderer.draw(ctx, points2, {closePath:false}); + } + this.shapeRenderer.draw(ctx, points1, opts); + this.shapeRenderer.draw(ctx, points2, opts); + }; + + $.jqplot.MarkerRenderer.prototype.drawDash = function(x, y, ctx, fill, options) { + var stretch = 1.0; + var dx = this.size/2*stretch; + var dy = this.size/2*stretch; + var points = [[x-dx, y], [x+dx, y]]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points); + } + this.shapeRenderer.draw(ctx, points, options); + }; + + $.jqplot.MarkerRenderer.prototype.drawLine = function(p1, p2, ctx, fill, options) { + var points = [p1, p2]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points); + } + this.shapeRenderer.draw(ctx, points, options); + }; + + $.jqplot.MarkerRenderer.prototype.drawSquare = function(x, y, ctx, fill, options) { + var stretch = 1.0; + var dx = this.size/2/stretch; + var dy = this.size/2*stretch; + var points = [[x-dx, y-dy], [x-dx, y+dy], [x+dx, y+dy], [x+dx, y-dy]]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points); + } + this.shapeRenderer.draw(ctx, points, options); + }; + + $.jqplot.MarkerRenderer.prototype.drawCircle = function(x, y, ctx, fill, options) { + var radius = this.size/2; + var end = 2*Math.PI; + var points = [x, y, radius, 0, end, true]; + if (this.shadow) { + this.shadowRenderer.draw(ctx, points); + } + this.shapeRenderer.draw(ctx, points, options); + }; + + $.jqplot.MarkerRenderer.prototype.draw = function(x, y, ctx, options) { + options = options || {}; + // hack here b/c shape renderer uses canvas based color style options + // and marker uses css style names. + if (options.show == null || options.show != false) { + if (options.color && !options.fillStyle) { + options.fillStyle = options.color; + } + if (options.color && !options.strokeStyle) { + options.strokeStyle = options.color; + } + switch (this.style) { + case 'diamond': + this.drawDiamond(x,y,ctx, false, options); + break; + case 'filledDiamond': + this.drawDiamond(x,y,ctx, true, options); + break; + case 'circle': + this.drawCircle(x,y,ctx, false, options); + break; + case 'filledCircle': + this.drawCircle(x,y,ctx, true, options); + break; + case 'square': + this.drawSquare(x,y,ctx, false, options); + break; + case 'filledSquare': + this.drawSquare(x,y,ctx, true, options); + break; + case 'x': + this.drawX(x,y,ctx, true, options); + break; + case 'plus': + this.drawPlus(x,y,ctx, true, options); + break; + case 'dash': + this.drawDash(x,y,ctx, true, options); + break; + case 'line': + this.drawLine(x, y, ctx, false, options); + break; + default: + this.drawDiamond(x,y,ctx, false, options); + break; + } + } + }; + + // class: $.jqplot.shadowRenderer + // The default jqPlot shadow renderer, rendering shadows behind shapes. + $.jqplot.ShadowRenderer = function(options){ + // Group: Properties + + // prop: angle + // Angle of the shadow in degrees. Measured counter-clockwise from the x axis. + this.angle = 45; + // prop: offset + // Pixel offset at the given shadow angle of each shadow stroke from the last stroke. + this.offset = 1; + // prop: alpha + // alpha transparency of shadow stroke. + this.alpha = 0.07; + // prop: lineWidth + // width of the shadow line stroke. + this.lineWidth = 1.5; + // prop: lineJoin + // How line segments of the shadow are joined. + this.lineJoin = 'miter'; + // prop: lineCap + // how ends of the shadow line are rendered. + this.lineCap = 'round'; + // prop; closePath + // whether line path segment is closed upon itself. + this.closePath = false; + // prop: fill + // whether to fill the shape. + this.fill = false; + // prop: depth + // how many times the shadow is stroked. Each stroke will be offset by offset at angle degrees. + this.depth = 3; + this.strokeStyle = 'rgba(0,0,0,0.1)'; + // prop: isarc + // whether the shadow is an arc or not. + this.isarc = false; + + $.extend(true, this, options); + }; + + $.jqplot.ShadowRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + // function: draw + // draws an transparent black (i.e. gray) shadow. + // + // ctx - canvas drawing context + // points - array of points or [x, y, radius, start angle (rad), end angle (rad)] + $.jqplot.ShadowRenderer.prototype.draw = function(ctx, points, options) { + ctx.save(); + var opts = (options != null) ? options : {}; + var fill = (opts.fill != null) ? opts.fill : this.fill; + var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; + var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; + var offset = (opts.offset != null) ? opts.offset : this.offset; + var alpha = (opts.alpha != null) ? opts.alpha : this.alpha; + var depth = (opts.depth != null) ? opts.depth : this.depth; + var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; + var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; + ctx.lineWidth = (opts.lineWidth != null) ? opts.lineWidth : this.lineWidth; + ctx.lineJoin = (opts.lineJoin != null) ? opts.lineJoin : this.lineJoin; + ctx.lineCap = (opts.lineCap != null) ? opts.lineCap : this.lineCap; + ctx.strokeStyle = opts.strokeStyle || this.strokeStyle || 'rgba(0,0,0,'+alpha+')'; + ctx.fillStyle = opts.fillStyle || this.fillStyle || 'rgba(0,0,0,'+alpha+')'; + for (var j=0; j<depth; j++) { + var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); + ctx.translate(Math.cos(this.angle*Math.PI/180)*offset, Math.sin(this.angle*Math.PI/180)*offset); + ctxPattern.beginPath(); + if (isarc) { + ctx.arc(points[0], points[1], points[2], points[3], points[4], true); + } + else if (fillRect) { + if (fillRect) { + ctx.fillRect(points[0], points[1], points[2], points[3]); + } + } + else if (points && points.length){ + var move = true; + for (var i=0; i<points.length; i++) { + // skip to the first non-null point and move to it. + if (points[i][0] != null && points[i][1] != null) { + if (move) { + ctxPattern.moveTo(points[i][0], points[i][1]); + move = false; + } + else { + ctxPattern.lineTo(points[i][0], points[i][1]); + } + } + else { + move = true; + } + } + + } + if (closePath) { + ctxPattern.closePath(); + } + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + } + ctx.restore(); + }; + + // class: $.jqplot.shapeRenderer + // The default jqPlot shape renderer. Given a set of points will + // plot them and either stroke a line (fill = false) or fill them (fill = true). + // If a filled shape is desired, closePath = true must also be set to close + // the shape. + $.jqplot.ShapeRenderer = function(options){ + + this.lineWidth = 1.5; + // prop: linePattern + // line pattern 'dashed', 'dotted', 'solid', some combination + // of '-' and '.' characters such as '.-.' or a numerical array like + // [draw, skip, draw, skip, ...] such as [1, 10] to draw a dotted line, + // [1, 10, 20, 10] to draw a dot-dash line, and so on. + this.linePattern = 'solid'; + // prop: lineJoin + // How line segments of the shadow are joined. + this.lineJoin = 'miter'; + // prop: lineCap + // how ends of the shadow line are rendered. + this.lineCap = 'round'; + // prop; closePath + // whether line path segment is closed upon itself. + this.closePath = false; + // prop: fill + // whether to fill the shape. + this.fill = false; + // prop: isarc + // whether the shadow is an arc or not. + this.isarc = false; + // prop: fillRect + // true to draw shape as a filled rectangle. + this.fillRect = false; + // prop: strokeRect + // true to draw shape as a stroked rectangle. + this.strokeRect = false; + // prop: clearRect + // true to cear a rectangle. + this.clearRect = false; + // prop: strokeStyle + // css color spec for the stoke style + this.strokeStyle = '#999999'; + // prop: fillStyle + // css color spec for the fill style. + this.fillStyle = '#999999'; + + $.extend(true, this, options); + }; + + $.jqplot.ShapeRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + // function: draw + // draws the shape. + // + // ctx - canvas drawing context + // points - array of points for shapes or + // [x, y, width, height] for rectangles or + // [x, y, radius, start angle (rad), end angle (rad)] for circles and arcs. + $.jqplot.ShapeRenderer.prototype.draw = function(ctx, points, options) { + ctx.save(); + var opts = (options != null) ? options : {}; + var fill = (opts.fill != null) ? opts.fill : this.fill; + var closePath = (opts.closePath != null) ? opts.closePath : this.closePath; + var fillRect = (opts.fillRect != null) ? opts.fillRect : this.fillRect; + var strokeRect = (opts.strokeRect != null) ? opts.strokeRect : this.strokeRect; + var clearRect = (opts.clearRect != null) ? opts.clearRect : this.clearRect; + var isarc = (opts.isarc != null) ? opts.isarc : this.isarc; + var linePattern = (opts.linePattern != null) ? opts.linePattern : this.linePattern; + var ctxPattern = $.jqplot.LinePattern(ctx, linePattern); + ctx.lineWidth = opts.lineWidth || this.lineWidth; + ctx.lineJoin = opts.lineJoin || this.lineJoin; + ctx.lineCap = opts.lineCap || this.lineCap; + ctx.strokeStyle = (opts.strokeStyle || opts.color) || this.strokeStyle; + ctx.fillStyle = opts.fillStyle || this.fillStyle; + ctx.beginPath(); + if (isarc) { + ctx.arc(points[0], points[1], points[2], points[3], points[4], true); + if (closePath) { + ctx.closePath(); + } + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + ctx.restore(); + return; + } + else if (clearRect) { + ctx.clearRect(points[0], points[1], points[2], points[3]); + ctx.restore(); + return; + } + else if (fillRect || strokeRect) { + if (fillRect) { + ctx.fillRect(points[0], points[1], points[2], points[3]); + } + if (strokeRect) { + ctx.strokeRect(points[0], points[1], points[2], points[3]); + ctx.restore(); + return; + } + } + else if (points && points.length){ + var move = true; + for (var i=0; i<points.length; i++) { + // skip to the first non-null point and move to it. + if (points[i][0] != null && points[i][1] != null) { + if (move) { + ctxPattern.moveTo(points[i][0], points[i][1]); + move = false; + } + else { + ctxPattern.lineTo(points[i][0], points[i][1]); + } + } + else { + move = true; + } + } + if (closePath) { + ctxPattern.closePath(); + } + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + } + ctx.restore(); + }; + + // class $.jqplot.TableLegendRenderer + // The default legend renderer for jqPlot. + $.jqplot.TableLegendRenderer = function(){ + // + }; + + $.jqplot.TableLegendRenderer.prototype.init = function(options) { + $.extend(true, this, options); + }; + + $.jqplot.TableLegendRenderer.prototype.addrow = function (label, color, pad, reverse) { + var rs = (pad) ? this.rowSpacing+'px' : '0px'; + var tr; + var td; + var elem; + var div0; + var div1; + elem = document.createElement('tr'); + tr = $(elem); + tr.addClass('jqplot-table-legend'); + elem = null; + + if (reverse){ + tr.prependTo(this._elem); + } + + else{ + tr.appendTo(this._elem); + } + + if (this.showSwatches) { + td = $(document.createElement('td')); + td.addClass('jqplot-table-legend jqplot-table-legend-swatch'); + td.css({textAlign: 'center', paddingTop: rs}); + + div0 = $(document.createElement('div')); + div0.addClass('jqplot-table-legend-swatch-outline'); + div1 = $(document.createElement('div')); + div1.addClass('jqplot-table-legend-swatch'); + div1.css({backgroundColor: color, borderColor: color}); + + tr.append(td.append(div0.append(div1))); + + // $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+ + // '</div></td>').appendTo(tr); + } + if (this.showLabels) { + td = $(document.createElement('td')); + td.addClass('jqplot-table-legend jqplot-table-legend-label'); + td.css('paddingTop', rs); + tr.append(td); + + // elem = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + // elem.appendTo(tr); + if (this.escapeHtml) { + td.text(label); + } + else { + td.html(label); + } + } + td = null; + div0 = null; + div1 = null; + tr = null; + elem = null; + }; + + // called with scope of legend + $.jqplot.TableLegendRenderer.prototype.draw = function() { + if (this._elem) { + this._elem.emptyForce(); + this._elem = null; + } + + if (this.show) { + var series = this._series; + // make a table. one line label per row. + var elem = document.createElement('table'); + this._elem = $(elem); + this._elem.addClass('jqplot-table-legend'); + + var ss = {position:'absolute'}; + if (this.background) { + ss['background'] = this.background; + } + if (this.border) { + ss['border'] = this.border; + } + if (this.fontSize) { + ss['fontSize'] = this.fontSize; + } + if (this.fontFamily) { + ss['fontFamily'] = this.fontFamily; + } + if (this.textColor) { + ss['textColor'] = this.textColor; + } + if (this.marginTop != null) { + ss['marginTop'] = this.marginTop; + } + if (this.marginBottom != null) { + ss['marginBottom'] = this.marginBottom; + } + if (this.marginLeft != null) { + ss['marginLeft'] = this.marginLeft; + } + if (this.marginRight != null) { + ss['marginRight'] = this.marginRight; + } + + + var pad = false, + reverse = false, + s; + for (var i = 0; i< series.length; i++) { + s = series[i]; + if (s._stack || s.renderer.constructor == $.jqplot.BezierCurveRenderer){ + reverse = true; + } + if (s.show && s.showLabel) { + var lt = this.labels[i] || s.label.toString(); + if (lt) { + var color = s.color; + if (reverse && i < series.length - 1){ + pad = true; + } + else if (reverse && i == series.length - 1){ + pad = false; + } + this.renderer.addrow.call(this, lt, color, pad, reverse); + pad = true; + } + // let plugins add more rows to legend. Used by trend line plugin. + for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { + var item = $.jqplot.addLegendRowHooks[j].call(this, s); + if (item) { + this.renderer.addrow.call(this, item.label, item.color, pad); + pad = true; + } + } + lt = null; + } + } + } + return this._elem; + }; + + $.jqplot.TableLegendRenderer.prototype.pack = function(offsets) { + if (this.show) { + if (this.placement == 'insideGrid') { + switch (this.location) { + case 'nw': + var a = offsets.left; + var b = offsets.top; + this._elem.css('left', a); + this._elem.css('top', b); + break; + case 'n': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = offsets.top; + this._elem.css('left', a); + this._elem.css('top', b); + break; + case 'ne': + var a = offsets.right; + var b = offsets.top; + this._elem.css({right:a, top:b}); + break; + case 'e': + var a = offsets.right; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({right:a, top:b}); + break; + case 'se': + var a = offsets.right; + var b = offsets.bottom; + this._elem.css({right:a, bottom:b}); + break; + case 's': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = offsets.bottom; + this._elem.css({left:a, bottom:b}); + break; + case 'sw': + var a = offsets.left; + var b = offsets.bottom; + this._elem.css({left:a, bottom:b}); + break; + case 'w': + var a = offsets.left; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({left:a, top:b}); + break; + default: // same as 'se' + var a = offsets.right; + var b = offsets.bottom; + this._elem.css({right:a, bottom:b}); + break; + } + + } + else if (this.placement == 'outside'){ + switch (this.location) { + case 'nw': + var a = this._plotDimensions.width - offsets.left; + var b = offsets.top; + this._elem.css('right', a); + this._elem.css('top', b); + break; + case 'n': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = this._plotDimensions.height - offsets.top; + this._elem.css('left', a); + this._elem.css('bottom', b); + break; + case 'ne': + var a = this._plotDimensions.width - offsets.right; + var b = offsets.top; + this._elem.css({left:a, top:b}); + break; + case 'e': + var a = this._plotDimensions.width - offsets.right; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({left:a, top:b}); + break; + case 'se': + var a = this._plotDimensions.width - offsets.right; + var b = offsets.bottom; + this._elem.css({left:a, bottom:b}); + break; + case 's': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = this._plotDimensions.height - offsets.bottom; + this._elem.css({left:a, top:b}); + break; + case 'sw': + var a = this._plotDimensions.width - offsets.left; + var b = offsets.bottom; + this._elem.css({right:a, bottom:b}); + break; + case 'w': + var a = this._plotDimensions.width - offsets.left; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({right:a, top:b}); + break; + default: // same as 'se' + var a = offsets.right; + var b = offsets.bottom; + this._elem.css({right:a, bottom:b}); + break; + } + } + else { + switch (this.location) { + case 'nw': + this._elem.css({left:0, top:offsets.top}); + break; + case 'n': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + this._elem.css({left: a, top:offsets.top}); + break; + case 'ne': + this._elem.css({right:0, top:offsets.top}); + break; + case 'e': + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({right:offsets.right, top:b}); + break; + case 'se': + this._elem.css({right:offsets.right, bottom:offsets.bottom}); + break; + case 's': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + this._elem.css({left: a, bottom:offsets.bottom}); + break; + case 'sw': + this._elem.css({left:offsets.left, bottom:offsets.bottom}); + break; + case 'w': + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({left:offsets.left, top:b}); + break; + default: // same as 'se' + this._elem.css({right:offsets.right, bottom:offsets.bottom}); + break; + } + } + } + }; + + /** + * Class: $.jqplot.ThemeEngine + * Theme Engine provides a programatic way to change some of the more + * common jqplot styling options such as fonts, colors and grid options. + * A theme engine instance is created with each plot. The theme engine + * manages a collection of themes which can be modified, added to, or + * applied to the plot. + * + * The themeEngine class is not instantiated directly. + * When a plot is initialized, the current plot options are scanned + * an a default theme named "Default" is created. This theme is + * used as the basis for other themes added to the theme engine and + * is always available. + * + * A theme is a simple javascript object with styling parameters for + * various entities of the plot. A theme has the form: + * + * + * > { + * > _name:f "Default", + * > target: { + * > backgroundColor: "transparent" + * > }, + * > legend: { + * > textColor: null, + * > fontFamily: null, + * > fontSize: null, + * > border: null, + * > background: null + * > }, + * > title: { + * > textColor: "rgb(102, 102, 102)", + * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", + * > fontSize: "19.2px", + * > textAlign: "center" + * > }, + * > seriesStyles: {}, + * > series: [{ + * > color: "#4bb2c5", + * > lineWidth: 2.5, + * > linePattern: "solid", + * > shadow: true, + * > fillColor: "#4bb2c5", + * > showMarker: true, + * > markerOptions: { + * > color: "#4bb2c5", + * > show: true, + * > style: 'filledCircle', + * > lineWidth: 1.5, + * > size: 4, + * > shadow: true + * > } + * > }], + * > grid: { + * > drawGridlines: true, + * > gridLineColor: "#cccccc", + * > gridLineWidth: 1, + * > backgroundColor: "#fffdf6", + * > borderColor: "#999999", + * > borderWidth: 2, + * > shadow: true + * > }, + * > axesStyles: { + * > label: {}, + * > ticks: {} + * > }, + * > axes: { + * > xaxis: { + * > borderColor: "#999999", + * > borderWidth: 2, + * > ticks: { + * > show: true, + * > showGridline: true, + * > showLabel: true, + * > showMark: true, + * > size: 4, + * > textColor: "", + * > whiteSpace: "nowrap", + * > fontSize: "12px", + * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" + * > }, + * > label: { + * > textColor: "rgb(102, 102, 102)", + * > whiteSpace: "normal", + * > fontSize: "14.6667px", + * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif", + * > fontWeight: "400" + * > } + * > }, + * > yaxis: { + * > borderColor: "#999999", + * > borderWidth: 2, + * > ticks: { + * > show: true, + * > showGridline: true, + * > showLabel: true, + * > showMark: true, + * > size: 4, + * > textColor: "", + * > whiteSpace: "nowrap", + * > fontSize: "12px", + * > fontFamily: "'Trebuchet MS',Arial,Helvetica,sans-serif" + * > }, + * > label: { + * > textColor: null, + * > whiteSpace: null, + * > fontSize: null, + * > fontFamily: null, + * > fontWeight: null + * > } + * > }, + * > x2axis: {... + * > }, + * > ... + * > y9axis: {... + * > } + * > } + * > } + * + * "seriesStyles" is a style object that will be applied to all series in the plot. + * It will forcibly override any styles applied on the individual series. "axesStyles" is + * a style object that will be applied to all axes in the plot. It will also forcibly + * override any styles on the individual axes. + * + * The example shown above has series options for a line series. Options for other + * series types are shown below: + * + * Bar Series: + * + * > { + * > color: "#4bb2c5", + * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], + * > lineWidth: 2.5, + * > shadow: true, + * > barPadding: 2, + * > barMargin: 10, + * > barWidth: 15.09375, + * > highlightColors: ["rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)", "rgb(129,201,214)"] + * > } + * + * Pie Series: + * + * > { + * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], + * > padding: 20, + * > sliceMargin: 0, + * > fill: true, + * > shadow: true, + * > startAngle: 0, + * > lineWidth: 2.5, + * > highlightColors: ["rgb(129,201,214)", "rgb(240,189,104)", "rgb(214,202,165)", "rgb(137,180,158)", "rgb(168,180,137)", "rgb(180,174,89)", "rgb(180,113,161)", "rgb(129,141,236)", "rgb(227,205,120)", "rgb(255,138,76)", "rgb(76,169,219)", "rgb(215,126,190)", "rgb(220,232,135)", "rgb(200,167,96)", "rgb(103,202,235)", "rgb(208,154,215)"] + * > } + * + * Funnel Series: + * + * > { + * > color: "#4bb2c5", + * > lineWidth: 2, + * > shadow: true, + * > padding: { + * > top: 20, + * > right: 20, + * > bottom: 20, + * > left: 20 + * > }, + * > sectionMargin: 6, + * > seriesColors: ["#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"], + * > highlightColors: ["rgb(147,208,220)", "rgb(242,199,126)", "rgb(220,210,178)", "rgb(154,191,172)", "rgb(180,191,154)", "rgb(191,186,112)", "rgb(191,133,174)", "rgb(147,157,238)", "rgb(231,212,139)", "rgb(255,154,102)", "rgb(102,181,224)", "rgb(221,144,199)", "rgb(225,235,152)", "rgb(200,167,96)", "rgb(124,210,238)", "rgb(215,169,221)"] + * > } + * + */ + $.jqplot.ThemeEngine = function(){ + // Group: Properties + // + // prop: themes + // hash of themes managed by the theme engine. + // Indexed by theme name. + this.themes = {}; + // prop: activeTheme + // Pointer to currently active theme + this.activeTheme=null; + + }; + + // called with scope of plot + $.jqplot.ThemeEngine.prototype.init = function() { + // get the Default theme from the current plot settings. + var th = new $.jqplot.Theme({_name:'Default'}); + var n, i, nn; + + for (n in th.target) { + if (n == "textColor") { + th.target[n] = this.target.css('color'); + } + else { + th.target[n] = this.target.css(n); + } + } + + if (this.title.show && this.title._elem) { + for (n in th.title) { + if (n == "textColor") { + th.title[n] = this.title._elem.css('color'); + } + else { + th.title[n] = this.title._elem.css(n); + } + } + } + + for (n in th.grid) { + th.grid[n] = this.grid[n]; + } + if (th.grid.backgroundColor == null && this.grid.background != null) { + th.grid.backgroundColor = this.grid.background; + } + if (this.legend.show && this.legend._elem) { + for (n in th.legend) { + if (n == 'textColor') { + th.legend[n] = this.legend._elem.css('color'); + } + else { + th.legend[n] = this.legend._elem.css(n); + } + } + } + var s; + + for (i=0; i<this.series.length; i++) { + s = this.series[i]; + if (s.renderer.constructor == $.jqplot.LineRenderer) { + th.series.push(new LineSeriesProperties()); + } + else if (s.renderer.constructor == $.jqplot.BarRenderer) { + th.series.push(new BarSeriesProperties()); + } + else if (s.renderer.constructor == $.jqplot.PieRenderer) { + th.series.push(new PieSeriesProperties()); + } + else if (s.renderer.constructor == $.jqplot.DonutRenderer) { + th.series.push(new DonutSeriesProperties()); + } + else if (s.renderer.constructor == $.jqplot.FunnelRenderer) { + th.series.push(new FunnelSeriesProperties()); + } + else if (s.renderer.constructor == $.jqplot.MeterGaugeRenderer) { + th.series.push(new MeterSeriesProperties()); + } + else { + th.series.push({}); + } + for (n in th.series[i]) { + th.series[i][n] = s[n]; + } + } + var a, ax; + for (n in this.axes) { + ax = this.axes[n]; + a = th.axes[n] = new AxisProperties(); + a.borderColor = ax.borderColor; + a.borderWidth = ax.borderWidth; + if (ax._ticks && ax._ticks[0]) { + for (nn in a.ticks) { + if (ax._ticks[0].hasOwnProperty(nn)) { + a.ticks[nn] = ax._ticks[0][nn]; + } + else if (ax._ticks[0]._elem){ + a.ticks[nn] = ax._ticks[0]._elem.css(nn); + } + } + } + if (ax._label && ax._label.show) { + for (nn in a.label) { + // a.label[nn] = ax._label._elem.css(nn); + if (ax._label[nn]) { + a.label[nn] = ax._label[nn]; + } + else if (ax._label._elem){ + if (nn == 'textColor') { + a.label[nn] = ax._label._elem.css('color'); + } + else { + a.label[nn] = ax._label._elem.css(nn); + } + } + } + } + } + this.themeEngine._add(th); + this.themeEngine.activeTheme = this.themeEngine.themes[th._name]; + }; + /** + * Group: methods + * + * method: get + * + * Get and return the named theme or the active theme if no name given. + * + * parameter: + * + * name - name of theme to get. + * + * returns: + * + * Theme instance of given name. + */ + $.jqplot.ThemeEngine.prototype.get = function(name) { + if (!name) { + // return the active theme + return this.activeTheme; + } + else { + return this.themes[name]; + } + }; + + function numericalOrder(a,b) { return a-b; } + + /** + * method: getThemeNames + * + * Return the list of theme names in this manager in alpha-numerical order. + * + * parameter: + * + * None + * + * returns: + * + * A the list of theme names in this manager in alpha-numerical order. + */ + $.jqplot.ThemeEngine.prototype.getThemeNames = function() { + var tn = []; + for (var n in this.themes) { + tn.push(n); + } + return tn.sort(numericalOrder); + }; + + /** + * method: getThemes + * + * Return a list of themes in alpha-numerical order by name. + * + * parameter: + * + * None + * + * returns: + * + * A list of themes in alpha-numerical order by name. + */ + $.jqplot.ThemeEngine.prototype.getThemes = function() { + var tn = []; + var themes = []; + for (var n in this.themes) { + tn.push(n); + } + tn.sort(numericalOrder); + for (var i=0; i<tn.length; i++) { + themes.push(this.themes[tn[i]]); + } + return themes; + }; + + $.jqplot.ThemeEngine.prototype.activate = function(plot, name) { + // sometimes need to redraw whole plot. + var redrawPlot = false; + if (!name && this.activeTheme && this.activeTheme._name) { + name = this.activeTheme._name; + } + if (!this.themes.hasOwnProperty(name)) { + throw new Error("No theme of that name"); + } + else { + var th = this.themes[name]; + this.activeTheme = th; + var val, checkBorderColor = false, checkBorderWidth = false; + var arr = ['xaxis', 'x2axis', 'yaxis', 'y2axis']; + + for (i=0; i<arr.length; i++) { + var ax = arr[i]; + if (th.axesStyles.borderColor != null) { + plot.axes[ax].borderColor = th.axesStyles.borderColor; + } + if (th.axesStyles.borderWidth != null) { + plot.axes[ax].borderWidth = th.axesStyles.borderWidth; + } + } + + for (var axname in plot.axes) { + var axis = plot.axes[axname]; + if (axis.show) { + var thaxis = th.axes[axname] || {}; + var thaxstyle = th.axesStyles; + var thax = $.jqplot.extend(true, {}, thaxis, thaxstyle); + val = (th.axesStyles.borderColor != null) ? th.axesStyles.borderColor : thax.borderColor; + if (thax.borderColor != null) { + axis.borderColor = thax.borderColor; + redrawPlot = true; + } + val = (th.axesStyles.borderWidth != null) ? th.axesStyles.borderWidth : thax.borderWidth; + if (thax.borderWidth != null) { + axis.borderWidth = thax.borderWidth; + redrawPlot = true; + } + if (axis._ticks && axis._ticks[0]) { + for (var nn in thax.ticks) { + // val = null; + // if (th.axesStyles.ticks && th.axesStyles.ticks[nn] != null) { + // val = th.axesStyles.ticks[nn]; + // } + // else if (thax.ticks[nn] != null){ + // val = thax.ticks[nn] + // } + val = thax.ticks[nn]; + if (val != null) { + axis.tickOptions[nn] = val; + axis._ticks = []; + redrawPlot = true; + } + } + } + if (axis._label && axis._label.show) { + for (var nn in thax.label) { + // val = null; + // if (th.axesStyles.label && th.axesStyles.label[nn] != null) { + // val = th.axesStyles.label[nn]; + // } + // else if (thax.label && thax.label[nn] != null){ + // val = thax.label[nn] + // } + val = thax.label[nn]; + if (val != null) { + axis.labelOptions[nn] = val; + redrawPlot = true; + } + } + } + + } + } + + for (var n in th.grid) { + if (th.grid[n] != null) { + plot.grid[n] = th.grid[n]; + } + } + if (!redrawPlot) { + plot.grid.draw(); + } + + if (plot.legend.show) { + for (n in th.legend) { + if (th.legend[n] != null) { + plot.legend[n] = th.legend[n]; + } + } + } + if (plot.title.show) { + for (n in th.title) { + if (th.title[n] != null) { + plot.title[n] = th.title[n]; + } + } + } + + var i; + for (i=0; i<th.series.length; i++) { + var opts = {}; + var redrawSeries = false; + for (n in th.series[i]) { + val = (th.seriesStyles[n] != null) ? th.seriesStyles[n] : th.series[i][n]; + if (val != null) { + opts[n] = val; + if (n == 'color') { + plot.series[i].renderer.shapeRenderer.fillStyle = val; + plot.series[i].renderer.shapeRenderer.strokeStyle = val; + plot.series[i][n] = val; + } + else if ((n == 'lineWidth') || (n == 'linePattern')) { + plot.series[i].renderer.shapeRenderer[n] = val; + plot.series[i][n] = val; + } + else if (n == 'markerOptions') { + merge (plot.series[i].markerOptions, val); + merge (plot.series[i].markerRenderer, val); + } + else { + plot.series[i][n] = val; + } + redrawPlot = true; + } + } + } + + if (redrawPlot) { + plot.target.empty(); + plot.draw(); + } + + for (n in th.target) { + if (th.target[n] != null) { + plot.target.css(n, th.target[n]); + } + } + } + + }; + + $.jqplot.ThemeEngine.prototype._add = function(theme, name) { + if (name) { + theme._name = name; + } + if (!theme._name) { + theme._name = Date.parse(new Date()); + } + if (!this.themes.hasOwnProperty(theme._name)) { + this.themes[theme._name] = theme; + } + else { + throw new Error("jqplot.ThemeEngine Error: Theme already in use"); + } + }; + + // method remove + // Delete the named theme, return true on success, false on failure. + + + /** + * method: remove + * + * Remove the given theme from the themeEngine. + * + * parameters: + * + * name - name of the theme to remove. + * + * returns: + * + * true on success, false on failure. + */ + $.jqplot.ThemeEngine.prototype.remove = function(name) { + if (name == 'Default') { + return false; + } + return delete this.themes[name]; + }; + + /** + * method: newTheme + * + * Create a new theme based on the default theme, adding it the themeEngine. + * + * parameters: + * + * name - name of the new theme. + * obj - optional object of styles to be applied to this new theme. + * + * returns: + * + * new Theme object. + */ + $.jqplot.ThemeEngine.prototype.newTheme = function(name, obj) { + if (typeof(name) == 'object') { + obj = obj || name; + name = null; + } + if (obj && obj._name) { + name = obj._name; + } + else { + name = name || Date.parse(new Date()); + } + // var th = new $.jqplot.Theme(name); + var th = this.copy(this.themes['Default']._name, name); + $.jqplot.extend(th, obj); + return th; + }; + + // function clone(obj) { + // return eval(obj.toSource()); + // } + + function clone(obj){ + if(obj == null || typeof(obj) != 'object'){ + return obj; + } + + var temp = new obj.constructor(); + for(var key in obj){ + temp[key] = clone(obj[key]); + } + return temp; + } + + $.jqplot.clone = clone; + + function merge(obj1, obj2) { + if (obj2 == null || typeof(obj2) != 'object') { + return; + } + for (var key in obj2) { + if (key == 'highlightColors') { + obj1[key] = clone(obj2[key]); + } + if (obj2[key] != null && typeof(obj2[key]) == 'object') { + if (!obj1.hasOwnProperty(key)) { + obj1[key] = {}; + } + merge(obj1[key], obj2[key]); + } + else { + obj1[key] = obj2[key]; + } + } + } + + $.jqplot.merge = merge; + + // Use the jQuery 1.3.2 extend function since behaviour in jQuery 1.4 seems problematic + $.jqplot.extend = function() { + // copy reference to target object + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !toString.call(target) === "[object Function]" ) { + target = {}; + } + + for ( ; i < length; i++ ){ + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( var name in options ) { + var src = target[ name ], copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging object values + if ( deep && copy && typeof copy === "object" && !copy.nodeType ) { + target[ name ] = $.jqplot.extend( deep, + // Never move original objects, clone them + src || ( copy.length != null ? [ ] : { } ) + , copy ); + } + // Don't bring in undefined values + else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + // Return the modified object + return target; + }; + + /** + * method: rename + * + * Rename a theme. + * + * parameters: + * + * oldName - current name of the theme. + * newName - desired name of the theme. + * + * returns: + * + * new Theme object. + */ + $.jqplot.ThemeEngine.prototype.rename = function (oldName, newName) { + if (oldName == 'Default' || newName == 'Default') { + throw new Error ("jqplot.ThemeEngine Error: Cannot rename from/to Default"); + } + if (this.themes.hasOwnProperty(newName)) { + throw new Error ("jqplot.ThemeEngine Error: New name already in use."); + } + else if (this.themes.hasOwnProperty(oldName)) { + var th = this.copy (oldName, newName); + this.remove(oldName); + return th; + } + throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid"); + }; + + /** + * method: copy + * + * Create a copy of an existing theme in the themeEngine, adding it the themeEngine. + * + * parameters: + * + * sourceName - name of the existing theme. + * targetName - name of the copy. + * obj - optional object of style parameter to apply to the new theme. + * + * returns: + * + * new Theme object. + */ + $.jqplot.ThemeEngine.prototype.copy = function (sourceName, targetName, obj) { + if (targetName == 'Default') { + throw new Error ("jqplot.ThemeEngine Error: Cannot copy over Default theme"); + } + if (!this.themes.hasOwnProperty(sourceName)) { + var s = "jqplot.ThemeEngine Error: Source name invalid"; + throw new Error(s); + } + if (this.themes.hasOwnProperty(targetName)) { + var s = "jqplot.ThemeEngine Error: Target name invalid"; + throw new Error(s); + } + else { + var th = clone(this.themes[sourceName]); + th._name = targetName; + $.jqplot.extend(true, th, obj); + this._add(th); + return th; + } + }; + + + $.jqplot.Theme = function(name, obj) { + if (typeof(name) == 'object') { + obj = obj || name; + name = null; + } + name = name || Date.parse(new Date()); + this._name = name; + this.target = { + backgroundColor: null + }; + this.legend = { + textColor: null, + fontFamily: null, + fontSize: null, + border: null, + background: null + }; + this.title = { + textColor: null, + fontFamily: null, + fontSize: null, + textAlign: null + }; + this.seriesStyles = {}; + this.series = []; + this.grid = { + drawGridlines: null, + gridLineColor: null, + gridLineWidth: null, + backgroundColor: null, + borderColor: null, + borderWidth: null, + shadow: null + }; + this.axesStyles = {label:{}, ticks:{}}; + this.axes = {}; + if (typeof(obj) == 'string') { + this._name = obj; + } + else if(typeof(obj) == 'object') { + $.jqplot.extend(true, this, obj); + } + }; + + var AxisProperties = function() { + this.borderColor = null; + this.borderWidth = null; + this.ticks = new AxisTicks(); + this.label = new AxisLabel(); + }; + + var AxisTicks = function() { + this.show = null; + this.showGridline = null; + this.showLabel = null; + this.showMark = null; + this.size = null; + this.textColor = null; + this.whiteSpace = null; + this.fontSize = null; + this.fontFamily = null; + }; + + var AxisLabel = function() { + this.textColor = null; + this.whiteSpace = null; + this.fontSize = null; + this.fontFamily = null; + this.fontWeight = null; + }; + + var LineSeriesProperties = function() { + this.color=null; + this.lineWidth=null; + this.linePattern=null; + this.shadow=null; + this.fillColor=null; + this.showMarker=null; + this.markerOptions = new MarkerOptions(); + }; + + var MarkerOptions = function() { + this.show = null; + this.style = null; + this.lineWidth = null; + this.size = null; + this.color = null; + this.shadow = null; + }; + + var BarSeriesProperties = function() { + this.color=null; + this.seriesColors=null; + this.lineWidth=null; + this.shadow=null; + this.barPadding=null; + this.barMargin=null; + this.barWidth=null; + this.highlightColors=null; + }; + + var PieSeriesProperties = function() { + this.seriesColors=null; + this.padding=null; + this.sliceMargin=null; + this.fill=null; + this.shadow=null; + this.startAngle=null; + this.lineWidth=null; + this.highlightColors=null; + }; + + var DonutSeriesProperties = function() { + this.seriesColors=null; + this.padding=null; + this.sliceMargin=null; + this.fill=null; + this.shadow=null; + this.startAngle=null; + this.lineWidth=null; + this.innerDiameter=null; + this.thickness=null; + this.ringMargin=null; + this.highlightColors=null; + }; + + var FunnelSeriesProperties = function() { + this.color=null; + this.lineWidth=null; + this.shadow=null; + this.padding=null; + this.sectionMargin=null; + this.seriesColors=null; + this.highlightColors=null; + }; + + var MeterSeriesProperties = function() { + this.padding=null; + this.backgroundColor=null; + this.ringColor=null; + this.tickColor=null; + this.ringWidth=null; + this.intervalColors=null; + this.intervalInnerRadius=null; + this.intervalOuterRadius=null; + this.hubRadius=null; + this.needleThickness=null; + this.needlePad=null; + }; + + + + + $.fn.jqplotChildText = function() { + return $(this).contents().filter(function() { + return this.nodeType == 3; // Node.TEXT_NODE not defined in I7 + }).text(); + }; + + // Returns font style as abbreviation for "font" property. + $.fn.jqplotGetComputedFontStyle = function() { + var css = window.getComputedStyle ? window.getComputedStyle(this[0], "") : this[0].currentStyle; + var attrs = css['font-style'] ? ['font-style', 'font-weight', 'font-size', 'font-family'] : ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily']; + var style = []; + + for (var i=0 ; i < attrs.length; ++i) { + var attr = String(css[attrs[i]]); + + if (attr && attr != 'normal') { + style.push(attr); + } + } + return style.join(' '); + }; + + /** + * Namespace: $.fn + * jQuery namespace to attach functions to jQuery elements. + * + */ + + $.fn.jqplotToImageCanvas = function(options) { + + options = options || {}; + var x_offset = (options.x_offset == null) ? 0 : options.x_offset; + var y_offset = (options.y_offset == null) ? 0 : options.y_offset; + var backgroundColor = (options.backgroundColor == null) ? 'rgb(255,255,255)' : options.backgroundColor; + + if ($(this).width() == 0 || $(this).height() == 0) { + return null; + } + + // excanvas and hence IE < 9 do not support toDataURL and cannot export images. + if ($.jqplot.use_excanvas) { + return null; + } + + var newCanvas = document.createElement("canvas"); + var h = $(this).outerHeight(true); + var w = $(this).outerWidth(true); + var offs = $(this).offset(); + var plotleft = offs.left; + var plottop = offs.top; + var transx = 0, transy = 0; + + // have to check if any elements are hanging outside of plot area before rendering, + // since changing width of canvas will erase canvas. + + var clses = ['jqplot-table-legend', 'jqplot-xaxis-tick', 'jqplot-x2axis-tick', 'jqplot-yaxis-tick', 'jqplot-y2axis-tick', 'jqplot-y3axis-tick', + 'jqplot-y4axis-tick', 'jqplot-y5axis-tick', 'jqplot-y6axis-tick', 'jqplot-y7axis-tick', 'jqplot-y8axis-tick', 'jqplot-y9axis-tick', + 'jqplot-xaxis-label', 'jqplot-x2axis-label', 'jqplot-yaxis-label', 'jqplot-y2axis-label', 'jqplot-y3axis-label', 'jqplot-y4axis-label', + 'jqplot-y5axis-label', 'jqplot-y6axis-label', 'jqplot-y7axis-label', 'jqplot-y8axis-label', 'jqplot-y9axis-label' ]; + + var temptop, templeft, tempbottom, tempright; + + for (var i = 0; i < clses.length; i++) { + $(this).find('.'+clses[i]).each(function() { + temptop = $(this).offset().top - plottop; + templeft = $(this).offset().left - plotleft; + tempright = templeft + $(this).outerWidth(true) + transx; + tempbottom = temptop + $(this).outerHeight(true) + transy; + if (templeft < -transx) { + w = w - transx - templeft; + transx = -templeft; + } + if (temptop < -transy) { + h = h - transy - temptop; + transy = - temptop; + } + if (tempright > w) { + w = tempright; + } + if (tempbottom > h) { + h = tempbottom; + } + }); + } + + newCanvas.width = w + Number(x_offset); + newCanvas.height = h + Number(y_offset); + + var newContext = newCanvas.getContext("2d"); + + newContext.save(); + newContext.fillStyle = backgroundColor; + newContext.fillRect(0,0, newCanvas.width, newCanvas.height); + newContext.restore(); + + newContext.translate(transx, transy); + newContext.textAlign = 'left'; + newContext.textBaseline = 'top'; + + function getLineheight(el) { + var lineheight = parseInt($(el).css('line-height'), 10); + + if (isNaN(lineheight)) { + lineheight = parseInt($(el).css('font-size'), 10) * 1.2; + } + return lineheight; + } + + function writeWrappedText (el, context, text, left, top, canvasWidth) { + var lineheight = getLineheight(el); + var tagwidth = $(el).innerWidth(); + var tagheight = $(el).innerHeight(); + var words = text.split(/\s+/); + var wl = words.length; + var w = ''; + var breaks = []; + var temptop = top; + var templeft = left; + + for (var i=0; i<wl; i++) { + w += words[i]; + if (context.measureText(w).width > tagwidth) { + breaks.push(i); + w = ''; + i--; + } + } + if (breaks.length === 0) { + // center text if necessary + if ($(el).css('textAlign') === 'center') { + templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; + } + context.fillText(text, templeft, top); + } + else { + w = words.slice(0, breaks[0]).join(' '); + // center text if necessary + if ($(el).css('textAlign') === 'center') { + templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; + } + context.fillText(w, templeft, temptop); + temptop += lineheight; + for (var i=1, l=breaks.length; i<l; i++) { + w = words.slice(breaks[i-1], breaks[i]).join(' '); + // center text if necessary + if ($(el).css('textAlign') === 'center') { + templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; + } + context.fillText(w, templeft, temptop); + temptop += lineheight; + } + w = words.slice(breaks[i-1], words.length).join(' '); + // center text if necessary + if ($(el).css('textAlign') === 'center') { + templeft = left + (canvasWidth - context.measureText(w).width)/2 - transx; + } + context.fillText(w, templeft, temptop); + } + + } + + function _jqpToImage(el, x_offset, y_offset) { + var tagname = el.tagName.toLowerCase(); + var p = $(el).position(); + var css = window.getComputedStyle ? window.getComputedStyle(el, "") : el.currentStyle; // for IE < 9 + var left = x_offset + p.left + parseInt(css.marginLeft, 10) + parseInt(css.borderLeftWidth, 10) + parseInt(css.paddingLeft, 10); + var top = y_offset + p.top + parseInt(css.marginTop, 10) + parseInt(css.borderTopWidth, 10)+ parseInt(css.paddingTop, 10); + var w = newCanvas.width; + // var left = x_offset + p.left + $(el).css('marginLeft') + $(el).css('borderLeftWidth') + + // somehow in here, for divs within divs, the width of the inner div should be used instead of the canvas. + + if ((tagname == 'div' || tagname == 'span') && !$(el).hasClass('jqplot-highlighter-tooltip')) { + $(el).children().each(function() { + _jqpToImage(this, left, top); + }); + var text = $(el).jqplotChildText(); + + if (text) { + newContext.font = $(el).jqplotGetComputedFontStyle(); + newContext.fillStyle = $(el).css('color'); + + writeWrappedText(el, newContext, text, left, top, w); + } + } + + // handle the standard table legend + + else if (tagname === 'table' && $(el).hasClass('jqplot-table-legend')) { + newContext.strokeStyle = $(el).css('border-top-color'); + newContext.fillStyle = $(el).css('background-color'); + newContext.fillRect(left, top, $(el).innerWidth(), $(el).innerHeight()); + if (parseInt($(el).css('border-top-width'), 10) > 0) { + newContext.strokeRect(left, top, $(el).innerWidth(), $(el).innerHeight()); + } + + // find all the swatches + $(el).find('div.jqplot-table-legend-swatch-outline').each(function() { + // get the first div and stroke it + var elem = $(this); + newContext.strokeStyle = elem.css('border-top-color'); + var l = left + elem.position().left; + var t = top + elem.position().top; + newContext.strokeRect(l, t, elem.innerWidth(), elem.innerHeight()); + + // now fill the swatch + + l += parseInt(elem.css('padding-left'), 10); + t += parseInt(elem.css('padding-top'), 10); + var h = elem.innerHeight() - 2 * parseInt(elem.css('padding-top'), 10); + var w = elem.innerWidth() - 2 * parseInt(elem.css('padding-left'), 10); + + var swatch = elem.children('div.jqplot-table-legend-swatch'); + newContext.fillStyle = swatch.css('background-color'); + newContext.fillRect(l, t, w, h); + }); + + // now add text + + $(el).find('td.jqplot-table-legend-label').each(function(){ + var elem = $(this); + var l = left + elem.position().left; + var t = top + elem.position().top + parseInt(elem.css('padding-top'), 10); + newContext.font = elem.jqplotGetComputedFontStyle(); + newContext.fillStyle = elem.css('color'); + writeWrappedText(elem, newContext, elem.text(), l, t, w); + }); + + var elem = null; + } + + else if (tagname == 'canvas') { + newContext.drawImage(el, left, top); + } + } + $(this).children().each(function() { + _jqpToImage(this, x_offset, y_offset); + }); + return newCanvas; + }; + + // return the raw image data string. + // Should work on canvas supporting browsers. + $.fn.jqplotToImageStr = function(options) { + var imgCanvas = $(this).jqplotToImageCanvas(options); + if (imgCanvas) { + return imgCanvas.toDataURL("image/png"); + } + else { + return null; + } + }; + + // return a DOM <img> element and return it. + // Should work on canvas supporting browsers. + $.fn.jqplotToImageElem = function(options) { + var elem = document.createElement("img"); + var str = $(this).jqplotToImageStr(options); + elem.src = str; + return elem; + }; + + // return a string for an <img> element and return it. + // Should work on canvas supporting browsers. + $.fn.jqplotToImageElemStr = function(options) { + var str = '<img src='+$(this).jqplotToImageStr(options)+' />'; + return str; + }; + + // Not guaranteed to work, even on canvas supporting browsers due to + // limitations with location.href and browser support. + $.fn.jqplotSaveImage = function() { + var imgData = $(this).jqplotToImageStr({}); + if (imgData) { + window.location.href = imgData.replace("image/png", "image/octet-stream"); + } + + }; + + // Not guaranteed to work, even on canvas supporting browsers due to + // limitations with window.open and arbitrary data. + $.fn.jqplotViewImage = function() { + var imgStr = $(this).jqplotToImageElemStr({}); + var imgData = $(this).jqplotToImageStr({}); + if (imgStr) { + var w = window.open(''); + w.document.open("image/png"); + w.document.write(imgStr); + w.document.close(); + w = null; + } + }; + + + + + /** + * @description + * <p>Object with extended date parsing and formatting capabilities. + * This library borrows many concepts and ideas from the Date Instance + * Methods by Ken Snyder along with some parts of Ken's actual code.</p> + * + * <p>jsDate takes a different approach by not extending the built-in + * Date Object, improving date parsing, allowing for multiple formatting + * syntaxes and multiple and more easily expandable localization.</p> + * + * @author Chris Leonello + * @date #date# + * @version #VERSION# + * @copyright (c) 2010-2013 Chris Leonello + * jsDate is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * <p>Ken's original Date Instance Methods and copyright notice:</p> + * <pre> + * Ken Snyder (ken d snyder at gmail dot com) + * 2008-09-10 + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) + * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) + * </pre> + * + * @class + * @name jsDate + * @param {String | Number | Array | Date Object | Options Object} arguments Optional arguments, either a parsable date/time string, + * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], + * a Date object, or an options object of form {syntax: "perl", date:some Date} where all options are optional. + */ + + var jsDate = function () { + + this.syntax = jsDate.config.syntax; + this._type = "jsDate"; + this.proxy = new Date(); + this.options = {}; + this.locale = jsDate.regional.getLocale(); + this.formatString = ''; + this.defaultCentury = jsDate.config.defaultCentury; + + switch ( arguments.length ) { + case 0: + break; + case 1: + // other objects either won't have a _type property or, + // if they do, it shouldn't be set to "jsDate", so + // assume it is an options argument. + if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { + var opts = this.options = arguments[0]; + this.syntax = opts.syntax || this.syntax; + this.defaultCentury = opts.defaultCentury || this.defaultCentury; + this.proxy = jsDate.createDate(opts.date); + } + else { + this.proxy = jsDate.createDate(arguments[0]); + } + break; + default: + var a = []; + for ( var i=0; i<arguments.length; i++ ) { + a.push(arguments[i]); + } + // this should be the current date/time? + this.proxy = new Date(); + this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); + if ( a.slice(3).length ) { + this.proxy.setHours.apply( this.proxy, a.slice(3) ); + } + break; + } + }; + + /** + * @namespace Configuration options that will be used as defaults for all instances on the page. + * @property {String} defaultLocale The default locale to use [en]. + * @property {String} syntax The default syntax to use [perl]. + * @property {Number} defaultCentury The default centry for 2 digit dates. + */ + jsDate.config = { + defaultLocale: 'en', + syntax: 'perl', + defaultCentury: 1900 + }; + + /** + * Add an arbitrary amount to the currently stored date + * + * @param {Number} number + * @param {String} unit + * @returns {jsDate} + */ + + jsDate.prototype.add = function(number, unit) { + var factor = multipliers[unit] || multipliers.day; + if (typeof factor == 'number') { + this.proxy.setTime(this.proxy.getTime() + (factor * number)); + } else { + factor.add(this, number); + } + return this; + }; + + /** + * Create a new jqplot.date object with the same date + * + * @returns {jsDate} + */ + + jsDate.prototype.clone = function() { + return new jsDate(this.proxy.getTime()); + }; + + /** + * Get the UTC TimeZone Offset of this date in milliseconds. + * + * @returns {Number} + */ + + jsDate.prototype.getUtcOffset = function() { + return this.proxy.getTimezoneOffset() * 60000; + }; + + /** + * Find the difference between this jsDate and another date. + * + * @param {String| Number| Array| jsDate Object| Date Object} dateObj + * @param {String} unit + * @param {Boolean} allowDecimal + * @returns {Number} Number of units difference between dates. + */ + + jsDate.prototype.diff = function(dateObj, unit, allowDecimal) { + // ensure we have a Date object + dateObj = new jsDate(dateObj); + if (dateObj === null) { + return null; + } + // get the multiplying factor integer or factor function + var factor = multipliers[unit] || multipliers.day; + if (typeof factor == 'number') { + // multiply + var unitDiff = (this.proxy.getTime() - dateObj.proxy.getTime()) / factor; + } else { + // run function + var unitDiff = factor.diff(this.proxy, dateObj.proxy); + } + // if decimals are not allowed, round toward zero + return (allowDecimal ? unitDiff : Math[unitDiff > 0 ? 'floor' : 'ceil'](unitDiff)); + }; + + /** + * Get the abbreviated name of the current week day + * + * @returns {String} + */ + + jsDate.prototype.getAbbrDayName = function() { + return jsDate.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]; + }; + + /** + * Get the abbreviated name of the current month + * + * @returns {String} + */ + + jsDate.prototype.getAbbrMonthName = function() { + return jsDate.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]; + }; + + /** + * Get UPPER CASE AM or PM for the current time + * + * @returns {String} + */ + + jsDate.prototype.getAMPM = function() { + return this.proxy.getHours() >= 12 ? 'PM' : 'AM'; + }; + + /** + * Get lower case am or pm for the current time + * + * @returns {String} + */ + + jsDate.prototype.getAmPm = function() { + return this.proxy.getHours() >= 12 ? 'pm' : 'am'; + }; + + /** + * Get the century (19 for 20th Century) + * + * @returns {Integer} Century (19 for 20th century). + */ + jsDate.prototype.getCentury = function() { + return parseInt(this.proxy.getFullYear()/100, 10); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getDate = function() { + return this.proxy.getDate(); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getDay = function() { + return this.proxy.getDay(); + }; + + /** + * Get the Day of week 1 (Monday) thru 7 (Sunday) + * + * @returns {Integer} Day of week 1 (Monday) thru 7 (Sunday) + */ + jsDate.prototype.getDayOfWeek = function() { + var dow = this.proxy.getDay(); + return dow===0?7:dow; + }; + + /** + * Get the day of the year + * + * @returns {Integer} 1 - 366, day of the year + */ + jsDate.prototype.getDayOfYear = function() { + var d = this.proxy; + var ms = d - new Date('' + d.getFullYear() + '/1/1 GMT'); + ms += d.getTimezoneOffset()*60000; + d = null; + return parseInt(ms/60000/60/24, 10)+1; + }; + + /** + * Get the name of the current week day + * + * @returns {String} + */ + + jsDate.prototype.getDayName = function() { + return jsDate.regional[this.locale]["dayNames"][this.proxy.getDay()]; + }; + + /** + * Get the week number of the given year, starting with the first Sunday as the first week + * @returns {Integer} Week number (13 for the 13th full week of the year). + */ + jsDate.prototype.getFullWeekOfYear = function() { + var d = this.proxy; + var doy = this.getDayOfYear(); + var rdow = 6-d.getDay(); + var woy = parseInt((doy+rdow)/7, 10); + return woy; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getFullYear = function() { + return this.proxy.getFullYear(); + }; + + /** + * Get the GMT offset in hours and minutes (e.g. +06:30) + * + * @returns {String} + */ + + jsDate.prototype.getGmtOffset = function() { + // divide the minutes offset by 60 + var hours = this.proxy.getTimezoneOffset() / 60; + // decide if we are ahead of or behind GMT + var prefix = hours < 0 ? '+' : '-'; + // remove the negative sign if any + hours = Math.abs(hours); + // add the +/- to the padded number of hours to : to the padded minutes + return prefix + addZeros(Math.floor(hours), 2) + ':' + addZeros((hours % 1) * 60, 2); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getHours = function() { + return this.proxy.getHours(); + }; + + /** + * Get the current hour on a 12-hour scheme + * + * @returns {Integer} + */ + + jsDate.prototype.getHours12 = function() { + var hours = this.proxy.getHours(); + return hours > 12 ? hours - 12 : (hours == 0 ? 12 : hours); + }; + + + jsDate.prototype.getIsoWeek = function() { + var d = this.proxy; + var woy = this.getWeekOfYear(); + var dow1_1 = (new Date('' + d.getFullYear() + '/1/1')).getDay(); + // First week is 01 and not 00 as in the case of %U and %W, + // so we add 1 to the final result except if day 1 of the year + // is a Monday (then %W returns 01). + // We also need to subtract 1 if the day 1 of the year is + // Friday-Sunday, so the resulting equation becomes: + var idow = woy + (dow1_1 > 4 || dow1_1 <= 1 ? 0 : 1); + if(idow == 53 && (new Date('' + d.getFullYear() + '/12/31')).getDay() < 4) + { + idow = 1; + } + else if(idow === 0) + { + d = new jsDate(new Date('' + (d.getFullYear()-1) + '/12/31')); + idow = d.getIsoWeek(); + } + d = null; + return idow; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getMilliseconds = function() { + return this.proxy.getMilliseconds(); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getMinutes = function() { + return this.proxy.getMinutes(); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getMonth = function() { + return this.proxy.getMonth(); + }; + + /** + * Get the name of the current month + * + * @returns {String} + */ + + jsDate.prototype.getMonthName = function() { + return jsDate.regional[this.locale]["monthNames"][this.proxy.getMonth()]; + }; + + /** + * Get the number of the current month, 1-12 + * + * @returns {Integer} + */ + + jsDate.prototype.getMonthNumber = function() { + return this.proxy.getMonth() + 1; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getSeconds = function() { + return this.proxy.getSeconds(); + }; + + /** + * Return a proper two-digit year integer + * + * @returns {Integer} + */ + + jsDate.prototype.getShortYear = function() { + return this.proxy.getYear() % 100; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getTime = function() { + return this.proxy.getTime(); + }; + + /** + * Get the timezone abbreviation + * + * @returns {String} Abbreviation for the timezone + */ + jsDate.prototype.getTimezoneAbbr = function() { + return this.proxy.toString().replace(/^.*\(([^)]+)\)$/, '$1'); + }; + + /** + * Get the browser-reported name for the current timezone (e.g. MDT, Mountain Daylight Time) + * + * @returns {String} + */ + jsDate.prototype.getTimezoneName = function() { + var match = /(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString()); + return match[1] || match[2] || 'GMT' + this.getGmtOffset(); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getTimezoneOffset = function() { + return this.proxy.getTimezoneOffset(); + }; + + + /** + * Get the week number of the given year, starting with the first Monday as the first week + * @returns {Integer} Week number (13 for the 13th week of the year). + */ + jsDate.prototype.getWeekOfYear = function() { + var doy = this.getDayOfYear(); + var rdow = 7 - this.getDayOfWeek(); + var woy = parseInt((doy+rdow)/7, 10); + return woy; + }; + + /** + * Get the current date as a Unix timestamp + * + * @returns {Integer} + */ + + jsDate.prototype.getUnix = function() { + return Math.round(this.proxy.getTime() / 1000, 0); + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.getYear = function() { + return this.proxy.getYear(); + }; + + /** + * Return a date one day ahead (or any other unit) + * + * @param {String} unit Optional, year | month | day | week | hour | minute | second | millisecond + * @returns {jsDate} + */ + + jsDate.prototype.next = function(unit) { + unit = unit || 'day'; + return this.clone().add(1, unit); + }; + + /** + * Set the jsDate instance to a new date. + * + * @param {String | Number | Array | Date Object | jsDate Object | Options Object} arguments Optional arguments, + * either a parsable date/time string, + * a JavaScript timestamp, an array of numbers of form [year, month, day, hours, minutes, seconds, milliseconds], + * a Date object, jsDate Object or an options object of form {syntax: "perl", date:some Date} where all options are optional. + */ + jsDate.prototype.set = function() { + switch ( arguments.length ) { + case 0: + this.proxy = new Date(); + break; + case 1: + // other objects either won't have a _type property or, + // if they do, it shouldn't be set to "jsDate", so + // assume it is an options argument. + if (get_type(arguments[0]) == "[object Object]" && arguments[0]._type != "jsDate") { + var opts = this.options = arguments[0]; + this.syntax = opts.syntax || this.syntax; + this.defaultCentury = opts.defaultCentury || this.defaultCentury; + this.proxy = jsDate.createDate(opts.date); + } + else { + this.proxy = jsDate.createDate(arguments[0]); + } + break; + default: + var a = []; + for ( var i=0; i<arguments.length; i++ ) { + a.push(arguments[i]); + } + // this should be the current date/time + this.proxy = new Date(); + this.proxy.setFullYear.apply( this.proxy, a.slice(0,3) ); + if ( a.slice(3).length ) { + this.proxy.setHours.apply( this.proxy, a.slice(3) ); + } + break; + } + return this; + }; + + /** + * Sets the day of the month for a specified date according to local time. + * @param {Integer} dayValue An integer from 1 to 31, representing the day of the month. + */ + jsDate.prototype.setDate = function(n) { + this.proxy.setDate(n); + return this; + }; + + /** + * Sets the full year for a specified date according to local time. + * @param {Integer} yearValue The numeric value of the year, for example, 1995. + * @param {Integer} monthValue Optional, between 0 and 11 representing the months January through December. + * @param {Integer} dayValue Optional, between 1 and 31 representing the day of the month. If you specify the dayValue parameter, you must also specify the monthValue. + */ + jsDate.prototype.setFullYear = function() { + this.proxy.setFullYear.apply(this.proxy, arguments); + return this; + }; + + /** + * Sets the hours for a specified date according to local time. + * + * @param {Integer} hoursValue An integer between 0 and 23, representing the hour. + * @param {Integer} minutesValue Optional, An integer between 0 and 59, representing the minutes. + * @param {Integer} secondsValue Optional, An integer between 0 and 59, representing the seconds. + * If you specify the secondsValue parameter, you must also specify the minutesValue. + * @param {Integer} msValue Optional, A number between 0 and 999, representing the milliseconds. + * If you specify the msValue parameter, you must also specify the minutesValue and secondsValue. + */ + jsDate.prototype.setHours = function() { + this.proxy.setHours.apply(this.proxy, arguments); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setMilliseconds = function(n) { + this.proxy.setMilliseconds(n); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setMinutes = function() { + this.proxy.setMinutes.apply(this.proxy, arguments); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setMonth = function() { + this.proxy.setMonth.apply(this.proxy, arguments); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setSeconds = function() { + this.proxy.setSeconds.apply(this.proxy, arguments); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setTime = function(n) { + this.proxy.setTime(n); + return this; + }; + + /** + * Implements Date functionality + */ + jsDate.prototype.setYear = function() { + this.proxy.setYear.apply(this.proxy, arguments); + return this; + }; + + /** + * Provide a formatted string representation of this date. + * + * @param {String} formatString A format string. + * See: {@link jsDate.formats}. + * @returns {String} Date String. + */ + + jsDate.prototype.strftime = function(formatString) { + formatString = formatString || this.formatString || jsDate.regional[this.locale]['formatString']; + return jsDate.strftime(this, formatString, this.syntax); + }; + + /** + * Return a String representation of this jsDate object. + * @returns {String} Date string. + */ + + jsDate.prototype.toString = function() { + return this.proxy.toString(); + }; + + /** + * Convert the current date to an 8-digit integer (%Y%m%d) + * + * @returns {Integer} + */ + + jsDate.prototype.toYmdInt = function() { + return (this.proxy.getFullYear() * 10000) + (this.getMonthNumber() * 100) + this.proxy.getDate(); + }; + + /** + * @namespace Holds localizations for month/day names. + * <p>jsDate attempts to detect locale when loaded and defaults to 'en'. + * If a localization is detected which is not available, jsDate defaults to 'en'. + * Additional localizations can be added after jsDate loads. After adding a localization, + * call the jsDate.regional.getLocale() method. Currently, en, fr and de are defined.</p> + * + * <p>Localizations must be an object and have the following properties defined: monthNames, monthNamesShort, dayNames, dayNamesShort and Localizations are added like:</p> + * <pre class="code"> + * jsDate.regional['en'] = { + * monthNames : 'January February March April May June July August September October November December'.split(' '), + * monthNamesShort : 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' '), + * dayNames : 'Sunday Monday Tuesday Wednesday Thursday Friday Saturday'.split(' '), + * dayNamesShort : 'Sun Mon Tue Wed Thu Fri Sat'.split(' ') + * }; + * </pre> + * <p>After adding localizations, call <code>jsDate.regional.getLocale();</code> to update the locale setting with the + * new localizations.</p> + */ + + jsDate.regional = { + 'en': { + monthNames: ['January','February','March','April','May','June','July','August','September','October','November','December'], + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'fr': { + monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'], + monthNamesShort: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'], + dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'], + dayNamesShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'de': { + monthNames: ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'], + monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'], + dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'], + dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'es': { + monthNames: ['Enero','Febrero','Marzo','Abril','Mayo','Junio', 'Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'], + monthNamesShort: ['Ene','Feb','Mar','Abr','May','Jun', 'Jul','Ago','Sep','Oct','Nov','Dic'], + dayNames: ['Domingo','Lunes','Martes','Miércoles','Jueves','Viernes','Sábado'], + dayNamesShort: ['Dom','Lun','Mar','Mié','Juv','Vie','Sáb'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'ru': { + monthNames: ['Январь','Февраль','Март','Апрель','Май','Июнь','Июль','Август','Сентябрь','Октябрь','Ноябрь','Декабрь'], + monthNamesShort: ['Янв','Фев','Мар','Апр','Май','Июн','Июл','Авг','Сен','Окт','Ноя','Дек'], + dayNames: ['воскресенье','понедельник','вторник','среда','четверг','пятница','суббота'], + dayNamesShort: ['вск','пнд','втр','срд','чтв','птн','сбт'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'ar': { + monthNames: ['كانون الثاني', 'شباط', 'آذار', 'نيسان', 'آذار', 'حزيران','تموز', 'آب', 'أيلول', 'تشرين الأول', 'تشرين الثاني', 'كانون الأول'], + monthNamesShort: ['1','2','3','4','5','6','7','8','9','10','11','12'], + dayNames: ['السبت', 'الأحد', 'الاثنين', 'الثلاثاء', 'الأربعاء', 'الخميس', 'الجمعة'], + dayNamesShort: ['سبت', 'أحد', 'اثنين', 'ثلاثاء', 'أربعاء', 'خميس', 'جمعة'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'pt': { + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'pt-BR': { + monthNames: ['Janeiro','Fevereiro','Março','Abril','Maio','Junho', 'Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'], + monthNamesShort: ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'], + dayNames: ['Domingo','Segunda-feira','Terça-feira','Quarta-feira','Quinta-feira','Sexta-feira','Sábado'], + dayNamesShort: ['Dom','Seg','Ter','Qua','Qui','Sex','Sáb'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'pl': { + monthNames: ['Styczeń','Luty','Marzec','Kwiecień','Maj','Czerwiec','Lipiec','Sierpień','Wrzesień','Październik','Listopad','Grudzień'], + monthNamesShort: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze','Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'], + dayNames: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'], + dayNamesShort: ['Ni', 'Pn', 'Wt', 'Śr', 'Cz', 'Pt', 'Sb'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'nl': { + monthNames: ['Januari','Februari','Maart','April','Mei','Juni','July','Augustus','September','Oktober','November','December'], + monthNamesShort: ['Jan','Feb','Mar','Apr','Mei','Jun','Jul','Aug','Sep','Okt','Nov','Dec'], + dayNames:','['Zondag','Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'], + dayNamesShort: ['Zo','Ma','Di','Wo','Do','Vr','Za'], + formatString: '%Y-%m-%d %H:%M:%S' + }, + + 'sv': { + monthNames: ['januari','februari','mars','april','maj','juni','juli','augusti','september','oktober','november','december'], + monthNamesShort: ['jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'], + dayNames: ['söndag','måndag','tisdag','onsdag','torsdag','fredag','lördag'], + dayNamesShort: ['sön','mån','tis','ons','tor','fre','lör'], + formatString: '%Y-%m-%d %H:%M:%S' + } + + }; + + // Set english variants to 'en' + jsDate.regional['en-US'] = jsDate.regional['en-GB'] = jsDate.regional['en']; + + /** + * Try to determine the users locale based on the lang attribute of the html page. Defaults to 'en' + * if it cannot figure out a locale of if the locale does not have a localization defined. + * @returns {String} locale + */ + + jsDate.regional.getLocale = function () { + var l = jsDate.config.defaultLocale; + + if ( document && document.getElementsByTagName('html') && document.getElementsByTagName('html')[0].lang ) { + l = document.getElementsByTagName('html')[0].lang; + if (!jsDate.regional.hasOwnProperty(l)) { + l = jsDate.config.defaultLocale; + } + } + + return l; + }; + + // ms in day + var day = 24 * 60 * 60 * 1000; + + // padd a number with zeros + var addZeros = function(num, digits) { + num = String(num); + var i = digits - num.length; + var s = String(Math.pow(10, i)).slice(1); + return s.concat(num); + }; + + // representations used for calculating differences between dates. + // This borrows heavily from Ken Snyder's work. + var multipliers = { + millisecond: 1, + second: 1000, + minute: 60 * 1000, + hour: 60 * 60 * 1000, + day: day, + week: 7 * day, + month: { + // add a number of months + add: function(d, number) { + // add any years needed (increments of 12) + multipliers.year.add(d, Math[number > 0 ? 'floor' : 'ceil'](number / 12)); + // ensure that we properly wrap betwen December and January + // 11 % 12 = 11 + // 12 % 12 = 0 + var prevMonth = d.getMonth() + (number % 12); + if (prevMonth == 12) { + prevMonth = 0; + d.setYear(d.getFullYear() + 1); + } else if (prevMonth == -1) { + prevMonth = 11; + d.setYear(d.getFullYear() - 1); + } + d.setMonth(prevMonth); + }, + // get the number of months between two Date objects (decimal to the nearest day) + diff: function(d1, d2) { + // get the number of years + var diffYears = d1.getFullYear() - d2.getFullYear(); + // get the number of remaining months + var diffMonths = d1.getMonth() - d2.getMonth() + (diffYears * 12); + // get the number of remaining days + var diffDays = d1.getDate() - d2.getDate(); + // return the month difference with the days difference as a decimal + return diffMonths + (diffDays / 30); + } + }, + year: { + // add a number of years + add: function(d, number) { + d.setYear(d.getFullYear() + Math[number > 0 ? 'floor' : 'ceil'](number)); + }, + // get the number of years between two Date objects (decimal to the nearest day) + diff: function(d1, d2) { + return multipliers.month.diff(d1, d2) / 12; + } + } + }; + // + // Alias each multiplier with an 's' to allow 'year' and 'years' for example. + // This comes from Ken Snyders work. + // + for (var unit in multipliers) { + if (unit.substring(unit.length - 1) != 's') { // IE will iterate newly added properties :| + multipliers[unit + 's'] = multipliers[unit]; + } + } + + // + // take a jsDate instance and a format code and return the formatted value. + // This is a somewhat modified version of Ken Snyder's method. + // + var format = function(d, code, syntax) { + // if shorcut codes are used, recursively expand those. + if (jsDate.formats[syntax]["shortcuts"][code]) { + return jsDate.strftime(d, jsDate.formats[syntax]["shortcuts"][code], syntax); + } else { + // get the format code function and addZeros() argument + var getter = (jsDate.formats[syntax]["codes"][code] || '').split('.'); + var nbr = d['get' + getter[0]] ? d['get' + getter[0]]() : ''; + if (getter[1]) { + nbr = addZeros(nbr, getter[1]); + } + return nbr; + } + }; + + /** + * @static + * Static function for convert a date to a string according to a given format. Also acts as namespace for strftime format codes. + * <p>strftime formatting can be accomplished without creating a jsDate object by calling jsDate.strftime():</p> + * <pre class="code"> + * var formattedDate = jsDate.strftime('Feb 8, 2006 8:48:32', '%Y-%m-%d %H:%M:%S'); + * </pre> + * @param {String | Number | Array | jsDate Object | Date Object} date A parsable date string, JavaScript time stamp, Array of form [year, month, day, hours, minutes, seconds, milliseconds], jsDate Object or Date object. + * @param {String} formatString String with embedded date formatting codes. + * See: {@link jsDate.formats}. + * @param {String} syntax Optional syntax to use [default perl]. + * @param {String} locale Optional locale to use. + * @returns {String} Formatted representation of the date. + */ + // + // Logic as implemented here is very similar to Ken Snyder's Date Instance Methods. + // + jsDate.strftime = function(d, formatString, syntax, locale) { + var syn = 'perl'; + var loc = jsDate.regional.getLocale(); + + // check if syntax and locale are available or reversed + if (syntax && jsDate.formats.hasOwnProperty(syntax)) { + syn = syntax; + } + else if (syntax && jsDate.regional.hasOwnProperty(syntax)) { + loc = syntax; + } + + if (locale && jsDate.formats.hasOwnProperty(locale)) { + syn = locale; + } + else if (locale && jsDate.regional.hasOwnProperty(locale)) { + loc = locale; + } + + if (get_type(d) != "[object Object]" || d._type != "jsDate") { + d = new jsDate(d); + d.locale = loc; + } + if (!formatString) { + formatString = d.formatString || jsDate.regional[loc]['formatString']; + } + // default the format string to year-month-day + var source = formatString || '%Y-%m-%d', + result = '', + match; + // replace each format code + while (source.length > 0) { + if (match = source.match(jsDate.formats[syn].codes.matcher)) { + result += source.slice(0, match.index); + result += (match[1] || '') + format(d, match[2], syn); + source = source.slice(match.index + match[0].length); + } else { + result += source; + source = ''; + } + } + return result; + }; + + /** + * @namespace + * Namespace to hold format codes and format shortcuts. "perl" and "php" format codes + * and shortcuts are defined by default. Additional codes and shortcuts can be + * added like: + * + * <pre class="code"> + * jsDate.formats["perl"] = { + * "codes": { + * matcher: /someregex/, + * Y: "fullYear", // name of "get" method without the "get", + * ..., // more codes + * }, + * "shortcuts": { + * F: '%Y-%m-%d', + * ..., // more shortcuts + * } + * }; + * </pre> + * + * <p>Additionally, ISO and SQL shortcuts are defined and can be accesses via: + * <code>jsDate.formats.ISO</code> and <code>jsDate.formats.SQL</code> + */ + + jsDate.formats = { + ISO:'%Y-%m-%dT%H:%M:%S.%N%G', + SQL:'%Y-%m-%d %H:%M:%S' + }; + + /** + * Perl format codes and shortcuts for strftime. + * + * A hash (object) of codes where each code must be an array where the first member is + * the name of a Date.prototype or jsDate.prototype function to call + * and optionally a second member indicating the number to pass to addZeros() + * + * <p>The following format codes are defined:</p> + * + * <pre class="code"> + * Code Result Description + * == Years == + * %Y 2008 Four-digit year + * %y 08 Two-digit year + * + * == Months == + * %m 09 Two-digit month + * %#m 9 One or two-digit month + * %B September Full month name + * %b Sep Abbreviated month name + * + * == Days == + * %d 05 Two-digit day of month + * %#d 5 One or two-digit day of month + * %e 5 One or two-digit day of month + * %A Sunday Full name of the day of the week + * %a Sun Abbreviated name of the day of the week + * %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) + * + * == Hours == + * %H 23 Hours in 24-hour format (two digits) + * %#H 3 Hours in 24-hour integer format (one or two digits) + * %I 11 Hours in 12-hour format (two digits) + * %#I 3 Hours in 12-hour integer format (one or two digits) + * %p PM AM or PM + * + * == Minutes == + * %M 09 Minutes (two digits) + * %#M 9 Minutes (one or two digits) + * + * == Seconds == + * %S 02 Seconds (two digits) + * %#S 2 Seconds (one or two digits) + * %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) + * + * == Milliseconds == + * %N 008 Milliseconds (three digits) + * %#N 8 Milliseconds (one to three digits) + * + * == Timezone == + * %O 360 difference in minutes between local time and GMT + * %Z Mountain Standard Time Name of timezone as reported by browser + * %G 06:00 Hours and minutes between GMT + * + * == Shortcuts == + * %F 2008-03-26 %Y-%m-%d + * %T 05:06:30 %H:%M:%S + * %X 05:06:30 %H:%M:%S + * %x 03/26/08 %m/%d/%y + * %D 03/26/08 %m/%d/%y + * %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y + * %v 3-Sep-2008 %e-%b-%Y + * %R 15:31 %H:%M + * %r 03:31:00 PM %I:%M:%S %p + * + * == Characters == + * %n \n Newline + * %t \t Tab + * %% % Percent Symbol + * </pre> + * + * <p>Formatting shortcuts that will be translated into their longer version. + * Be sure that format shortcuts do not refer to themselves: this will cause an infinite loop.</p> + * + * <p>Format codes and format shortcuts can be redefined after the jsDate + * module is imported.</p> + * + * <p>Note that if you redefine the whole hash (object), you must supply a "matcher" + * regex for the parser. The default matcher is:</p> + * + * <code>/()%(#?(%|[a-z]))/i</code> + * + * <p>which corresponds to the Perl syntax used by default.</p> + * + * <p>By customizing the matcher and format codes, nearly any strftime functionality is possible.</p> + */ + + jsDate.formats.perl = { + codes: { + // + // 2-part regex matcher for format codes + // + // first match must be the character before the code (to account for escaping) + // second match must be the format code character(s) + // + matcher: /()%(#?(%|[a-z]))/i, + // year + Y: 'FullYear', + y: 'ShortYear.2', + // month + m: 'MonthNumber.2', + '#m': 'MonthNumber', + B: 'MonthName', + b: 'AbbrMonthName', + // day + d: 'Date.2', + '#d': 'Date', + e: 'Date', + A: 'DayName', + a: 'AbbrDayName', + w: 'Day', + // hours + H: 'Hours.2', + '#H': 'Hours', + I: 'Hours12.2', + '#I': 'Hours12', + p: 'AMPM', + // minutes + M: 'Minutes.2', + '#M': 'Minutes', + // seconds + S: 'Seconds.2', + '#S': 'Seconds', + s: 'Unix', + // milliseconds + N: 'Milliseconds.3', + '#N': 'Milliseconds', + // timezone + O: 'TimezoneOffset', + Z: 'TimezoneName', + G: 'GmtOffset' + }, + + shortcuts: { + // date + F: '%Y-%m-%d', + // time + T: '%H:%M:%S', + X: '%H:%M:%S', + // local format date + x: '%m/%d/%y', + D: '%m/%d/%y', + // local format extended + '#c': '%a %b %e %H:%M:%S %Y', + // local format short + v: '%e-%b-%Y', + R: '%H:%M', + r: '%I:%M:%S %p', + // tab and newline + t: '\t', + n: '\n', + '%': '%' + } + }; + + /** + * PHP format codes and shortcuts for strftime. + * + * A hash (object) of codes where each code must be an array where the first member is + * the name of a Date.prototype or jsDate.prototype function to call + * and optionally a second member indicating the number to pass to addZeros() + * + * <p>The following format codes are defined:</p> + * + * <pre class="code"> + * Code Result Description + * === Days === + * %a Sun through Sat An abbreviated textual representation of the day + * %A Sunday - Saturday A full textual representation of the day + * %d 01 to 31 Two-digit day of the month (with leading zeros) + * %e 1 to 31 Day of the month, with a space preceding single digits. + * %j 001 to 366 Day of the year, 3 digits with leading zeros + * %u 1 - 7 (Mon - Sun) ISO-8601 numeric representation of the day of the week + * %w 0 - 6 (Sun - Sat) Numeric representation of the day of the week + * + * === Week === + * %U 13 Full Week number, starting with the first Sunday as the first week + * %V 01 through 53 ISO-8601:1988 week number, starting with the first week of the year + * with at least 4 weekdays, with Monday being the start of the week + * %W 46 A numeric representation of the week of the year, + * starting with the first Monday as the first week + * === Month === + * %b Jan through Dec Abbreviated month name, based on the locale + * %B January - December Full month name, based on the locale + * %h Jan through Dec Abbreviated month name, based on the locale (an alias of %b) + * %m 01 - 12 (Jan - Dec) Two digit representation of the month + * + * === Year === + * %C 19 Two digit century (year/100, truncated to an integer) + * %y 09 for 2009 Two digit year + * %Y 2038 Four digit year + * + * === Time === + * %H 00 through 23 Two digit representation of the hour in 24-hour format + * %I 01 through 12 Two digit representation of the hour in 12-hour format + * %l 1 through 12 Hour in 12-hour format, with a space preceeding single digits + * %M 00 through 59 Two digit representation of the minute + * %p AM/PM UPPER-CASE 'AM' or 'PM' based on the given time + * %P am/pm lower-case 'am' or 'pm' based on the given time + * %r 09:34:17 PM Same as %I:%M:%S %p + * %R 00:35 Same as %H:%M + * %S 00 through 59 Two digit representation of the second + * %T 21:34:17 Same as %H:%M:%S + * %X 03:59:16 Preferred time representation based on locale, without the date + * %z -0500 or EST Either the time zone offset from UTC or the abbreviation + * %Z -0500 or EST The time zone offset/abbreviation option NOT given by %z + * + * === Time and Date === + * %D 02/05/09 Same as %m/%d/%y + * %F 2009-02-05 Same as %Y-%m-%d (commonly used in database datestamps) + * %s 305815200 Unix Epoch Time timestamp (same as the time() function) + * %x 02/05/09 Preferred date representation, without the time + * + * === Miscellaneous === + * %n --- A newline character (\n) + * %t --- A Tab character (\t) + * %% --- A literal percentage character (%) + * </pre> + */ + + jsDate.formats.php = { + codes: { + // + // 2-part regex matcher for format codes + // + // first match must be the character before the code (to account for escaping) + // second match must be the format code character(s) + // + matcher: /()%((%|[a-z]))/i, + // day + a: 'AbbrDayName', + A: 'DayName', + d: 'Date.2', + e: 'Date', + j: 'DayOfYear.3', + u: 'DayOfWeek', + w: 'Day', + // week + U: 'FullWeekOfYear.2', + V: 'IsoWeek.2', + W: 'WeekOfYear.2', + // month + b: 'AbbrMonthName', + B: 'MonthName', + m: 'MonthNumber.2', + h: 'AbbrMonthName', + // year + C: 'Century.2', + y: 'ShortYear.2', + Y: 'FullYear', + // time + H: 'Hours.2', + I: 'Hours12.2', + l: 'Hours12', + p: 'AMPM', + P: 'AmPm', + M: 'Minutes.2', + S: 'Seconds.2', + s: 'Unix', + O: 'TimezoneOffset', + z: 'GmtOffset', + Z: 'TimezoneAbbr' + }, + + shortcuts: { + D: '%m/%d/%y', + F: '%Y-%m-%d', + T: '%H:%M:%S', + X: '%H:%M:%S', + x: '%m/%d/%y', + R: '%H:%M', + r: '%I:%M:%S %p', + t: '\t', + n: '\n', + '%': '%' + } + }; + // + // Conceptually, the logic implemented here is similar to Ken Snyder's Date Instance Methods. + // I use his idea of a set of parsers which can be regular expressions or functions, + // iterating through those, and then seeing if Date.parse() will create a date. + // The parser expressions and functions are a little different and some bugs have been + // worked out. Also, a lot of "pre-parsing" is done to fix implementation + // variations of Date.parse() between browsers. + // + jsDate.createDate = function(date) { + // if passing in multiple arguments, try Date constructor + if (date == null) { + return new Date(); + } + // If the passed value is already a date object, return it + if (date instanceof Date) { + return date; + } + // if (typeof date == 'number') return new Date(date * 1000); + // If the passed value is an integer, interpret it as a javascript timestamp + if (typeof date == 'number') { + return new Date(date); + } + + // Before passing strings into Date.parse(), have to normalize them for certain conditions. + // If strings are not formatted staccording to the EcmaScript spec, results from Date parse will be implementation dependent. + // + // For example: + // * FF and Opera assume 2 digit dates are pre y2k, Chome assumes <50 is pre y2k, 50+ is 21st century. + // * Chrome will correctly parse '1984-1-25' into localtime, FF and Opera will not parse. + // * Both FF, Chrome and Opera will parse '1984/1/25' into localtime. + + // remove leading and trailing spaces + var parsable = String(date).replace(/^\s*(.+)\s*$/g, '$1'); + + // replace dahses (-) with slashes (/) in dates like n[nnn]/n[n]/n[nnn] + parsable = parsable.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/, "$1/$2/$3"); + + ///////// + // Need to check for '15-Dec-09' also. + // FF will not parse, but Chrome will. + // Chrome will set date to 2009 as well. + ///////// + + // first check for 'dd-mmm-yyyy' or 'dd/mmm/yyyy' like '15-Dec-2010' + parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i, "$1 $2 $3"); + + // Now check for 'dd-mmm-yy' or 'dd/mmm/yy' and normalize years to default century. + var match = parsable.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i); + if (match && match.length > 3) { + var m3 = parseFloat(match[3]); + var ny = jsDate.config.defaultCentury + m3; + ny = String(ny); + + // now replace 2 digit year with 4 digit year + parsable = parsable.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i, match[1] +' '+ match[2] +' '+ ny); + + } + + // Check for '1/19/70 8:14PM' + // where starts with mm/dd/yy or yy/mm/dd and have something after + // Check if 1st postiion is greater than 31, assume it is year. + // Assme all 2 digit years are 1900's. + // Finally, change them into US style mm/dd/yyyy representations. + match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/); + + function h1(parsable, match) { + var m1 = parseFloat(match[1]); + var m2 = parseFloat(match[2]); + var m3 = parseFloat(match[3]); + var cent = jsDate.config.defaultCentury; + var ny, nd, nm, str; + + if (m1 > 31) { // first number is a year + nd = m3; + nm = m2; + ny = cent + m1; + } + + else { // last number is the year + nd = m2; + nm = m1; + ny = cent + m3; + } + + str = nm+'/'+nd+'/'+ny; + + // now replace 2 digit year with 4 digit year + return parsable.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/, str); + + } + + if (match && match.length > 3) { + parsable = h1(parsable, match); + } + + // Now check for '1/19/70' with nothing after and do as above + var match = parsable.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/); + + if (match && match.length > 3) { + parsable = h1(parsable, match); + } + + + var i = 0; + var length = jsDate.matchers.length; + var pattern, + ms, + current = parsable, + obj; + while (i < length) { + ms = Date.parse(current); + if (!isNaN(ms)) { + return new Date(ms); + } + pattern = jsDate.matchers[i]; + if (typeof pattern == 'function') { + obj = pattern.call(jsDate, current); + if (obj instanceof Date) { + return obj; + } + } else { + current = parsable.replace(pattern[0], pattern[1]); + } + i++; + } + return NaN; + }; + + + /** + * @static + * Handy static utility function to return the number of days in a given month. + * @param {Integer} year Year + * @param {Integer} month Month (1-12) + * @returns {Integer} Number of days in the month. + */ + // + // handy utility method Borrowed right from Ken Snyder's Date Instance Mehtods. + // + jsDate.daysInMonth = function(year, month) { + if (month == 2) { + return new Date(year, 1, 29).getDate() == 29 ? 29 : 28; + } + return [undefined,31,undefined,31,30,31,30,31,31,30,31,30,31][month]; + }; + + + // + // An Array of regular expressions or functions that will attempt to match the date string. + // Functions are called with scope of a jsDate instance. + // + jsDate.matchers = [ + // convert dd.mmm.yyyy to mm/dd/yyyy (world date to US date). + [/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/, '$2/$1/$3'], + // convert yyyy-mm-dd to mm/dd/yyyy (ISO date to US date). + [/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/, '$2/$3/$1'], + // Handle 12 hour or 24 hour time with milliseconds am/pm and optional date part. + function(str) { + var match = str.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i); + // opt. date hour opt. minute opt. second opt. msec opt. am or pm + if (match) { + if (match[1]) { + var d = this.createDate(match[1]); + if (isNaN(d)) { + return; + } + } else { + var d = new Date(); + d.setMilliseconds(0); + } + var hour = parseFloat(match[2]); + if (match[6]) { + hour = match[6].toLowerCase() == 'am' ? (hour == 12 ? 0 : hour) : (hour == 12 ? 12 : hour + 12); + } + d.setHours(hour, parseInt(match[3] || 0, 10), parseInt(match[4] || 0, 10), ((parseFloat(match[5] || 0)) || 0)*1000); + return d; + } + else { + return str; + } + }, + // Handle ISO timestamp with time zone. + function(str) { + var match = str.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i); + if (match) { + if (match[1]) { + var d = this.createDate(match[1]); + if (isNaN(d)) { + return; + } + } else { + var d = new Date(); + d.setMilliseconds(0); + } + var hour = parseFloat(match[2]); + d.setHours(hour, parseInt(match[3], 10), parseInt(match[4], 10), parseFloat(match[5])*1000); + return d; + } + else { + return str; + } + }, + // Try to match ambiguous strings like 12/8/22. + // Use FF date assumption that 2 digit years are 20th century (i.e. 1900's). + // This may be redundant with pre processing of date already performed. + function(str) { + var match = str.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/); + if (match) { + var d = new Date(); + var cent = jsDate.config.defaultCentury; + var m1 = parseFloat(match[1]); + var m3 = parseFloat(match[3]); + var ny, nd, nm; + if (m1 > 31) { // first number is a year + nd = m3; + ny = cent + m1; + } + + else { // last number is the year + nd = m1; + ny = cent + m3; + } + + var nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNamesShort"]); + + if (nm == -1) { + nm = inArray(match[2], jsDate.regional[jsDate.regional.getLocale()]["monthNames"]); + } + + d.setFullYear(ny, nm, nd); + d.setHours(0,0,0,0); + return d; + } + + else { + return str; + } + } + ]; + + // + // I think John Reisig published this method on his blog, ejohn. + // + function inArray( elem, array ) { + if ( array.indexOf ) { + return array.indexOf( elem ); + } + + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === elem ) { + return i; + } + } + + return -1; + } + + // + // Thanks to Kangax, Christian Sciberras and Stack Overflow for this method. + // + function get_type(thing){ + if(thing===null) return "[object Null]"; // special case + return Object.prototype.toString.call(thing); + } + + $.jsDate = jsDate; + + + /** + * JavaScript printf/sprintf functions. + * + * This code has been adapted from the publicly available sprintf methods + * by Ash Searle. His original header follows: + * + * This code is unrestricted: you are free to use it however you like. + * + * The functions should work as expected, performing left or right alignment, + * truncating strings, outputting numbers with a required precision etc. + * + * For complex cases, these functions follow the Perl implementations of + * (s)printf, allowing arguments to be passed out-of-order, and to set the + * precision or length of the output based on arguments instead of fixed + * numbers. + * + * See http://perldoc.perl.org/functions/sprintf.html for more information. + * + * Implemented: + * - zero and space-padding + * - right and left-alignment, + * - base X prefix (binary, octal and hex) + * - positive number prefix + * - (minimum) width + * - precision / truncation / maximum width + * - out of order arguments + * + * Not implemented (yet): + * - vector flag + * - size (bytes, words, long-words etc.) + * + * Will not implement: + * - %n or %p (no pass-by-reference in JavaScript) + * + * @version 2007.04.27 + * @author Ash Searle + * + * You can see the original work and comments on his blog: + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + */ + + /** + * @Modifications 2009.05.26 + * @author Chris Leonello + * + * Added %p %P specifier + * Acts like %g or %G but will not add more significant digits to the output than present in the input. + * Example: + * Format: '%.3p', Input: 0.012, Output: 0.012 + * Format: '%.3g', Input: 0.012, Output: 0.0120 + * Format: '%.4p', Input: 12.0, Output: 12.0 + * Format: '%.4g', Input: 12.0, Output: 12.00 + * Format: '%.4p', Input: 4.321e-5, Output: 4.321e-5 + * Format: '%.4g', Input: 4.321e-5, Output: 4.3210e-5 + * + * Example: + * >>> $.jqplot.sprintf('%.2f, %d', 23.3452, 43.23) + * "23.35, 43" + * >>> $.jqplot.sprintf("no value: %n, decimal with thousands separator: %'d", 23.3452, 433524) + * "no value: , decimal with thousands separator: 433,524" + */ + $.jqplot.sprintf = function() { + function pad(str, len, chr, leftJustify) { + var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); + return leftJustify ? str + padding : padding + str; + + } + + function thousand_separate(value) { + var value_str = new String(value); + for (var i=10; i>0; i--) { + if (value_str == (value_str = value_str.replace(/^(\d+)(\d{3})/, "$1"+$.jqplot.sprintf.thousandsSeparator+"$2"))) break; + } + return value_str; + } + + function justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace) { + var diff = minWidth - value.length; + if (diff > 0) { + var spchar = ' '; + if (htmlSpace) { spchar = ' '; } + if (leftJustify || !zeroPad) { + value = pad(value, minWidth, spchar, leftJustify); + } else { + value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); + } + } + return value; + } + + function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad, htmlSpace) { + // Note: casts negative numbers to positive ones + var number = value >>> 0; + prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || ''; + value = prefix + pad(number.toString(base), precision || 0, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); + } + + function formatString(value, leftJustify, minWidth, precision, zeroPad, htmlSpace) { + if (precision != null) { + value = value.slice(0, precision); + } + return justify(value, '', leftJustify, minWidth, zeroPad, htmlSpace); + } + + var a = arguments, i = 0, format = a[i++]; + + return format.replace($.jqplot.sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) { + if (substring == '%%') { return '%'; } + + // parse flags + var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, htmlSpace = false, thousandSeparation = false; + for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) { + case ' ': positivePrefix = ' '; break; + case '+': positivePrefix = '+'; break; + case '-': leftJustify = true; break; + case '0': zeroPad = true; break; + case '#': prefixBaseX = true; break; + case '&': htmlSpace = true; break; + case '\'': thousandSeparation = true; break; + } + + // parameters may be null, undefined, empty-string or real valued + // we want to ignore null, undefined and empty-string values + + if (!minWidth) { + minWidth = 0; + } + else if (minWidth == '*') { + minWidth = +a[i++]; + } + else if (minWidth.charAt(0) == '*') { + minWidth = +a[minWidth.slice(1, -1)]; + } + else { + minWidth = +minWidth; + } + + // Note: undocumented perl feature: + if (minWidth < 0) { + minWidth = -minWidth; + leftJustify = true; + } + + if (!isFinite(minWidth)) { + throw new Error('$.jqplot.sprintf: (minimum-)width must be finite'); + } + + if (!precision) { + precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0); + } + else if (precision == '*') { + precision = +a[i++]; + } + else if (precision.charAt(0) == '*') { + precision = +a[precision.slice(1, -1)]; + } + else { + precision = +precision; + } + + // grab value using valueIndex if required? + var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; + + switch (type) { + case 's': { + if (value == null) { + return ''; + } + return formatString(String(value), leftJustify, minWidth, precision, zeroPad, htmlSpace); + } + case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad, htmlSpace); + case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad,htmlSpace); + case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); + case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); + case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace).toUpperCase(); + case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad, htmlSpace); + case 'i': { + var number = parseInt(+value, 10); + if (isNaN(number)) { + return ''; + } + var prefix = number < 0 ? '-' : positivePrefix; + var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); + value = prefix + pad(number_str, precision, '0', false); + //value = prefix + pad(String(Math.abs(number)), precision, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); + } + case 'd': { + var number = Math.round(+value); + if (isNaN(number)) { + return ''; + } + var prefix = number < 0 ? '-' : positivePrefix; + var number_str = thousandSeparation ? thousand_separate(String(Math.abs(number))): String(Math.abs(number)); + value = prefix + pad(number_str, precision, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace); + } + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + { + var number = +value; + if (isNaN(number)) { + return ''; + } + var prefix = number < 0 ? '-' : positivePrefix; + var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; + var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; + var number_str = Math.abs(number)[method](precision); + + // Apply the decimal mark properly by splitting the number by the + // decimalMark, applying thousands separator, and then placing it + // back in. + var parts = number_str.toString().split('.'); + parts[0] = thousandSeparation ? thousand_separate(parts[0]) : parts[0]; + number_str = parts.join($.jqplot.sprintf.decimalMark); + + value = prefix + number_str; + var justified = justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); + + return justified; + } + case 'p': + case 'P': + { + // make sure number is a number + var number = +value; + if (isNaN(number)) { + return ''; + } + var prefix = number < 0 ? '-' : positivePrefix; + + var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); + var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : String(number).length; + var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; + + if (Math.abs(number) < 1) { + if (sd + zeros <= precision) { + value = prefix + Math.abs(number).toPrecision(sd); + } + else { + if (sd <= precision - 1) { + value = prefix + Math.abs(number).toExponential(sd-1); + } + else { + value = prefix + Math.abs(number).toExponential(precision-1); + } + } + } + else { + var prec = (sd <= precision) ? sd : precision; + value = prefix + Math.abs(number).toPrecision(prec); + } + var textTransform = ['toString', 'toUpperCase']['pP'.indexOf(type) % 2]; + return justify(value, prefix, leftJustify, minWidth, zeroPad, htmlSpace)[textTransform](); + } + case 'n': return ''; + default: return substring; + } + }); + }; + + $.jqplot.sprintf.thousandsSeparator = ','; + // Specifies the decimal mark for floating point values. By default a period '.' + // is used. If you change this value to for example a comma be sure to also + // change the thousands separator or else this won't work since a simple String + // replace is used (replacing all periods with the mark specified here). + $.jqplot.sprintf.decimalMark = '.'; + + $.jqplot.sprintf.regex = /%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g; + + $.jqplot.getSignificantFigures = function(number) { + var parts = String(Number(Math.abs(number)).toExponential()).split(/e|E/); + // total significant digits + var sd = (parts[0].indexOf('.') != -1) ? parts[0].length - 1 : parts[0].length; + var zeros = (parts[1] < 0) ? -parts[1] - 1 : 0; + // exponent + var expn = parseInt(parts[1], 10); + // digits to the left of the decimal place + var dleft = (expn + 1 > 0) ? expn + 1 : 0; + // digits to the right of the decimal place + var dright = (sd <= dleft) ? 0 : sd - expn - 1; + return {significantDigits: sd, digitsLeft: dleft, digitsRight: dright, zeros: zeros, exponent: expn} ; + }; + + $.jqplot.getPrecision = function(number) { + return $.jqplot.getSignificantFigures(number).digitsRight; + }; + + + + + var backCompat = $.uiBackCompat !== false; + + $.jqplot.effects = { + effect: {} + }; + + // prefix used for storing data on .data() + var dataSpace = "jqplot.storage."; + + /******************************************************************************/ + /*********************************** EFFECTS **********************************/ + /******************************************************************************/ + + $.extend( $.jqplot.effects, { + version: "1.9pre", + + // Saves a set of properties in a data storage + save: function( element, set ) { + for( var i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + for( var i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); + } + } + }, + + setMode: function( el, mode ) { + if (mode === "toggle") { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { + + // if the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" )) { + return element.parent(); + } + + // wrap the element + var props = { + width: element.outerWidth(true), + height: element.outerHeight(true), + "float": element.css( "float" ) + }, + wrapper = $( "<div></div>" ) + .addClass( "ui-effects-wrapper" ) + .css({ + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + }), + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element + + // transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css({ position: "relative" }); + element.css({ position: "relative" }); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + }); + $.each([ "top", "left", "bottom", "right" ], function(i, pos) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; + } + }); + element.css({ + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + }); + } + element.css(size); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + } + + + return element; + } + }); + + // return an effect options object for the given parameters: + function _normalizeArguments( effect, options, speed, callback ) { + + // short path for passing an effect options object: + if ( $.isPlainObject( effect ) ) { + return effect; + } + + // convert to an object + effect = { effect: effect }; + + // catch (effect) + if ( options === undefined ) { + options = {}; + } + + // catch (effect, callback) + if ( $.isFunction( options ) ) { + callback = options; + speed = null; + options = {}; + } + + // catch (effect, speed, ?) + if ( $.type( options ) === "number" || $.fx.speeds[ options ]) { + callback = speed; + speed = options; + options = {}; + } + + // catch (effect, options, callback) + if ( $.isFunction( speed ) ) { + callback = speed; + speed = null; + } + + // add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : typeof speed === "number" + ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; + } + + function standardSpeed( speed ) { + // valid standard speeds + if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { + return true; + } + + // invalid strings - treat as "normal" speed + if ( typeof speed === "string" && !$.jqplot.effects.effect[ speed ] ) { + // TODO: remove in 2.0 (#7115) + if ( backCompat && $.jqplot.effects[ speed ] ) { + return false; + } + return true; + } + + return false; + } + + $.fn.extend({ + jqplotEffect: function( effect, options, speed, callback ) { + var args = _normalizeArguments.apply( this, arguments ), + mode = args.mode, + queue = args.queue, + effectMethod = $.jqplot.effects.effect[ args.effect ], + + // DEPRECATED: remove in 2.0 (#7115) + oldEffectMethod = !effectMethod && backCompat && $.jqplot.effects[ args.effect ]; + + if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, args.complete ); + } else { + return this.each( function() { + if ( args.complete ) { + args.complete.call( this ); + } + }); + } + } + + function run( next ) { + var elem = $( this ), + complete = args.complete, + mode = args.mode; + + function done() { + if ( $.isFunction( complete ) ) { + complete.call( elem[0] ); + } + if ( $.isFunction( next ) ) { + next(); + } + } + + // if the element is hiddden and mode is hide, + // or element is visible and mode is show + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + done(); + } else { + effectMethod.call( elem[0], args, done ); + } + } + + // TODO: remove this check in 2.0, effectMethod will always be true + if ( effectMethod ) { + return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); + } else { + // DEPRECATED: remove in 2.0 (#7115) + return oldEffectMethod.call(this, { + options: args, + duration: args.duration, + callback: args.complete, + mode: args.mode + }); + } + } + }); + + + + + var rvertical = /up|down|vertical/, + rpositivemotion = /up|left|vertical|horizontal/; + + $.jqplot.effects.effect.blind = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.jqplot.effects.setMode( el, o.mode || "hide" ), + direction = o.direction || "up", + vertical = rvertical.test( direction ), + ref = vertical ? "height" : "width", + ref2 = vertical ? "top" : "left", + motion = rpositivemotion.test( direction ), + animation = {}, + show = mode === "show", + wrapper, distance, top; + + // // if already wrapped, the wrapper's properties are my property. #6245 + if ( el.parent().is( ".ui-effects-wrapper" ) ) { + $.jqplot.effects.save( el.parent(), props ); + } else { + $.jqplot.effects.save( el, props ); + } + el.show(); + top = parseInt(el.css('top'), 10); + wrapper = $.jqplot.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + distance = vertical ? wrapper[ ref ]() + top : wrapper[ ref ](); + + animation[ ref ] = show ? String(distance) : '0'; + if ( !motion ) { + el + .css( vertical ? "bottom" : "right", 0 ) + .css( vertical ? "top" : "left", "" ) + .css({ position: "absolute" }); + animation[ ref2 ] = show ? '0' : String(distance); + } + + // // start at 0 if we are showing + if ( show ) { + wrapper.css( ref, 0 ); + if ( ! motion ) { + wrapper.css( ref2, distance ); + } + } + + // // Animate + wrapper.animate( animation, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.jqplot.effects.restore( el, props ); + $.jqplot.effects.removeWrapper( el ); + done(); + } + }); + + }; + +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.css b/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.css new file mode 100644 index 0000000..0f84835 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.css @@ -0,0 +1 @@ +.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em}.jqplot-axis{font-size:.75em}.jqplot-xaxis{margin-top:10px}.jqplot-x2axis{margin-bottom:10px}.jqplot-yaxis{margin-right:10px}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom}.jqplot-yaxis-tick{right:0;top:15px;text-align:right}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute}.jqplot-yMidAxis-label{font-size:11pt;position:absolute}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute}.jqplot-meterGauge-tick{font-size:.75em;color:#999}.jqplot-meterGauge-label{font-size:1em;color:#999}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em}td.jqplot-table-legend{vertical-align:middle}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px}.jqplot-point-label{font-size:.75em;z-index:2}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em}.jqplot-error{text-align:center}.jqplot-error-message{position:relative;top:46%;display:inline-block}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%)}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7)}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3)} \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.js b/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.js new file mode 100644 index 0000000..f25712c --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/jquery.jqplot.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(L){var u;L.fn.emptyForce=function(){for(var ah=0,ai;(ai=L(this)[ah])!=null;ah++){if(ai.nodeType===1){L.cleanData(ai.getElementsByTagName("*"))}if(L.jqplot.use_excanvas){ai.outerHTML=""}else{while(ai.firstChild){ai.removeChild(ai.firstChild)}}ai=null}return L(this)};L.fn.removeChildForce=function(ah){while(ah.firstChild){this.removeChildForce(ah.firstChild);ah.removeChild(ah.firstChild)}};L.fn.jqplot=function(){var ah=[];var aj=[];for(var ak=0,ai=arguments.length;ak<ai;ak++){if(L.isArray(arguments[ak])){ah.push(arguments[ak])}else{if(L.isPlainObject(arguments[ak])){aj.push(arguments[ak])}}}return this.each(function(an){var at,ar,aq=L(this),am=ah.length,al=aj.length,ap,ao;if(an<am){ap=ah[an]}else{ap=am?ah[am-1]:null}if(an<al){ao=aj[an]}else{ao=al?aj[al-1]:null}at=aq.attr("id");if(at===u){at="jqplot_target_"+L.jqplot.targetCounter++;aq.attr("id",at)}ar=L.jqplot(at,ap,ao);aq.data("jqplot",ar)})};L.jqplot=function(an,ak,ai){var aj=null,ah=null;if(arguments.length===3){aj=ak;ah=ai}else{if(arguments.length===2){if(L.isArray(ak)){aj=ak}else{if(L.isPlainObject(ak)){ah=ak}}}}if(aj===null&&ah!==null&&ah.data){aj=ah.data}var am=new R();L("#"+an).removeClass("jqplot-error");if(L.jqplot.config.catchErrors){try{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}catch(al){var ao=L.jqplot.config.errorMessage||al.message;L("#"+an).append('<div class="jqplot-error-message">'+ao+"</div>");L("#"+an).addClass("jqplot-error");document.getElementById(an).style.background=L.jqplot.config.errorBackground;document.getElementById(an).style.border=L.jqplot.config.errorBorder;document.getElementById(an).style.fontFamily=L.jqplot.config.errorFontFamily;document.getElementById(an).style.fontSize=L.jqplot.config.errorFontSize;document.getElementById(an).style.fontStyle=L.jqplot.config.errorFontStyle;document.getElementById(an).style.fontWeight=L.jqplot.config.errorFontWeight}}else{am.init(an,aj,ah);am.draw();am.themeEngine.init.call(am);return am}};L.jqplot.version="1.0.8";L.jqplot.revision="1250";L.jqplot.targetCounter=1;L.jqplot.CanvasManager=function(){if(typeof L.jqplot.CanvasManager.canvases=="undefined"){L.jqplot.CanvasManager.canvases=[];L.jqplot.CanvasManager.free=[]}var ah=[];this.getCanvas=function(){var ak;var aj=true;if(!L.jqplot.use_excanvas){for(var al=0,ai=L.jqplot.CanvasManager.canvases.length;al<ai;al++){if(L.jqplot.CanvasManager.free[al]===true){aj=false;ak=L.jqplot.CanvasManager.canvases[al];L.jqplot.CanvasManager.free[al]=false;ah.push(al);break}}}if(aj){ak=document.createElement("canvas");ah.push(L.jqplot.CanvasManager.canvases.length);L.jqplot.CanvasManager.canvases.push(ak);L.jqplot.CanvasManager.free.push(false)}return ak};this.initCanvas=function(ai){if(L.jqplot.use_excanvas){return window.G_vmlCanvasManager.initElement(ai)}return ai};this.freeAllCanvases=function(){for(var aj=0,ai=ah.length;aj<ai;aj++){this.freeCanvas(ah[aj])}ah=[]};this.freeCanvas=function(ai){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(L.jqplot.CanvasManager.canvases[ai]);L.jqplot.CanvasManager.canvases[ai]=null}else{var aj=L.jqplot.CanvasManager.canvases[ai];aj.getContext("2d").clearRect(0,0,aj.width,aj.height);L(aj).unbind().removeAttr("class").removeAttr("style");L(aj).css({left:"",top:"",position:""});aj.width=0;aj.height=0;L.jqplot.CanvasManager.free[ai]=true}}};L.jqplot.log=function(){if(window.console){window.console.log.apply(window.console,arguments)}};L.jqplot.config={addDomReference:false,enablePlugins:false,defaultHeight:300,defaultWidth:400,UTCAdjust:false,timezoneOffset:new Date(new Date().getTimezoneOffset()*60000),errorMessage:"",errorBackground:"",errorBorder:"",errorFontFamily:"",errorFontSize:"",errorFontStyle:"",errorFontWeight:"",catchErrors:false,defaultTickFormatString:"%.1f",defaultColors:["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"],defaultNegativeColors:["#498991","#C08840","#9F9274","#546D61","#646C4A","#6F6621","#6E3F5F","#4F64B0","#A89050","#C45923","#187399","#945381","#959E5C","#C7AF7B","#478396","#907294"],dashLength:4,gapLength:4,dotGapLength:2.5,srcLocation:"jqplot/src/",pluginLocation:"jqplot/src/plugins/"};L.jqplot.arrayMax=function(ah){return Math.max.apply(Math,ah)};L.jqplot.arrayMin=function(ah){return Math.min.apply(Math,ah)};L.jqplot.enablePlugins=L.jqplot.config.enablePlugins;L.jqplot.support_canvas=function(){if(typeof L.jqplot.support_canvas.result=="undefined"){L.jqplot.support_canvas.result=!!document.createElement("canvas").getContext}return L.jqplot.support_canvas.result};L.jqplot.support_canvas_text=function(){if(typeof L.jqplot.support_canvas_text.result=="undefined"){if(window.G_vmlCanvasManager!==u&&window.G_vmlCanvasManager._version>887){L.jqplot.support_canvas_text.result=true}else{L.jqplot.support_canvas_text.result=!!(document.createElement("canvas").getContext&&typeof document.createElement("canvas").getContext("2d").fillText=="function")}}return L.jqplot.support_canvas_text.result};L.jqplot.use_excanvas=((!L.support.boxModel||!L.support.objectAll||!$support.leadingWhitespace)&&!L.jqplot.support_canvas())?true:false;L.jqplot.preInitHooks=[];L.jqplot.postInitHooks=[];L.jqplot.preParseOptionsHooks=[];L.jqplot.postParseOptionsHooks=[];L.jqplot.preDrawHooks=[];L.jqplot.postDrawHooks=[];L.jqplot.preDrawSeriesHooks=[];L.jqplot.postDrawSeriesHooks=[];L.jqplot.preDrawLegendHooks=[];L.jqplot.addLegendRowHooks=[];L.jqplot.preSeriesInitHooks=[];L.jqplot.postSeriesInitHooks=[];L.jqplot.preParseSeriesOptionsHooks=[];L.jqplot.postParseSeriesOptionsHooks=[];L.jqplot.eventListenerHooks=[];L.jqplot.preDrawSeriesShadowHooks=[];L.jqplot.postDrawSeriesShadowHooks=[];L.jqplot.ElemContainer=function(){this._elem;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null}};L.jqplot.ElemContainer.prototype.createElement=function(ak,am,ai,aj,an){this._offsets=am;var ah=ai||"jqplot";var al=document.createElement(ak);this._elem=L(al);this._elem.addClass(ah);this._elem.css(aj);this._elem.attr(an);al=null;return this._elem};L.jqplot.ElemContainer.prototype.getWidth=function(){if(this._elem){return this._elem.outerWidth(true)}else{return null}};L.jqplot.ElemContainer.prototype.getHeight=function(){if(this._elem){return this._elem.outerHeight(true)}else{return null}};L.jqplot.ElemContainer.prototype.getPosition=function(){if(this._elem){return this._elem.position()}else{return{top:null,left:null,bottom:null,right:null}}};L.jqplot.ElemContainer.prototype.getTop=function(){return this.getPosition().top};L.jqplot.ElemContainer.prototype.getLeft=function(){return this.getPosition().left};L.jqplot.ElemContainer.prototype.getBottom=function(){return this._elem.css("bottom")};L.jqplot.ElemContainer.prototype.getRight=function(){return this._elem.css("right")};function w(ah){L.jqplot.ElemContainer.call(this);this.name=ah;this._series=[];this.show=false;this.tickRenderer=L.jqplot.AxisTickRenderer;this.tickOptions={};this.labelRenderer=L.jqplot.AxisLabelRenderer;this.labelOptions={};this.label=null;this.showLabel=true;this.min=null;this.max=null;this.autoscale=false;this.pad=1.2;this.padMax=null;this.padMin=null;this.ticks=[];this.numberTicks;this.tickInterval;this.renderer=L.jqplot.LinearAxisRenderer;this.rendererOptions={};this.showTicks=true;this.showTickMarks=true;this.showMinorTicks=true;this.drawMajorGridlines=true;this.drawMinorGridlines=false;this.drawMajorTickMarks=true;this.drawMinorTickMarks=true;this.useSeriesColor=false;this.borderWidth=null;this.borderColor=null;this.scaleToHiddenSeries=false;this._dataBounds={min:null,max:null};this._intervalStats=[];this._offsets={min:null,max:null};this._ticks=[];this._label=null;this.syncTicks=null;this.tickSpacing=75;this._min=null;this._max=null;this._tickInterval=null;this._numberTicks=null;this.__ticks=null;this._options={}}w.prototype=new L.jqplot.ElemContainer();w.prototype.constructor=w;w.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.tickOptions.axis=this.name;if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTicks}if(this.tickOptions.showMark==null){this.tickOptions.showMark=this.showTickMarks}if(this.tickOptions.showLabel==null){this.tickOptions.showLabel=this.showTicks}if(this.label==null||this.label==""){this.showLabel=false}else{this.labelOptions.label=this.label}if(this.showLabel==false){this.labelOptions.show=false}if(this.pad==0){this.pad=1}if(this.padMax==0){this.padMax=1}if(this.padMin==0){this.padMin=1}if(this.padMax==null){this.padMax=(this.pad-1)/2+1}if(this.padMin==null){this.padMin=(this.pad-1)/2+1}this.pad=this.padMax+this.padMin-1;if(this.min!=null||this.max!=null){this.autoscale=false}if(this.syncTicks==null&&this.name.indexOf("y")>-1){this.syncTicks=true}else{if(this.syncTicks==null){this.syncTicks=false}}this.renderer.init.call(this,this.rendererOptions)};w.prototype.draw=function(ah,ai){if(this.__ticks){this.__ticks=null}return this.renderer.draw.call(this,ah,ai)};w.prototype.set=function(){this.renderer.set.call(this)};w.prototype.pack=function(ai,ah){if(this.show){this.renderer.pack.call(this,ai,ah)}if(this._min==null){this._min=this.min;this._max=this.max;this._tickInterval=this.tickInterval;this._numberTicks=this.numberTicks;this.__ticks=this._ticks}};w.prototype.reset=function(){this.renderer.reset.call(this)};w.prototype.resetScale=function(ah){L.extend(true,this,{min:null,max:null,numberTicks:null,tickInterval:null,_ticks:[],ticks:[]},ah);this.resetDataBounds()};w.prototype.resetDataBounds=function(){var ao=this._dataBounds;ao.min=null;ao.max=null;var ai,ap,am;var aj=(this.show)?true:false;for(var al=0;al<this._series.length;al++){ap=this._series[al];if(ap.show||this.scaleToHiddenSeries){am=ap._plotData;if(ap._type==="line"&&ap.renderer.bands.show&&this.name.charAt(0)!=="x"){am=[[0,ap.renderer.bands._min],[1,ap.renderer.bands._max]]}var ah=1,an=1;if(ap._type!=null&&ap._type=="ohlc"){ah=3;an=2}for(var ak=0,ai=am.length;ak<ai;ak++){if(this.name=="xaxis"||this.name=="x2axis"){if((am[ak][0]!=null&&am[ak][0]<ao.min)||ao.min==null){ao.min=am[ak][0]}if((am[ak][0]!=null&&am[ak][0]>ao.max)||ao.max==null){ao.max=am[ak][0]}}else{if((am[ak][ah]!=null&&am[ak][ah]<ao.min)||ao.min==null){ao.min=am[ak][ah]}if((am[ak][an]!=null&&am[ak][an]>ao.max)||ao.max==null){ao.max=am[ak][an]}}}if(aj&&ap.renderer.constructor!==L.jqplot.BarRenderer){aj=false}else{if(aj&&this._options.hasOwnProperty("forceTickAt0")&&this._options.forceTickAt0==false){aj=false}else{if(aj&&ap.renderer.constructor===L.jqplot.BarRenderer){if(ap.barDirection=="vertical"&&this.name!="xaxis"&&this.name!="x2axis"){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}else{if(ap.barDirection=="horizontal"&&(this.name=="xaxis"||this.name=="x2axis")){if(this._options.pad!=null||this._options.padMin!=null){aj=false}}}}}}}}if(aj&&this.renderer.constructor===L.jqplot.LinearAxisRenderer&&ao.min>=0){this.padMin=1;this.forceTickAt0=true}};function q(ah){L.jqplot.ElemContainer.call(this);this.show=false;this.location="ne";this.labels=[];this.showLabels=true;this.showSwatches=true;this.placement="insideGrid";this.xoffset=0;this.yoffset=0;this.border;this.background;this.textColor;this.fontFamily;this.fontSize;this.rowSpacing="0.5em";this.renderer=L.jqplot.TableLegendRenderer;this.rendererOptions={};this.preDraw=false;this.marginTop=null;this.marginRight=null;this.marginBottom=null;this.marginLeft=null;this.escapeHtml=false;this._series=[];L.extend(true,this,ah)}q.prototype=new L.jqplot.ElemContainer();q.prototype.constructor=q;q.prototype.setOptions=function(ah){L.extend(true,this,ah);if(this.placement=="inside"){this.placement="insideGrid"}if(this.xoffset>0){if(this.placement=="insideGrid"){switch(this.location){case"nw":case"w":case"sw":if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break;case"ne":case"e":case"se":default:if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break}}else{if(this.placement=="outside"){switch(this.location){case"nw":case"w":case"sw":if(this.marginRight==null){this.marginRight=this.xoffset+"px"}this.marginLeft="0px";break;case"ne":case"e":case"se":default:if(this.marginLeft==null){this.marginLeft=this.xoffset+"px"}this.marginRight="0px";break}}}this.xoffset=0}if(this.yoffset>0){if(this.placement=="outside"){switch(this.location){case"sw":case"s":case"se":if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break;case"ne":case"n":case"nw":default:if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break}}else{if(this.placement=="insideGrid"){switch(this.location){case"sw":case"s":case"se":if(this.marginBottom==null){this.marginBottom=this.yoffset+"px"}this.marginTop="0px";break;case"ne":case"n":case"nw":default:if(this.marginTop==null){this.marginTop=this.yoffset+"px"}this.marginBottom="0px";break}}}this.yoffset=0}};q.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};q.prototype.draw=function(ai,aj){for(var ah=0;ah<L.jqplot.preDrawLegendHooks.length;ah++){L.jqplot.preDrawLegendHooks[ah].call(this,ai)}return this.renderer.draw.call(this,ai,aj)};q.prototype.pack=function(ah){this.renderer.pack.call(this,ah)};function y(ah){L.jqplot.ElemContainer.call(this);this.text=ah;this.show=true;this.fontFamily;this.fontSize;this.textAlign;this.textColor;this.renderer=L.jqplot.DivTitleRenderer;this.rendererOptions={};this.escapeHtml=false}y.prototype=new L.jqplot.ElemContainer();y.prototype.constructor=y;y.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};y.prototype.draw=function(ah){return this.renderer.draw.call(this,ah)};y.prototype.pack=function(){this.renderer.pack.call(this)};function S(ah){ah=ah||{};L.jqplot.ElemContainer.call(this);this.show=true;this.xaxis="xaxis";this._xaxis;this.yaxis="yaxis";this._yaxis;this.gridBorderWidth=2;this.renderer=L.jqplot.LineRenderer;this.rendererOptions={};this.data=[];this.gridData=[];this.label="";this.showLabel=true;this.color;this.negativeColor;this.lineWidth=2.5;this.lineJoin="round";this.lineCap="round";this.linePattern="solid";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.25;this.shadowDepth=3;this.shadowAlpha="0.1";this.breakOnNull=false;this.markerRenderer=L.jqplot.MarkerRenderer;this.markerOptions={};this.showLine=true;this.showMarker=true;this.index;this.fill=false;this.fillColor;this.fillAlpha;this.fillAndStroke=false;this.disableStack=false;this._stack=false;this.neighborThreshold=4;this.fillToZero=false;this.fillToValue=0;this.fillAxis="y";this.useNegativeColors=true;this._stackData=[];this._plotData=[];this._plotValues={x:[],y:[]};this._intervals={x:{},y:{}};this._prevPlotData=[];this._prevGridData=[];this._stackAxis="y";this._primaryAxis="_xaxis";this.canvas=new L.jqplot.GenericCanvas();this.shadowCanvas=new L.jqplot.GenericCanvas();this.plugins={};this._sumy=0;this._sumx=0;this._type=""}S.prototype=new L.jqplot.ElemContainer();S.prototype.constructor=S;S.prototype.init=function(ak,ao,am){this.index=ak;this.gridBorderWidth=ao;var an=this.data;var aj=[],al,ah;for(al=0,ah=an.length;al<ah;al++){if(!this.breakOnNull){if(an[al]==null||an[al][0]==null||an[al][1]==null){continue}else{aj.push(an[al])}}else{aj.push(an[al])}}this.data=aj;if(!this.color){this.color=am.colorGenerator.get(this.index)}if(!this.negativeColor){this.negativeColor=am.negativeColorGenerator.get(this.index)}if(!this.fillColor){this.fillColor=this.color}if(this.fillAlpha){var ai=L.jqplot.normalize2rgb(this.fillColor);var ai=L.jqplot.getColorComponents(ai);this.fillColor="rgba("+ai[0]+","+ai[1]+","+ai[2]+","+this.fillAlpha+")"}if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions,am);this.markerRenderer=new this.markerRenderer();if(!this.markerOptions.color){this.markerOptions.color=this.color}if(this.markerOptions.show==null){this.markerOptions.show=this.showMarker}this.showMarker=this.markerOptions.show;this.markerRenderer.init(this.markerOptions)};S.prototype.draw=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.canvas._ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesHooks.length;ah++){L.jqplot.preDrawSeriesHooks[ah].call(this,an,ai)}if(this.show){this.renderer.setGridData.call(this,am);if(!ai.preventJqPlotSeriesDrawTrigger){L(an.canvas).trigger("jqplotSeriesDraw",[this.data,this.gridData])}al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);if(this._type==="line"&&this.renderer.smooth&&this.renderer._smoothedData.length){aj=this.renderer._smoothedData}this.renderer.draw.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesHooks.length;ah++){L.jqplot.postDrawSeriesHooks[ah].call(this,an,ai,am)}an=ak=am=ah=al=aj=null};S.prototype.drawShadow=function(an,ak,am){var ai=(ak==u)?{}:ak;an=(an==u)?this.shadowCanvas._ctx:an;var ah,al,aj;for(ah=0;ah<L.jqplot.preDrawSeriesShadowHooks.length;ah++){L.jqplot.preDrawSeriesShadowHooks[ah].call(this,an,ai)}if(this.shadow){this.renderer.setGridData.call(this,am);al=[];if(ai.data){al=ai.data}else{if(!this._stack){al=this.data}else{al=this._plotData}}aj=ai.gridData||this.renderer.makeGridData.call(this,al,am);this.renderer.drawShadow.call(this,an,aj,ai,am)}for(ah=0;ah<L.jqplot.postDrawSeriesShadowHooks.length;ah++){L.jqplot.postDrawSeriesShadowHooks[ah].call(this,an,ai)}an=ak=am=ah=al=aj=null};S.prototype.toggleDisplay=function(ai,ak){var ah,aj;if(ai.data.series){ah=ai.data.series}else{ah=this}if(ai.data.speed){aj=ai.data.speed}if(aj){if(ah.canvas._elem.is(":hidden")||!ah.show){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeIn(aj)}ah.canvas._elem.fadeIn(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeIn(aj)}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.fadeOut(aj)}ah.canvas._elem.fadeOut(aj,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).fadeOut(aj)}}else{if(ah.canvas._elem.is(":hidden")||!ah.show){ah.show=true;ah.canvas._elem.removeClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.show()}ah.canvas._elem.show(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).show()}else{ah.show=false;ah.canvas._elem.addClass("jqplot-series-hidden");if(ah.shadowCanvas._elem){ah.shadowCanvas._elem.hide()}ah.canvas._elem.hide(0,ak);ah.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+ah.index).hide()}}};function M(){L.jqplot.ElemContainer.call(this);this.drawGridlines=true;this.gridLineColor="#cccccc";this.gridLineWidth=1;this.background="#fffdf6";this.borderColor="#999999";this.borderWidth=2;this.drawBorder=true;this.shadow=true;this.shadowAngle=45;this.shadowOffset=1.5;this.shadowWidth=3;this.shadowDepth=3;this.shadowColor=null;this.shadowAlpha="0.07";this._left;this._top;this._right;this._bottom;this._width;this._height;this._axes=[];this.renderer=L.jqplot.CanvasGridRenderer;this.rendererOptions={};this._offsets={top:null,bottom:null,left:null,right:null}}M.prototype=new L.jqplot.ElemContainer();M.prototype.constructor=M;M.prototype.init=function(){if(L.isFunction(this.renderer)){this.renderer=new this.renderer()}this.renderer.init.call(this,this.rendererOptions)};M.prototype.createElement=function(ah,ai){this._offsets=ah;return this.renderer.createElement.call(this,ai)};M.prototype.draw=function(){this.renderer.draw.call(this)};L.jqplot.GenericCanvas=function(){L.jqplot.ElemContainer.call(this);this._ctx};L.jqplot.GenericCanvas.prototype=new L.jqplot.ElemContainer();L.jqplot.GenericCanvas.prototype.constructor=L.jqplot.GenericCanvas;L.jqplot.GenericCanvas.prototype.createElement=function(al,aj,ai,am){this._offsets=al;var ah="jqplot";if(aj!=u){ah=aj}var ak;ak=am.canvasManager.getCanvas();if(ai!=null){this._plotDimensions=ai}ak.width=this._plotDimensions.width-this._offsets.left-this._offsets.right;ak.height=this._plotDimensions.height-this._offsets.top-this._offsets.bottom;this._elem=L(ak);this._elem.css({position:"absolute",left:this._offsets.left,top:this._offsets.top});this._elem.addClass(ah);ak=am.canvasManager.initCanvas(ak);ak=null;return this._elem};L.jqplot.GenericCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};L.jqplot.GenericCanvas.prototype.resetCanvas=function(){if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce()}this._ctx=null};L.jqplot.HooksManager=function(){this.hooks=[];this.args=[]};L.jqplot.HooksManager.prototype.addOnce=function(ak,ai){ai=ai||[];var al=false;for(var aj=0,ah=this.hooks.length;aj<ah;aj++){if(this.hooks[aj]==ak){al=true}}if(!al){this.hooks.push(ak);this.args.push(ai)}};L.jqplot.HooksManager.prototype.add=function(ai,ah){ah=ah||[];this.hooks.push(ai);this.args.push(ah)};L.jqplot.EventListenerManager=function(){this.hooks=[]};L.jqplot.EventListenerManager.prototype.addOnce=function(al,ak){var am=false,aj,ai;for(var ai=0,ah=this.hooks.length;ai<ah;ai++){aj=this.hooks[ai];if(aj[0]==al&&aj[1]==ak){am=true}}if(!am){this.hooks.push([al,ak])}};L.jqplot.EventListenerManager.prototype.add=function(ai,ah){this.hooks.push([ai,ah])};var U=["yMidAxis","xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];function R(){this.animate=false;this.animateReplot=false;this.axes={xaxis:new w("xaxis"),yaxis:new w("yaxis"),x2axis:new w("x2axis"),y2axis:new w("y2axis"),y3axis:new w("y3axis"),y4axis:new w("y4axis"),y5axis:new w("y5axis"),y6axis:new w("y6axis"),y7axis:new w("y7axis"),y8axis:new w("y8axis"),y9axis:new w("y9axis"),yMidAxis:new w("yMidAxis")};this.baseCanvas=new L.jqplot.GenericCanvas();this.captureRightClick=false;this.data=[];this.dataRenderer;this.dataRendererOptions;this.defaults={axesDefaults:{},axes:{xaxis:{},yaxis:{},x2axis:{},y2axis:{},y3axis:{},y4axis:{},y5axis:{},y6axis:{},y7axis:{},y8axis:{},y9axis:{},yMidAxis:{}},seriesDefaults:{},series:[]};this.defaultAxisStart=1;this.drawIfHidden=false;this.eventCanvas=new L.jqplot.GenericCanvas();this.fillBetween={series1:null,series2:null,color:null,baseSeries:0,fill:true};this.fontFamily;this.fontSize;this.grid=new M();this.legend=new q();this.noDataIndicator={show:false,indicator:"Loading Data...",axes:{xaxis:{min:0,max:10,tickInterval:2,show:true},yaxis:{min:0,max:12,tickInterval:3,show:true}}};this.negativeSeriesColors=L.jqplot.config.defaultNegativeColors;this.options={};this.previousSeriesStack=[];this.plugins={};this.series=[];this.seriesStack=[];this.seriesColors=L.jqplot.config.defaultColors;this.sortData=true;this.stackSeries=false;this.syncXTicks=true;this.syncYTicks=true;this.target=null;this.targetId=null;this.textColor;this.title=new y();this._drawCount=0;this._sumy=0;this._sumx=0;this._stackData=[];this._plotData=[];this._width=null;this._height=null;this._plotDimensions={height:null,width:null};this._gridPadding={top:null,right:null,bottom:null,left:null};this._defaultGridPadding={top:10,right:10,bottom:23,left:10};this._addDomReference=L.jqplot.config.addDomReference;this.preInitHooks=new L.jqplot.HooksManager();this.postInitHooks=new L.jqplot.HooksManager();this.preParseOptionsHooks=new L.jqplot.HooksManager();this.postParseOptionsHooks=new L.jqplot.HooksManager();this.preDrawHooks=new L.jqplot.HooksManager();this.postDrawHooks=new L.jqplot.HooksManager();this.preDrawSeriesHooks=new L.jqplot.HooksManager();this.postDrawSeriesHooks=new L.jqplot.HooksManager();this.preDrawLegendHooks=new L.jqplot.HooksManager();this.addLegendRowHooks=new L.jqplot.HooksManager();this.preSeriesInitHooks=new L.jqplot.HooksManager();this.postSeriesInitHooks=new L.jqplot.HooksManager();this.preParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.postParseSeriesOptionsHooks=new L.jqplot.HooksManager();this.eventListenerHooks=new L.jqplot.EventListenerManager();this.preDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.postDrawSeriesShadowHooks=new L.jqplot.HooksManager();this.colorGenerator=new L.jqplot.ColorGenerator();this.negativeColorGenerator=new L.jqplot.ColorGenerator();this.canvasManager=new L.jqplot.CanvasManager();this.themeEngine=new L.jqplot.ThemeEngine();var aj=0;this.init=function(av,ar,ay){ay=ay||{};for(var at=0;at<L.jqplot.preInitHooks.length;at++){L.jqplot.preInitHooks[at].call(this,av,ar,ay)}for(var at=0;at<this.preInitHooks.hooks.length;at++){this.preInitHooks.hooks[at].call(this,av,ar,ay)}this.targetId="#"+av;this.target=L("#"+av);if(this._addDomReference){this.target.data("jqplot",this)}this.target.removeClass("jqplot-error");if(!this.target.get(0)){throw new Error("No plot target specified")}if(this.target.css("position")=="static"){this.target.css("position","relative")}if(!this.target.hasClass("jqplot-target")){this.target.addClass("jqplot-target")}if(!this.target.height()){var au;if(ay&&ay.height){au=parseInt(ay.height,10)}else{if(this.target.attr("data-height")){au=parseInt(this.target.attr("data-height"),10)}else{au=parseInt(L.jqplot.config.defaultHeight,10)}}this._height=au;this.target.css("height",au+"px")}else{this._height=au=this.target.height()}if(!this.target.width()){var aw;if(ay&&ay.width){aw=parseInt(ay.width,10)}else{if(this.target.attr("data-width")){aw=parseInt(this.target.attr("data-width"),10)}else{aw=parseInt(L.jqplot.config.defaultWidth,10)}}this._width=aw;this.target.css("width",aw+"px")}else{this._width=aw=this.target.width()}for(var at=0,ap=U.length;at<ap;at++){this.axes[U[at]]=new w(U[at])}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Canvas dimension not set")}if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;ar=this.dataRenderer(ar,this,this.dataRendererOptions)}if(ay.noDataIndicator&&L.isPlainObject(ay.noDataIndicator)){L.extend(true,this.noDataIndicator,ay.noDataIndicator)}if(ar==null||L.isArray(ar)==false||ar.length==0||L.isArray(ar[0])==false||ar[0].length==0){if(this.noDataIndicator.show==false){throw new Error("No data specified")}else{for(var al in this.noDataIndicator.axes){for(var an in this.noDataIndicator.axes[al]){this.axes[al][an]=this.noDataIndicator.axes[al][an]}}this.postDrawHooks.add(function(){var aD=this.eventCanvas.getHeight();var aA=this.eventCanvas.getWidth();var az=L('<div class="jqplot-noData-container" style="position:absolute;"></div>');this.target.append(az);az.height(aD);az.width(aA);az.css("top",this.eventCanvas._offsets.top);az.css("left",this.eventCanvas._offsets.left);var aC=L('<div class="jqplot-noData-contents" style="text-align:center; position:relative; margin-left:auto; margin-right:auto;"></div>');az.append(aC);aC.html(this.noDataIndicator.indicator);var aB=aC.height();var ax=aC.width();aC.height(aB);aC.width(ax);aC.css("top",(aD-aB)/2+"px")})}}this.data=L.extend(true,[],ar);this.parseOptions(ay);if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.computePlotData();for(var at=0;at<this.series.length;at++){this.seriesStack.push(at);this.previousSeriesStack.push(at);this.series[at].shadowCanvas._plotDimensions=this._plotDimensions;this.series[at].canvas._plotDimensions=this._plotDimensions;for(var aq=0;aq<L.jqplot.preSeriesInitHooks.length;aq++){L.jqplot.preSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.preSeriesInitHooks.hooks.length;aq++){this.preSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this.series[at]._plotDimensions=this._plotDimensions;this.series[at].init(at,this.grid.borderWidth,this);for(var aq=0;aq<L.jqplot.postSeriesInitHooks.length;aq++){L.jqplot.postSeriesInitHooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}for(var aq=0;aq<this.postSeriesInitHooks.hooks.length;aq++){this.postSeriesInitHooks.hooks[aq].call(this.series[at],av,this.data,this.options.seriesDefaults,this.options.series[at],this)}this._sumy+=this.series[at]._sumy;this._sumx+=this.series[at]._sumx}var am,ao;for(var at=0,ap=U.length;at<ap;at++){am=U[at];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(this.axes[am].borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var at=0;at<L.jqplot.postInitHooks.length;at++){L.jqplot.postInitHooks[at].call(this,av,this.data,ay)}for(var at=0;at<this.postInitHooks.hooks.length;at++){this.postInitHooks.hooks[at].call(this,av,this.data,ay)}};this.resetAxesScale=function(aq,am){var ao=am||{};var ap=aq||this.axes;if(ap===true){ap=this.axes}if(L.isArray(ap)){for(var an=0;an<ap.length;an++){this.axes[ap[an]].resetScale(ao[ap[an]])}}else{if(typeof(ap)==="object"){for(var al in ap){this.axes[al].resetScale(ao[al])}}}};this.reInitialize=function(au,al){var ay=L.extend(true,{},this.options,al);var aw=this.targetId.substr(1);var ar=(au==null)?this.data:au;for(var av=0;av<L.jqplot.preInitHooks.length;av++){L.jqplot.preInitHooks[av].call(this,aw,ar,ay)}for(var av=0;av<this.preInitHooks.hooks.length;av++){this.preInitHooks.hooks[av].call(this,aw,ar,ay)}this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Target dimension not set")}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;var am,ax,at,ao;for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ax=ao._ticks;for(var at=0,ap=ax.length;at<ap;at++){var an=ax[at]._elem;if(an){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(an.get(0))}an.emptyForce();an=null;ax._elem=null}}ax=null;delete ao.ticks;delete ao._ticks;this.axes[am]=new w(am);this.axes[am]._plotWidth=this._width;this.axes[am]._plotHeight=this._height}if(au){if(ay.dataRenderer&&L.isFunction(ay.dataRenderer)){if(ay.dataRendererOptions){this.dataRendererOptions=ay.dataRendererOptions}this.dataRenderer=ay.dataRenderer;au=this.dataRenderer(au,this,this.dataRendererOptions)}this.data=L.extend(true,[],au)}if(al){this.parseOptions(ay)}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this.title.init();this.legend.init();this._sumy=0;this._sumx=0;this.seriesStack=[];this.previousSeriesStack=[];this.computePlotData();for(var av=0,aq=this.series.length;av<aq;av++){this.seriesStack.push(av);this.previousSeriesStack.push(av);this.series[av].shadowCanvas._plotDimensions=this._plotDimensions;this.series[av].canvas._plotDimensions=this._plotDimensions;for(var at=0;at<L.jqplot.preSeriesInitHooks.length;at++){L.jqplot.preSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}for(var at=0;at<this.preSeriesInitHooks.hooks.length;at++){this.preSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this.series[av]._plotDimensions=this._plotDimensions;this.series[av].init(av,this.grid.borderWidth,this);for(var at=0;at<L.jqplot.postSeriesInitHooks.length;at++){L.jqplot.postSeriesInitHooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}for(var at=0;at<this.postSeriesInitHooks.hooks.length;at++){this.postSeriesInitHooks.hooks[at].call(this.series[av],aw,this.data,this.options.seriesDefaults,this.options.series[av],this)}this._sumy+=this.series[av]._sumy;this._sumx+=this.series[av]._sumx}for(var av=0,aq=U.length;av<aq;av++){am=U[av];ao=this.axes[am];ao._plotDimensions=this._plotDimensions;ao.init();if(ao.borderColor==null){if(am.charAt(0)!=="x"&&ao.useSeriesColor===true&&ao.show){ao.borderColor=ao._series[0].color}else{ao.borderColor=this.grid.borderColor}}}if(this.sortData){ah(this.series)}this.grid.init();this.grid._axes=this.axes;this.legend._series=this.series;for(var av=0,aq=L.jqplot.postInitHooks.length;av<aq;av++){L.jqplot.postInitHooks[av].call(this,aw,this.data,ay)}for(var av=0,aq=this.postInitHooks.hooks.length;av<aq;av++){this.postInitHooks.hooks[av].call(this,aw,this.data,ay)}};this.quickInit=function(){this._height=this.target.height();this._width=this.target.width();if(this._height<=0||this._width<=0||!this._height||!this._width){throw new Error("Target dimension not set")}this._plotDimensions.height=this._height;this._plotDimensions.width=this._width;this.grid._plotDimensions=this._plotDimensions;this.title._plotDimensions=this._plotDimensions;this.baseCanvas._plotDimensions=this._plotDimensions;this.eventCanvas._plotDimensions=this._plotDimensions;this.legend._plotDimensions=this._plotDimensions;for(var aq in this.axes){this.axes[aq]._plotWidth=this._width;this.axes[aq]._plotHeight=this._height}this.title._plotWidth=this._width;if(this.textColor){this.target.css("color",this.textColor)}if(this.fontFamily){this.target.css("font-family",this.fontFamily)}if(this.fontSize){this.target.css("font-size",this.fontSize)}this._sumy=0;this._sumx=0;this.computePlotData();for(var ao=0;ao<this.series.length;ao++){if(this.series[ao]._type==="line"&&this.series[ao].renderer.bands.show){this.series[ao].renderer.initBands.call(this.series[ao],this.series[ao].renderer.options,this)}this.series[ao]._plotDimensions=this._plotDimensions;this.series[ao].canvas._plotDimensions=this._plotDimensions;this._sumy+=this.series[ao]._sumy;this._sumx+=this.series[ao]._sumx}var am;for(var al=0;al<12;al++){am=U[al];var an=this.axes[am]._ticks;for(var ao=0;ao<an.length;ao++){var ap=an[ao]._elem;if(ap){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){window.G_vmlCanvasManager.uninitElement(ap.get(0))}ap.emptyForce();ap=null;an._elem=null}}an=null;this.axes[am]._plotDimensions=this._plotDimensions;this.axes[am]._ticks=[]}if(this.sortData){ah(this.series)}this.grid._axes=this.axes;this.legend._series=this.series};function ah(ap){var au,av,aw,al,at;for(var aq=0;aq<ap.length;aq++){var am;var ar=[ap[aq].data,ap[aq]._stackData,ap[aq]._plotData,ap[aq]._prevPlotData];for(var an=0;an<4;an++){am=true;au=ar[an];if(ap[aq]._stackAxis=="x"){for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][1])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[1]-ax[1]})}}else{for(var ao=0;ao<au.length;ao++){if(typeof(au[ao][0])!="number"){am=false;break}}if(am){au.sort(function(ay,ax){return ay[0]-ax[0]})}}}}}this.computePlotData=function(){this._plotData=[];this._stackData=[];var at,au,ao;for(au=0,ao=this.series.length;au<ao;au++){at=this.series[au];this._plotData.push([]);this._stackData.push([]);var am=at.data;this._plotData[au]=L.extend(true,[],am);this._stackData[au]=L.extend(true,[],am);at._plotData=this._plotData[au];at._stackData=this._stackData[au];var ax={x:[],y:[]};if(this.stackSeries&&!at.disableStack){at._stack=true;var av=(at._stackAxis==="x")?0:1;for(var ap=0,al=am.length;ap<al;ap++){var aw=am[ap][av];if(aw==null){aw=0}this._plotData[au][ap][av]=aw;this._stackData[au][ap][av]=aw;if(au>0){for(var aq=au;aq--;){var an=this._plotData[aq][ap][av];if(aw*an>=0){this._plotData[au][ap][av]+=an;this._stackData[au][ap][av]+=an;break}}}}}else{for(var ar=0;ar<at.data.length;ar++){ax.x.push(at.data[ar][0]);ax.y.push(at.data[ar][1])}this._stackData.push(at.data);this.series[au]._stackData=at.data;this._plotData.push(at.data);at._plotData=at.data;at._plotValues=ax}if(au>0){at._prevPlotData=this.series[au-1]._plotData}at._sumy=0;at._sumx=0;for(ar=at.data.length-1;ar>-1;ar--){at._sumy+=at.data[ar][1];at._sumx+=at.data[ar][0]}}};this.populatePlotData=function(au,av){this._plotData=[];this._stackData=[];au._stackData=[];au._plotData=[];var ay={x:[],y:[]};if(this.stackSeries&&!au.disableStack){au._stack=true;var ax=(au._stackAxis==="x")?0:1;var az=L.extend(true,[],au.data);var aA=L.extend(true,[],au.data);var an,am,ao,aw,al;for(var ar=0;ar<av;ar++){var ap=this.series[ar].data;for(var aq=0;aq<ap.length;aq++){ao=ap[aq];an=(ao[0]!=null)?ao[0]:0;am=(ao[1]!=null)?ao[1]:0;az[aq][0]+=an;az[aq][1]+=am;aw=(ax)?am:an;if(au.data[aq][ax]*aw>=0){aA[aq][ax]+=aw}}}for(var at=0;at<aA.length;at++){ay.x.push(aA[at][0]);ay.y.push(aA[at][1])}this._plotData.push(aA);this._stackData.push(az);au._stackData=az;au._plotData=aA;au._plotValues=ay}else{for(var at=0;at<au.data.length;at++){ay.x.push(au.data[at][0]);ay.y.push(au.data[at][1])}this._stackData.push(au.data);this.series[av]._stackData=au.data;this._plotData.push(au.data);au._plotData=au.data;au._plotValues=ay}if(av>0){au._prevPlotData=this.series[av-1]._plotData}au._sumy=0;au._sumx=0;for(at=au.data.length-1;at>-1;at--){au._sumy+=au.data[at][1];au._sumx+=au.data[at][0]}};this.getNextSeriesColor=(function(am){var al=0;var an=am.seriesColors;return function(){if(al<an.length){return an[al++]}else{al=0;return an[al++]}}})(this);this.parseOptions=function(ay){for(var at=0;at<this.preParseOptionsHooks.hooks.length;at++){this.preParseOptionsHooks.hooks[at].call(this,ay)}for(var at=0;at<L.jqplot.preParseOptionsHooks.length;at++){L.jqplot.preParseOptionsHooks[at].call(this,ay)}this.options=L.extend(true,{},this.defaults,ay);var am=this.options;this.animate=am.animate;this.animateReplot=am.animateReplot;this.stackSeries=am.stackSeries;if(L.isPlainObject(am.fillBetween)){var ax=["series1","series2","color","baseSeries","fill"],au;for(var at=0,aq=ax.length;at<aq;at++){au=ax[at];if(am.fillBetween[au]!=null){this.fillBetween[au]=am.fillBetween[au]}}}if(am.seriesColors){this.seriesColors=am.seriesColors}if(am.negativeSeriesColors){this.negativeSeriesColors=am.negativeSeriesColors}if(am.captureRightClick){this.captureRightClick=am.captureRightClick}this.defaultAxisStart=(ay&&ay.defaultAxisStart!=null)?ay.defaultAxisStart:this.defaultAxisStart;this.colorGenerator.setColors(this.seriesColors);this.negativeColorGenerator.setColors(this.negativeSeriesColors);L.extend(true,this._gridPadding,am.gridPadding);this.sortData=(am.sortData!=null)?am.sortData:this.sortData;for(var at=0;at<12;at++){var an=U[at];var ap=this.axes[an];ap._options=L.extend(true,{},am.axesDefaults,am.axes[an]);L.extend(true,ap,am.axesDefaults,am.axes[an]);ap._plotWidth=this._width;ap._plotHeight=this._height}var aw=function(aD,aB,aE){var aA=[];var aC,az;aB=aB||"vertical";if(!L.isArray(aD[0])){for(aC=0,az=aD.length;aC<az;aC++){if(aB=="vertical"){aA.push([aE+aC,aD[aC]])}else{aA.push([aD[aC],aE+aC])}}}else{L.extend(true,aA,aD)}return aA};var av=0;this.series=[];for(var at=0;at<this.data.length;at++){var al=L.extend(true,{index:at},{seriesColors:this.seriesColors,negativeSeriesColors:this.negativeSeriesColors},this.options.seriesDefaults,this.options.series[at],{rendererOptions:{animation:{show:this.animate}}});var ax=new S(al);for(var ar=0;ar<L.jqplot.preParseSeriesOptionsHooks.length;ar++){L.jqplot.preParseSeriesOptionsHooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.preParseSeriesOptionsHooks.hooks.length;ar++){this.preParseSeriesOptionsHooks.hooks[ar].call(ax,this.options.seriesDefaults,this.options.series[at])}L.extend(true,ax,al);var ao="vertical";if(ax.renderer===L.jqplot.BarRenderer&&ax.rendererOptions&&ax.rendererOptions.barDirection=="horizontal"){ao="horizontal";ax._stackAxis="x";ax._primaryAxis="_yaxis"}ax.data=aw(this.data[at],ao,this.defaultAxisStart);switch(ax.xaxis){case"xaxis":ax._xaxis=this.axes.xaxis;break;case"x2axis":ax._xaxis=this.axes.x2axis;break;default:break}ax._yaxis=this.axes[ax.yaxis];ax._xaxis._series.push(ax);ax._yaxis._series.push(ax);if(ax.show){ax._xaxis.show=true;ax._yaxis.show=true}else{if(ax._xaxis.scaleToHiddenSeries){ax._xaxis.show=true}if(ax._yaxis.scaleToHiddenSeries){ax._yaxis.show=true}}if(!ax.label){ax.label="Series "+(at+1).toString()}this.series.push(ax);for(var ar=0;ar<L.jqplot.postParseSeriesOptionsHooks.length;ar++){L.jqplot.postParseSeriesOptionsHooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}for(var ar=0;ar<this.postParseSeriesOptionsHooks.hooks.length;ar++){this.postParseSeriesOptionsHooks.hooks[ar].call(this.series[at],this.options.seriesDefaults,this.options.series[at])}}L.extend(true,this.grid,this.options.grid);for(var at=0,aq=U.length;at<aq;at++){var an=U[at];var ap=this.axes[an];if(ap.borderWidth==null){ap.borderWidth=this.grid.borderWidth}}if(typeof this.options.title=="string"){this.title.text=this.options.title}else{if(typeof this.options.title=="object"){L.extend(true,this.title,this.options.title)}}this.title._plotWidth=this._width;this.legend.setOptions(this.options.legend);for(var at=0;at<L.jqplot.postParseOptionsHooks.length;at++){L.jqplot.postParseOptionsHooks[at].call(this,ay)}for(var at=0;at<this.postParseOptionsHooks.hooks.length;at++){this.postParseOptionsHooks.hooks[at].call(this,ay)}};this.destroy=function(){this.canvasManager.freeAllCanvases();if(this.eventCanvas&&this.eventCanvas._elem){this.eventCanvas._elem.unbind()}this.target.empty();this.target[0].innerHTML=""};this.replot=function(am){var an=am||{};var ap=an.data||null;var al=(an.clear===false)?false:true;var ao=an.resetAxes||false;delete an.data;delete an.clear;delete an.resetAxes;this.target.trigger("jqplotPreReplot");if(al){this.destroy()}if(ap||!L.isEmptyObject(an)){this.reInitialize(ap,an)}else{this.quickInit()}if(ao){this.resetAxesScale(ao,an.axes)}this.draw();this.target.trigger("jqplotPostReplot")};this.redraw=function(al){al=(al!=null)?al:true;this.target.trigger("jqplotPreRedraw");if(al){this.canvasManager.freeAllCanvases();this.eventCanvas._elem.unbind();this.target.empty()}for(var an in this.axes){this.axes[an]._ticks=[]}this.computePlotData();this._sumy=0;this._sumx=0;for(var am=0,ao=this.series.length;am<ao;am++){this._sumy+=this.series[am]._sumy;this._sumx+=this.series[am]._sumx}this.draw();this.target.trigger("jqplotPostRedraw")};this.draw=function(){if(this.drawIfHidden||this.target.is(":visible")){this.target.trigger("jqplotPreDraw");var aH,aF,aE,ao;for(aH=0,aE=L.jqplot.preDrawHooks.length;aH<aE;aH++){L.jqplot.preDrawHooks[aH].call(this)}for(aH=0,aE=this.preDrawHooks.hooks.length;aH<aE;aH++){this.preDrawHooks.hooks[aH].apply(this,this.preDrawSeriesHooks.args[aH])}this.target.append(this.baseCanvas.createElement({left:0,right:0,top:0,bottom:0},"jqplot-base-canvas",null,this));this.baseCanvas.setContext();this.target.append(this.title.draw());this.title.pack({top:0,left:0});var aL=this.legend.draw({},this);var al={top:0,left:0,bottom:0,right:0};if(this.legend.placement=="outsideGrid"){this.target.append(aL);switch(this.legend.location){case"n":al.top+=this.legend.getHeight();break;case"s":al.bottom+=this.legend.getHeight();break;case"ne":case"e":case"se":al.right+=this.legend.getWidth();break;case"nw":case"w":case"sw":al.left+=this.legend.getWidth();break;default:al.right+=this.legend.getWidth();break}aL=aL.detach()}var ar=this.axes;var aM;for(aH=0;aH<12;aH++){aM=U[aH];this.target.append(ar[aM].draw(this.baseCanvas._ctx,this));ar[aM].set()}if(ar.yaxis.show){al.left+=ar.yaxis.getWidth()}var aG=["y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis"];var az=[0,0,0,0,0,0,0,0];var aC=0;var aB;for(aB=0;aB<8;aB++){if(ar[aG[aB]].show){aC+=ar[aG[aB]].getWidth();az[aB]=aC}}al.right+=aC;if(ar.x2axis.show){al.top+=ar.x2axis.getHeight()}if(this.title.show){al.top+=this.title.getHeight()}if(ar.xaxis.show){al.bottom+=ar.xaxis.getHeight()}if(this.options.gridDimensions&&L.isPlainObject(this.options.gridDimensions)){var at=parseInt(this.options.gridDimensions.width,10)||0;var aI=parseInt(this.options.gridDimensions.height,10)||0;var an=(this._width-al.left-al.right-at)/2;var aK=(this._height-al.top-al.bottom-aI)/2;if(aK>=0&&an>=0){al.top+=aK;al.bottom+=aK;al.left+=an;al.right+=an}}var am=["top","bottom","left","right"];for(var aB in am){if(this._gridPadding[am[aB]]==null&&al[am[aB]]>0){this._gridPadding[am[aB]]=al[am[aB]]}else{if(this._gridPadding[am[aB]]==null){this._gridPadding[am[aB]]=this._defaultGridPadding[am[aB]]}}}var aA=this._gridPadding;if(this.legend.placement==="outsideGrid"){aA={top:this.title.getHeight(),left:0,right:0,bottom:0};if(this.legend.location==="s"){aA.left=this._gridPadding.left;aA.right=this._gridPadding.right}}ar.xaxis.pack({position:"absolute",bottom:this._gridPadding.bottom-ar.xaxis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});ar.yaxis.pack({position:"absolute",top:0,left:this._gridPadding.left-ar.yaxis.getWidth(),height:this._height},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});ar.x2axis.pack({position:"absolute",top:this._gridPadding.top-ar.x2axis.getHeight(),left:0,width:this._width},{min:this._gridPadding.left,max:this._width-this._gridPadding.right});for(aH=8;aH>0;aH--){ar[aG[aH-1]].pack({position:"absolute",top:0,right:this._gridPadding.right-az[aH-1]},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top})}var au=(this._width-this._gridPadding.left-this._gridPadding.right)/2+this._gridPadding.left-ar.yMidAxis.getWidth()/2;ar.yMidAxis.pack({position:"absolute",top:0,left:au,zIndex:9,textAlign:"center"},{min:this._height-this._gridPadding.bottom,max:this._gridPadding.top});this.target.append(this.grid.createElement(this._gridPadding,this));this.grid.draw();var aq=this.series;var aJ=aq.length;for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].shadowCanvas.createElement(this._gridPadding,"jqplot-series-shadowCanvas",null,this));aq[aF].shadowCanvas.setContext();aq[aF].shadowCanvas._elem.data("seriesIndex",aF)}for(aH=0,aE=aJ;aH<aE;aH++){aF=this.seriesStack[aH];this.target.append(aq[aF].canvas.createElement(this._gridPadding,"jqplot-series-canvas",null,this));aq[aF].canvas.setContext();aq[aF].canvas._elem.data("seriesIndex",aF)}this.target.append(this.eventCanvas.createElement(this._gridPadding,"jqplot-event-canvas",null,this));this.eventCanvas.setContext();this.eventCanvas._ctx.fillStyle="rgba(0,0,0,0)";this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width,this.eventCanvas._ctx.canvas.height);this.bindCustomEvents();if(this.legend.preDraw){this.eventCanvas._elem.before(aL);this.legend.pack(aA);if(this.legend._elem){this.drawSeries({legendInfo:{location:this.legend.location,placement:this.legend.placement,width:this.legend.getWidth(),height:this.legend.getHeight(),xoffset:this.legend.xoffset,yoffset:this.legend.yoffset}})}else{this.drawSeries()}}else{this.drawSeries();if(aJ){L(aq[aJ-1].canvas._elem).after(aL)}this.legend.pack(aA)}for(var aH=0,aE=L.jqplot.eventListenerHooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(L.jqplot.eventListenerHooks[aH][0],{plot:this},L.jqplot.eventListenerHooks[aH][1])}for(var aH=0,aE=this.eventListenerHooks.hooks.length;aH<aE;aH++){this.eventCanvas._elem.bind(this.eventListenerHooks.hooks[aH][0],{plot:this},this.eventListenerHooks.hooks[aH][1])}var ay=this.fillBetween;if(ay.fill&&ay.series1!==ay.series2&&ay.series1<aJ&&ay.series2<aJ&&aq[ay.series1]._type==="line"&&aq[ay.series2]._type==="line"){this.doFillBetweenLines()}for(var aH=0,aE=L.jqplot.postDrawHooks.length;aH<aE;aH++){L.jqplot.postDrawHooks[aH].call(this)}for(var aH=0,aE=this.postDrawHooks.hooks.length;aH<aE;aH++){this.postDrawHooks.hooks[aH].apply(this,this.postDrawHooks.args[aH])}if(this.target.is(":visible")){this._drawCount+=1}var av,aw,aD,ap;for(aH=0,aE=aJ;aH<aE;aH++){av=aq[aH];aw=av.renderer;aD=".jqplot-point-label.jqplot-series-"+aH;if(aw.animation&&aw.animation._supported&&aw.animation.show&&(this._drawCount<2||this.animateReplot)){ap=this.target.find(aD);ap.stop(true,true).hide();av.canvas._elem.stop(true,true).hide();av.shadowCanvas._elem.stop(true,true).hide();av.canvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw.animation.speed);av.shadowCanvas._elem.jqplotEffect("blind",{mode:"show",direction:aw.animation.direction},aw.animation.speed);ap.fadeIn(aw.animation.speed*0.8)}}ap=null;this.target.trigger("jqplotPostDraw",[this])}};R.prototype.doFillBetweenLines=function(){var an=this.fillBetween;var ax=an.series1;var av=an.series2;var aw=(ax<av)?ax:av;var au=(av>ax)?av:ax;var ar=this.series[aw];var aq=this.series[au];if(aq.renderer.smooth){var ap=aq.renderer._smoothedData.slice(0).reverse()}else{var ap=aq.gridData.slice(0).reverse()}if(ar.renderer.smooth){var at=ar.renderer._smoothedData.concat(ap)}else{var at=ar.gridData.concat(ap)}var ao=(an.color!==null)?an.color:this.series[ax].fillColor;var ay=(an.baseSeries!==null)?an.baseSeries:aw;var am=this.series[ay].renderer.shapeRenderer;var al={fillStyle:ao,fill:true,closePath:true};am.draw(ar.shadowCanvas._ctx,at,al)};this.bindCustomEvents=function(){this.eventCanvas._elem.bind("click",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("mousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("mousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("mouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("mouseup",{plot:this},this.onMouseUp)}};function ai(av){var au=av.data.plot;var ap=au.eventCanvas._elem.offset();var at={x:av.pageX-ap.left,y:av.pageY-ap.top};var aq={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var ar=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var al=au.axes;var am,ao;for(am=11;am>0;am--){ao=ar[am-1];if(al[ao].show){aq[ao]=al[ao].series_p2u(at[ao.charAt(0)])}}return{offsets:ap,gridPos:at,dataPos:aq}}function ak(al,am){var aq=am.series;var aW,aU,aT,aO,aP,aJ,aI,aw,au,az,aA,aK;var aS,aX,aQ,ar,aH,aM,aV;var an,aN;for(aT=am.seriesStack.length-1;aT>=0;aT--){aW=am.seriesStack[aT];aO=aq[aW];aV=aO._highlightThreshold;switch(aO.renderer.constructor){case L.jqplot.BarRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]&&aJ<aH[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.PyramidRenderer:aJ=al.x;aI=al.y;for(aU=0;aU<aO._barPoints.length;aU++){aH=aO._barPoints[aU];aQ=aO.gridData[aU];if(aJ>aH[0][0]+aV[0][0]&&aJ<aH[2][0]+aV[2][0]&&aI>aH[2][1]&&aI<aH[0][1]){return{seriesIndex:aO.index,pointIndex:aU,gridData:aQ,data:aO.data[aU],points:aO._barPoints[aU]}}}break;case L.jqplot.DonutRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius&&aP>aO._innerRadius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:[al.x,al.y],data:aO.data[aU]}}}}break;case L.jqplot.PieRenderer:az=aO.startAngle/180*Math.PI;aJ=al.x-aO._center[0];aI=al.y-aO._center[1];aP=Math.sqrt(Math.pow(aJ,2)+Math.pow(aI,2));if(aJ>0&&-aI>=0){aw=2*Math.PI-Math.atan(-aI/aJ)}else{if(aJ>0&&-aI<0){aw=-Math.atan(-aI/aJ)}else{if(aJ<0){aw=Math.PI-Math.atan(-aI/aJ)}else{if(aJ==0&&-aI>0){aw=3*Math.PI/2}else{if(aJ==0&&-aI<0){aw=Math.PI/2}else{if(aJ==0&&aI==0){aw=0}}}}}}if(az){aw-=az;if(aw<0){aw+=2*Math.PI}else{if(aw>2*Math.PI){aw-=2*Math.PI}}}au=aO.sliceMargin/180*Math.PI;if(aP<aO._radius){for(aU=0;aU<aO.gridData.length;aU++){aA=(aU>0)?aO.gridData[aU-1][1]+au:au;aK=aO.gridData[aU][1];if(aw>aA&&aw<aK){return{seriesIndex:aO.index,pointIndex:aU,gridData:[al.x,al.y],data:aO.data[aU]}}}}break;case L.jqplot.BubbleRenderer:aJ=al.x;aI=al.y;var aF=null;if(aO.show){for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=aQ[2]&&(aX<=aS||aS==null)){aS=aX;aF={seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}if(aF!=null){return aF}}break;case L.jqplot.FunnelRenderer:aJ=al.x;aI=al.y;var aL=aO._vertices,ap=aL[0],ao=aL[aL.length-1],at,aE,ay;function aR(a0,a2,a1){var aZ=(a2[1]-a1[1])/(a2[0]-a1[0]);var aY=a2[1]-aZ*a2[0];var a3=a0+a2[1];return[(a3-aY)/aZ,a3]}at=aR(aI,ap[0],ao[3]);aE=aR(aI,ap[1],ao[2]);for(aU=0;aU<aL.length;aU++){ay=aL[aU];if(aI>=ay[0][1]&&aI<=ay[3][1]&&aJ>=at[0]&&aJ<=aE[0]){return{seriesIndex:aO.index,pointIndex:aU,gridData:null,data:aO.data[aU]}}}break;case L.jqplot.LineRenderer:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){if((aO.fill||(aO.renderer.bands.show&&aO.renderer.bands.fill))&&(!am.plugins.highlighter||!am.plugins.highlighter.show)){var ax=false;if(aJ>aO._boundingBox[0][0]&&aJ<aO._boundingBox[1][0]&&aI>aO._boundingBox[1][1]&&aI<aO._boundingBox[0][1]){var aD=aO._areaPoints.length;var aG;var aU=aD-1;for(var aG=0;aG<aD;aG++){var aC=[aO._areaPoints[aG][0],aO._areaPoints[aG][1]];var aB=[aO._areaPoints[aU][0],aO._areaPoints[aU][1]];if(aC[1]<aI&&aB[1]>=aI||aB[1]<aI&&aC[1]>=aI){if(aC[0]+(aI-aC[1])/(aB[1]-aC[1])*(aB[0]-aC[0])<aJ){ax=!ax}}aU=aG}}if(ax){return{seriesIndex:aW,pointIndex:null,gridData:aO.gridData,data:aO.data,points:aO._areaPoints}}break}else{aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{if(aQ[0]!=null&&aQ[1]!=null){aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}}}break;default:aJ=al.x;aI=al.y;aP=aO.renderer;if(aO.show){aN=aO.markerRenderer.size/2+aO.neighborThreshold;an=(aN>0)?aN:0;for(var aU=0;aU<aO.gridData.length;aU++){aQ=aO.gridData[aU];if(aP.constructor==L.jqplot.OHLCRenderer){if(aP.candleStick){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._bodyWidth/2&&aJ<=aQ[0]+aP._bodyWidth/2&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{if(!aP.hlc){var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][2])&&aI<=av(aO.data[aU][3])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}else{var av=aO._yaxis.series_u2p;if(aJ>=aQ[0]-aP._tickLength&&aJ<=aQ[0]+aP._tickLength&&aI>=av(aO.data[aU][1])&&aI<=av(aO.data[aU][2])){return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}else{aX=Math.sqrt((aJ-aQ[0])*(aJ-aQ[0])+(aI-aQ[1])*(aI-aQ[1]));if(aX<=an&&(aX<=aS||aS==null)){aS=aX;return{seriesIndex:aW,pointIndex:aU,gridData:aQ,data:aO.data[aU]}}}}}break}}return null}this.onClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onDblClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotDblClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseDown=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseDown");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseUp=function(an){var am=ai(an);var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,null,an.data.plot])};this.onRightClick=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);if(ap.captureRightClick){if(an.which==3){var al=L.Event("jqplotRightClick");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}else{var al=L.Event("jqplotMouseUp");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])}}};this.onMouseMove=function(an){var am=ai(an);var ap=an.data.plot;var ao=ak(am.gridPos,ap);var al=L.Event("jqplotMouseMove");al.pageX=an.pageX;al.pageY=an.pageY;L(this).trigger(al,[am.gridPos,am.dataPos,ao,ap])};this.onMouseEnter=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseEnter");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.onMouseLeave=function(an){var am=ai(an);var ao=an.data.plot;var al=L.Event("jqplotMouseLeave");al.pageX=an.pageX;al.pageY=an.pageY;al.relatedTarget=an.relatedTarget;L(this).trigger(al,[am.gridPos,am.dataPos,null,ao])};this.drawSeries=function(an,al){var ap,ao,am;al=(typeof(an)==="number"&&al==null)?an:al;an=(typeof(an)==="object")?an:{};if(al!=u){ao=this.series[al];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this);if(ao.renderer.constructor==L.jqplot.BezierCurveRenderer){if(al<this.series.length-1){this.drawSeries(al+1)}}}else{for(ap=0;ap<this.series.length;ap++){ao=this.series[ap];am=ao.shadowCanvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.drawShadow(am,an,this);am=ao.canvas._ctx;am.clearRect(0,0,am.canvas.width,am.canvas.height);ao.draw(am,an,this)}}an=al=ap=ao=am=null};this.moveSeriesToFront=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==-1){return}if(ap==this.seriesStack.length-1){this.previousSeriesStack=this.seriesStack.slice(0);return}var al=this.seriesStack[this.seriesStack.length-1];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.after(an);this.series[al].canvas._elem.after(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.push(am)};this.moveSeriesToBack=function(am){am=parseInt(am,10);var ap=L.inArray(am,this.seriesStack);if(ap==0||ap==-1){return}var al=this.seriesStack[0];var ao=this.series[am].canvas._elem.detach();var an=this.series[am].shadowCanvas._elem.detach();this.series[al].shadowCanvas._elem.before(an);this.series[al].canvas._elem.before(ao);this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack.splice(ap,1);this.seriesStack.unshift(am)};this.restorePreviousSeriesOrder=function(){var ar,aq,ap,ao,an,al,am;if(this.seriesStack==this.previousSeriesStack){return}for(ar=1;ar<this.previousSeriesStack.length;ar++){al=this.previousSeriesStack[ar];am=this.previousSeriesStack[ar-1];ap=this.series[al].canvas._elem.detach();ao=this.series[al].shadowCanvas._elem.detach();this.series[am].shadowCanvas._elem.after(ao);this.series[am].canvas._elem.after(ap)}an=this.seriesStack.slice(0);this.seriesStack=this.previousSeriesStack.slice(0);this.previousSeriesStack=an};this.restoreOriginalSeriesOrder=function(){var ap,ao,al=[],an,am;for(ap=0;ap<this.series.length;ap++){al.push(ap)}if(this.seriesStack==al){return}this.previousSeriesStack=this.seriesStack.slice(0);this.seriesStack=al;for(ap=1;ap<this.seriesStack.length;ap++){an=this.series[ap].canvas._elem.detach();am=this.series[ap].shadowCanvas._elem.detach();this.series[ap-1].shadowCanvas._elem.after(am);this.series[ap-1].canvas._elem.after(an)}};this.activateTheme=function(al){this.themeEngine.activate(this,al)}}L.jqplot.computeHighlightColors=function(ai){var ak;if(L.isArray(ai)){ak=[];for(var am=0;am<ai.length;am++){var al=L.jqplot.getColorComponents(ai[am]);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak.push("rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")")}}else{var al=L.jqplot.getColorComponents(ai);var ah=[al[0],al[1],al[2]];var an=ah[0]+ah[1]+ah[2];for(var aj=0;aj<3;aj++){ah[aj]=(an>660)?ah[aj]*0.85:0.73*ah[aj]+90;ah[aj]=parseInt(ah[aj],10);(ah[aj]>255)?255:ah[aj]}ah[3]=0.3+0.35*al[3];ak="rgba("+ah[0]+","+ah[1]+","+ah[2]+","+ah[3]+")"}return ak};L.jqplot.ColorGenerator=function(ai){ai=ai||L.jqplot.config.defaultColors;var ah=0;this.next=function(){if(ah<ai.length){return ai[ah++]}else{ah=0;return ai[ah++]}};this.previous=function(){if(ah>0){return ai[ah--]}else{ah=ai.length-1;return ai[ah]}};this.get=function(ak){var aj=ak-ai.length*Math.floor(ak/ai.length);return ai[aj]};this.setColors=function(aj){ai=aj};this.reset=function(){ah=0};this.getIndex=function(){return ah};this.setIndex=function(aj){ah=aj}};L.jqplot.hex2rgb=function(aj,ah){aj=aj.replace("#","");if(aj.length==3){aj=aj.charAt(0)+aj.charAt(0)+aj.charAt(1)+aj.charAt(1)+aj.charAt(2)+aj.charAt(2)}var ai;ai="rgba("+parseInt(aj.slice(0,2),16)+", "+parseInt(aj.slice(2,4),16)+", "+parseInt(aj.slice(4,6),16);if(ah){ai+=", "+ah}ai+=")";return ai};L.jqplot.rgb2hex=function(am){var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *(?:, *[0-9.]*)?\)/;var ah=am.match(aj);var al="#";for(var ak=1;ak<4;ak++){var ai;if(ah[ak].search(/%/)!=-1){ai=parseInt(255*ah[ak]/100,10).toString(16);if(ai.length==1){ai="0"+ai}}else{ai=parseInt(ah[ak],10).toString(16);if(ai.length==1){ai="0"+ai}}al+=ai}return al};L.jqplot.normalize2rgb=function(ai,ah){if(ai.search(/^ *rgba?\(/)!=-1){return ai}else{if(ai.search(/^ *#?[0-9a-fA-F]?[0-9a-fA-F]/)!=-1){return L.jqplot.hex2rgb(ai,ah)}else{throw new Error("Invalid color spec")}}};L.jqplot.getColorComponents=function(am){am=L.jqplot.colorKeywordMap[am]||am;var ak=L.jqplot.normalize2rgb(am);var aj=/rgba?\( *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *, *([0-9]{1,3}\.?[0-9]*%?) *,? *([0-9.]* *)?\)/;var ah=ak.match(aj);var ai=[];for(var al=1;al<4;al++){if(ah[al].search(/%/)!=-1){ai[al-1]=parseInt(255*ah[al]/100,10)}else{ai[al-1]=parseInt(ah[al],10)}}ai[3]=parseFloat(ah[4])?parseFloat(ah[4]):1;return ai};L.jqplot.colorKeywordMap={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb( 0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb( 0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb( 0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb( 95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(220, 20, 60)",cyan:"rgb( 0, 255, 255)",darkblue:"rgb( 0, 0, 139)",darkcyan:"rgb( 0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgreen:"rgb( 0, 100, 0)",darkgrey:"rgb(169, 169, 169)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb( 85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb( 72, 61, 139)",darkslategray:"rgb( 47, 79, 79)",darkslategrey:"rgb( 47, 79, 79)",darkturquoise:"rgb( 0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb( 0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb( 30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb( 34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb( 0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb( 75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgray:"rgb(211, 211, 211)",lightgreen:"rgb(144, 238, 144)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb( 32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb( 0, 255, 0)",limegreen:"rgb( 50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb( 0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb( 60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb( 0, 250, 154)",mediumturquoise:"rgb( 72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb( 25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb( 0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb( 65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb( 46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb( 0, 255, 127)",steelblue:"rgb( 70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb( 0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb( 64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)"};L.jqplot.AxisLabelRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.axis;this.show=true;this.label="";this.fontFamily=null;this.fontSize=null;this.textColor=null;this._elem;this.escapeHTML=false;L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisLabelRenderer.prototype.constructor=L.jqplot.AxisLabelRenderer;L.jqplot.AxisLabelRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisLabelRenderer.prototype.draw=function(ah,ai){if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L('<div style="position:absolute;" class="jqplot-'+this.axis+'-label"></div>');if(Number(this.label)){this._elem.css("white-space","nowrap")}if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}return this._elem};L.jqplot.AxisLabelRenderer.prototype.pack=function(){};L.jqplot.AxisTickRenderer=function(ah){L.jqplot.ElemContainer.call(this);this.mark="outside";this.axis;this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.size=4;this.markSize=6;this.show=true;this.showLabel=true;this.label=null;this.value=null;this._styles={};this.formatter=L.jqplot.DefaultTickFormatter;this.prefix="";this.suffix="";this.formatString="";this.fontFamily;this.fontSize;this.textColor;this.escapeHTML=false;this._elem;this._breakTick=false;L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.AxisTickRenderer.prototype=new L.jqplot.ElemContainer();L.jqplot.AxisTickRenderer.prototype.constructor=L.jqplot.AxisTickRenderer;L.jqplot.AxisTickRenderer.prototype.setTick=function(ah,aj,ai){this.value=ah;this.axis=aj;if(ai){this.isMinorTick=true}return this};L.jqplot.AxisTickRenderer.prototype.draw=function(){if(this.label===null){this.label=this.prefix+this.formatter(this.formatString,this.value)+this.suffix}var ai={position:"absolute"};if(Number(this.label)){ai.whitSpace="nowrap"}if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-"+this.axis+"-tick");if(!this.escapeHTML){this._elem.html(this.label)}else{this._elem.text(this.label)}this._elem.css(ai);for(var ah in this._styles){this._elem.css(ah,this._styles[ah])}if(this.fontFamily){this._elem.css("font-family",this.fontFamily)}if(this.fontSize){this._elem.css("font-size",this.fontSize)}if(this.textColor){this._elem.css("color",this.textColor)}if(this._breakTick){this._elem.addClass("jqplot-breakTick")}return this._elem};L.jqplot.DefaultTickFormatter=function(ah,ai){if(typeof ai=="number"){if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.PercentTickFormatter=function(ah,ai){if(typeof ai=="number"){ai=100*ai;if(!ah){ah=L.jqplot.config.defaultTickFormatString}return L.jqplot.sprintf(ah,ai)}else{return String(ai)}};L.jqplot.AxisTickRenderer.prototype.pack=function(){};L.jqplot.CanvasGridRenderer=function(){this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.CanvasGridRenderer.prototype.init=function(ai){this._ctx;L.extend(true,this,ai);var ah={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(ah)};L.jqplot.CanvasGridRenderer.prototype.createElement=function(ak){var aj;if(this._elem){if(L.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==u){aj=this._elem.get(0);window.G_vmlCanvasManager.uninitElement(aj);aj=null}this._elem.emptyForce();this._elem=null}aj=ak.canvasManager.getCanvas();var ah=this._plotDimensions.width;var ai=this._plotDimensions.height;aj.width=ah;aj.height=ai;this._elem=L(aj);this._elem.addClass("jqplot-grid-canvas");this._elem.css({position:"absolute",left:0,top:0});aj=ak.canvasManager.initCanvas(aj);this._top=this._offsets.top;this._bottom=ai-this._offsets.bottom;this._left=this._offsets.left;this._right=ah-this._offsets.right;this._width=this._right-this._left;this._height=this._bottom-this._top;aj=null;return this._elem};L.jqplot.CanvasGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var at=this._ctx;var aw=this._axes;at.save();at.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);at.fillStyle=this.backgroundColor||this.background;at.fillRect(this._left,this._top,this._width,this._height);at.save();at.lineJoin="miter";at.lineCap="butt";at.lineWidth=this.gridLineWidth;at.strokeStyle=this.gridLineColor;var aA,az,ap,aq;var am=["xaxis","yaxis","x2axis","y2axis"];for(var ay=4;ay>0;ay--){var aD=am[ay-1];var ah=aw[aD];var aB=ah._ticks;var ar=aB.length;if(ah.show){if(ah.drawBaseline){var aC={};if(ah.baselineWidth!==null){aC.lineWidth=ah.baselineWidth}if(ah.baselineColor!==null){aC.strokeStyle=ah.baselineColor}switch(aD){case"xaxis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"yaxis":ao(this._left,this._bottom,this._left,this._top,aC);break;case"x2axis":ao(this._left,this._bottom,this._right,this._bottom,aC);break;case"y2axis":ao(this._right,this._bottom,this._right,this._top,aC);break}}for(var au=ar;au>0;au--){var an=aB[au-1];if(an.show){var ak=Math.round(ah.u2p(an.value))+0.5;switch(aD){case"xaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._top,ak,this._bottom)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._bottom;az=this._bottom+ap;break;case"inside":aA=this._bottom-ap;az=this._bottom;break;case"cross":aA=this._bottom-ap;az=this._bottom+ap;break;default:aA=this._bottom;az=this._bottom+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"yaxis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._right,ak,this._left,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._left-ap;az=this._left;break;case"inside":aA=this._left;az=this._left+ap;break;case"cross":aA=this._left-ap;az=this._left+ap;break;default:aA=this._left-ap;az=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;case"x2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(ak,this._bottom,ak,this._top)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._top-ap;az=this._top;break;case"inside":aA=this._top;az=this._top+ap;break;case"cross":aA=this._top-ap;az=this._top+ap;break;default:aA=this._top-ap;az=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[ak,aA],[ak,az]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}ao(ak,aA,ak,az)}break;case"y2axis":if(an.showGridline&&this.drawGridlines&&((!an.isMinorTick&&ah.drawMajorGridlines)||(an.isMinorTick&&ah.drawMinorGridlines))){ao(this._left,ak,this._right,ak)}if(an.showMark&&an.mark&&((!an.isMinorTick&&ah.drawMajorTickMarks)||(an.isMinorTick&&ah.drawMinorTickMarks))){ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;switch(aq){case"outside":aA=this._right;az=this._right+ap;break;case"inside":aA=this._right-ap;az=this._right;break;case"cross":aA=this._right-ap;az=this._right+ap;break;default:aA=this._right;az=this._right+ap;break}if(this.shadow){this.renderer.shadowRenderer.draw(at,[[aA,ak],[az,ak]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}break;default:break}}}an=null}ah=null;aB=null}am=["y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];for(var ay=7;ay>0;ay--){var ah=aw[am[ay-1]];var aB=ah._ticks;if(ah.show){var ai=aB[ah.numberTicks-1];var al=aB[0];var aj=ah.getLeft();var av=[[aj,ai.getTop()+ai.getHeight()/2],[aj,al.getTop()+al.getHeight()/2+1]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",fill:false,closePath:false})}ao(av[0][0],av[0][1],av[1][0],av[1][1],{lineCap:"butt",strokeStyle:ah.borderColor,lineWidth:ah.borderWidth});for(var au=aB.length;au>0;au--){var an=aB[au-1];ap=an.markSize;aq=an.mark;var ak=Math.round(ah.u2p(an.value))+0.5;if(an.showMark&&an.mark){switch(aq){case"outside":aA=aj;az=aj+ap;break;case"inside":aA=aj-ap;az=aj;break;case"cross":aA=aj-ap;az=aj+ap;break;default:aA=aj;az=aj+ap;break}av=[[aA,ak],[az,ak]];if(this.shadow){this.renderer.shadowRenderer.draw(at,av,{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}ao(aA,ak,az,ak,{strokeStyle:ah.borderColor})}an=null}al=null}ah=null;aB=null}at.restore();function ao(aH,aG,aE,ax,aF){at.save();aF=aF||{};if(aF.lineWidth==null||aF.lineWidth!=0){L.extend(true,at,aF);at.beginPath();at.moveTo(aH,aG);at.lineTo(aE,ax);at.stroke();at.restore()}}if(this.shadow){var av=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(at,av)}if(this.borderWidth!=0&&this.drawBorder){ao(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:aw.x2axis.borderColor,lineWidth:aw.x2axis.borderWidth});ao(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:aw.y2axis.borderColor,lineWidth:aw.y2axis.borderWidth});ao(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:aw.xaxis.borderColor,lineWidth:aw.xaxis.borderWidth});ao(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:aw.yaxis.borderColor,lineWidth:aw.yaxis.borderWidth})}at.restore();at=null;aw=null};L.jqplot.DivTitleRenderer=function(){};L.jqplot.DivTitleRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.DivTitleRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}var ak=this.renderer;var aj=document.createElement("div");this._elem=L(aj);this._elem.addClass("jqplot-title");if(!this.text){this.show=false;this._elem.height(0);this._elem.width(0)}else{if(this.text){var ah;if(this.color){ah=this.color}else{if(this.textColor){ah=this.textColor}}var ai={position:"absolute",top:"0px",left:"0px"};if(this._plotWidth){ai.width=this._plotWidth+"px"}if(this.fontSize){ai.fontSize=this.fontSize}if(typeof this.textAlign==="string"){ai.textAlign=this.textAlign}else{ai.textAlign="center"}if(ah){ai.color=ah}if(this.paddingBottom){ai.paddingBottom=this.paddingBottom}if(this.fontFamily){ai.fontFamily=this.fontFamily}this._elem.css(ai);if(this.escapeHtml){this._elem.text(this.text)}else{this._elem.html(this.text)}}}aj=null;return this._elem};L.jqplot.DivTitleRenderer.prototype.pack=function(){};var r=0.1;L.jqplot.LinePattern=function(aw,aq){var ap={dotted:[r,L.jqplot.config.dotGapLength],dashed:[L.jqplot.config.dashLength,L.jqplot.config.gapLength],solid:null};if(typeof aq==="string"){if(aq[0]==="."||aq[0]==="-"){var ax=aq;aq=[];for(var ao=0,al=ax.length;ao<al;ao++){if(ax[ao]==="."){aq.push(r)}else{if(ax[ao]==="-"){aq.push(L.jqplot.config.dashLength)}else{continue}}aq.push(L.jqplot.config.gapLength)}}else{aq=ap[aq]}}if(!(aq&&aq.length)){return aw}var ak=0;var ar=aq[0];var au=0;var at=0;var an=0;var ah=0;var av=function(ay,az){aw.moveTo(ay,az);au=ay;at=az;an=ay;ah=az};var aj=function(ay,aE){var aC=aw.lineWidth;var aA=ay-au;var az=aE-at;var aB=Math.sqrt(aA*aA+az*az);if((aB>0)&&(aC>0)){aA/=aB;az/=aB;while(true){var aD=aC*ar;if(aD<aB){au+=aD*aA;at+=aD*az;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}aB-=aD;ak++;if(ak>=aq.length){ak=0}ar=aq[ak]}else{au=ay;at=aE;if((ak&1)==0){aw.lineTo(au,at)}else{aw.moveTo(au,at)}ar-=aB/aC;break}}}};var ai=function(){aw.beginPath()};var am=function(){aj(an,ah)};return{moveTo:av,lineTo:aj,beginPath:ai,closePath:am}};L.jqplot.LineRenderer=function(){this.shapeRenderer=new L.jqplot.ShapeRenderer();this.shadowRenderer=new L.jqplot.ShadowRenderer()};L.jqplot.LineRenderer.prototype.init=function(ai,an){ai=ai||{};this._type="line";this.renderer.animation={show:false,direction:"left",speed:2500,_supported:true};this.renderer.smooth=false;this.renderer.tension=null;this.renderer.constrainSmoothing=true;this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];this.renderer.bandData=[];this.renderer.bands={show:false,hiData:[],lowData:[],color:this.color,showLines:false,fill:true,fillColor:null,_min:null,_max:null,interval:"3%"};var al={highlightMouseOver:ai.highlightMouseOver,highlightMouseDown:ai.highlightMouseDown,highlightColor:ai.highlightColor};delete (ai.highlightMouseOver);delete (ai.highlightMouseDown);delete (ai.highlightColor);L.extend(true,this.renderer,ai);this.renderer.options=ai;if(this.renderer.bandData.length>1&&(!ai.bands||ai.bands.show==null)){this.renderer.bands.show=true}else{if(ai.bands&&ai.bands.show==null&&ai.bands.interval!=null){this.renderer.bands.show=true}}if(this.fill){this.renderer.bands.show=false}if(this.renderer.bands.show){this.renderer.initBands.call(this,this.renderer.options,an)}if(this._stack){this.renderer.smooth=false}var am={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.fillColor,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shapeRenderer.init(am);var aj=ai.shadowOffset;if(aj==null){if(this.lineWidth>2.5){aj=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{aj=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var ah={lineJoin:this.lineJoin,lineCap:this.lineCap,fill:this.fill,isarc:false,angle:this.shadowAngle,offset:aj,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.lineWidth,linePattern:this.linePattern,closePath:this.fill};this.renderer.shadowRenderer.init(ah);this._areaPoints=[];this._boundingBox=[[],[]];if(!this.isTrendline&&this.fill||this.renderer.bands.show){this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColor=null;if(al.highlightMouseDown&&al.highlightMouseOver==null){al.highlightMouseOver=false}L.extend(true,this,{highlightMouseOver:al.highlightMouseOver,highlightMouseDown:al.highlightMouseDown,highlightColor:al.highlightColor});if(!this.highlightColor){var ak=(this.renderer.bands.show)?this.renderer.bands.fillColor:this.fillColor;this.highlightColor=L.jqplot.computeHighlightColors(ak)}if(this.highlighter){this.highlighter.show=false}}if(!this.isTrendline&&an){an.plugins.lineRenderer={};an.postInitHooks.addOnce(z);an.postDrawHooks.addOnce(af);an.eventListenerHooks.addOnce("jqplotMouseMove",h);an.eventListenerHooks.addOnce("jqplotMouseDown",e);an.eventListenerHooks.addOnce("jqplotMouseUp",ad);an.eventListenerHooks.addOnce("jqplotClick",g);an.eventListenerHooks.addOnce("jqplotRightClick",s)}};L.jqplot.LineRenderer.prototype.initBands=function(ak,av){var al=ak.bandData||[];var an=this.renderer.bands;an.hiData=[];an.lowData=[];var aB=this.data;an._max=null;an._min=null;if(al.length==2){if(L.isArray(al[0][0])){var ao;var ah=0,ar=0;for(var aw=0,at=al[0].length;aw<at;aw++){ao=al[0][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1]}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1]}}for(var aw=0,at=al[1].length;aw<at;aw++){ao=al[1][aw];if((ao[1]!=null&&ao[1]>an._max)||an._max==null){an._max=ao[1];ar=1}if((ao[1]!=null&&ao[1]<an._min)||an._min==null){an._min=ao[1];ah=1}}if(ar===ah){an.show=false}an.hiData=al[ar];an.lowData=al[ah]}else{if(al[0].length===aB.length&&al[1].length===aB.length){var aj=(al[0][0]>al[1][0])?0:1;var aC=(aj)?0:1;for(var aw=0,at=aB.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aj][aw]]);an.lowData.push([aB[aw][0],al[aC][aw]])}}else{an.show=false}}}else{if(al.length>2&&!L.isArray(al[0][0])){var aj=(al[0][0]>al[0][1])?0:1;var aC=(aj)?0:1;for(var aw=0,at=al.length;aw<at;aw++){an.hiData.push([aB[aw][0],al[aw][aj]]);an.lowData.push([aB[aw][0],al[aw][aC]])}}else{var aq=an.interval;var aA=null;var az=null;var ai=null;var au=null;if(L.isArray(aq)){aA=aq[0];az=aq[1]}else{aA=aq}if(isNaN(aA)){if(aA.charAt(aA.length-1)==="%"){ai="multiply";aA=parseFloat(aA)/100+1}}else{aA=parseFloat(aA);ai="add"}if(az!==null&&isNaN(az)){if(az.charAt(az.length-1)==="%"){au="multiply";az=parseFloat(az)/100+1}}else{if(az!==null){az=parseFloat(az);au="add"}}if(aA!==null){if(az===null){az=-aA;au=ai;if(au==="multiply"){az+=2}}if(aA<az){var ax=aA;aA=az;az=ax;ax=ai;ai=au;au=ax}for(var aw=0,at=aB.length;aw<at;aw++){switch(ai){case"add":an.hiData.push([aB[aw][0],aB[aw][1]+aA]);break;case"multiply":an.hiData.push([aB[aw][0],aB[aw][1]*aA]);break}switch(au){case"add":an.lowData.push([aB[aw][0],aB[aw][1]+az]);break;case"multiply":an.lowData.push([aB[aw][0],aB[aw][1]*az]);break}}}else{an.show=false}}}var am=an.hiData;var ap=an.lowData;for(var aw=0,at=am.length;aw<at;aw++){if((am[aw][1]!=null&&am[aw][1]>an._max)||an._max==null){an._max=am[aw][1]}}for(var aw=0,at=ap.length;aw<at;aw++){if((ap[aw][1]!=null&&ap[aw][1]<an._min)||an._min==null){an._min=ap[aw][1]}}if(an.fillColor===null){var ay=L.jqplot.getColorComponents(an.color);ay[3]=ay[3]*0.5;an.fillColor="rgba("+ay[0]+", "+ay[1]+", "+ay[2]+", "+ay[3]+")"}};function K(ai,ah){return(3.4182054+ah)*Math.pow(ai,-0.3534992)}function n(aj,ai){var ah=Math.sqrt(Math.pow((ai[0]-aj[0]),2)+Math.pow((ai[1]-aj[1]),2));return 5.7648*Math.log(ah)+7.4456}function A(ah){var ai=(Math.exp(2*ah)-1)/(Math.exp(2*ah)+1);return ai}function J(aJ){var at=this.renderer.smooth;var aD=this.canvas.getWidth();var an=this._xaxis.series_p2u;var aG=this._yaxis.series_p2u;var aF=null;var am=null;var az=aJ.length/aD;var aj=[];var ay=[];if(!isNaN(parseFloat(at))){aF=parseFloat(at)}else{aF=K(az,0.5)}var aw=[];var ak=[];for(var aE=0,aA=aJ.length;aE<aA;aE++){aw.push(aJ[aE][1]);ak.push(aJ[aE][0])}function av(aK,aL){if(aK-aL==0){return Math.pow(10,10)}else{return aK-aL}}var ax,ar,aq,ap;var ah=aJ.length-1;for(var al=1,aB=aJ.length;al<aB;al++){var ai=[];var au=[];for(var aC=0;aC<2;aC++){var aE=al-1+aC;if(aE==0||aE==ah){ai[aC]=Math.pow(10,10)}else{if(aw[aE+1]-aw[aE]==0||aw[aE]-aw[aE-1]==0){ai[aC]=0}else{if(((ak[aE+1]-ak[aE])/(aw[aE+1]-aw[aE])+(ak[aE]-ak[aE-1])/(aw[aE]-aw[aE-1]))==0){ai[aC]=0}else{if((aw[aE+1]-aw[aE])*(aw[aE]-aw[aE-1])<0){ai[aC]=0}else{ai[aC]=2/(av(ak[aE+1],ak[aE])/(aw[aE+1]-aw[aE])+av(ak[aE],ak[aE-1])/(aw[aE]-aw[aE-1]))}}}}}if(al==1){ai[0]=3/2*(aw[1]-aw[0])/av(ak[1],ak[0])-ai[1]/2}else{if(al==ah){ai[1]=3/2*(aw[ah]-aw[ah-1])/av(ak[ah],ak[ah-1])-ai[0]/2}}au[0]=-2*(ai[1]+2*ai[0])/av(ak[al],ak[al-1])+6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);au[1]=2*(2*ai[1]+ai[0])/av(ak[al],ak[al-1])-6*(aw[al]-aw[al-1])/Math.pow(av(ak[al],ak[al-1]),2);ap=1/6*(au[1]-au[0])/av(ak[al],ak[al-1]);aq=1/2*(ak[al]*au[0]-ak[al-1]*au[1])/av(ak[al],ak[al-1]);ar=(aw[al]-aw[al-1]-aq*(Math.pow(ak[al],2)-Math.pow(ak[al-1],2))-ap*(Math.pow(ak[al],3)-Math.pow(ak[al-1],3)))/av(ak[al],ak[al-1]);ax=aw[al-1]-ar*ak[al-1]-aq*Math.pow(ak[al-1],2)-ap*Math.pow(ak[al-1],3);var aI=(ak[al]-ak[al-1])/aF;var aH,ao;for(var aC=0,aA=aF;aC<aA;aC++){aH=[];ao=ak[al-1]+aC*aI;aH.push(ao);aH.push(ax+ar*ao+aq*Math.pow(ao,2)+ap*Math.pow(ao,3));aj.push(aH);ay.push([an(aH[0]),aG(aH[1])])}}aj.push(aJ[aE]);ay.push([an(aJ[aE][0]),aG(aJ[aE][1])]);return[aj,ay]}function F(ap){var ao=this.renderer.smooth;var aU=this.renderer.tension;var ah=this.canvas.getWidth();var aH=this._xaxis.series_p2u;var aq=this._yaxis.series_p2u;var aI=null;var aJ=null;var aT=null;var aO=null;var aM=null;var at=null;var aR=null;var am=null;var aK,aL,aD,aC,aA,ay;var ak,ai,av,au;var aB,az,aN;var aw=[];var aj=[];var al=ap.length/ah;var aS,ax,aF,aG,aE;var ar=[];var an=[];if(!isNaN(parseFloat(ao))){aI=parseFloat(ao)}else{aI=K(al,0.5)}if(!isNaN(parseFloat(aU))){aU=parseFloat(aU)}for(var aQ=0,aP=ap.length-1;aQ<aP;aQ++){if(aU===null){at=Math.abs((ap[aQ+1][1]-ap[aQ][1])/(ap[aQ+1][0]-ap[aQ][0]));aS=0.3;ax=0.6;aF=(ax-aS)/2;aG=2.5;aE=-1.4;am=at/aG+aE;aO=aF*A(am)-aF*A(aE)+aS;if(aQ>0){aR=Math.abs((ap[aQ][1]-ap[aQ-1][1])/(ap[aQ][0]-ap[aQ-1][0]))}am=aR/aG+aE;aM=aF*A(am)-aF*A(aE)+aS;aT=(aO+aM)/2}else{aT=aU}for(aK=0;aK<aI;aK++){aL=aK/aI;aD=(1+2*aL)*Math.pow((1-aL),2);aC=aL*Math.pow((1-aL),2);aA=Math.pow(aL,2)*(3-2*aL);ay=Math.pow(aL,2)*(aL-1);if(ap[aQ-1]){ak=aT*(ap[aQ+1][0]-ap[aQ-1][0]);ai=aT*(ap[aQ+1][1]-ap[aQ-1][1])}else{ak=aT*(ap[aQ+1][0]-ap[aQ][0]);ai=aT*(ap[aQ+1][1]-ap[aQ][1])}if(ap[aQ+2]){av=aT*(ap[aQ+2][0]-ap[aQ][0]);au=aT*(ap[aQ+2][1]-ap[aQ][1])}else{av=aT*(ap[aQ+1][0]-ap[aQ][0]);au=aT*(ap[aQ+1][1]-ap[aQ][1])}aB=aD*ap[aQ][0]+aA*ap[aQ+1][0]+aC*ak+ay*av;az=aD*ap[aQ][1]+aA*ap[aQ+1][1]+aC*ai+ay*au;aN=[aB,az];ar.push(aN);an.push([aH(aB),aq(az)])}}ar.push(ap[aP]);an.push([aH(ap[aP][0]),aq(ap[aP][1])]);return[ar,an]}L.jqplot.LineRenderer.prototype.setGridData=function(ap){var al=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var am=this._plotData;var aq=this._prevPlotData;this.gridData=[];this._prevGridData=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var ak=this.renderer.bands;var ai=false;for(var an=0,aj=am.length;an<aj;an++){if(am[an][0]!=null&&am[an][1]!=null){this.gridData.push([al.call(this._xaxis,am[an][0]),ah.call(this._yaxis,am[an][1])])}else{if(am[an][0]==null){ai=true;this.gridData.push([null,ah.call(this._yaxis,am[an][1])])}else{if(am[an][1]==null){ai=true;this.gridData.push([al.call(this._xaxis,am[an][0]),null])}}}if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]!=null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]==null){this._prevGridData.push([null,ah.call(this._yaxis,aq[an][1])])}else{if(aq[an]!=null&&aq[an][0]!=null&&aq[an][1]==null){this._prevGridData.push([al.call(this._xaxis,aq[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){ak.show=false}}if(this._type==="line"&&ak.show){for(var an=0,aj=ak.hiData.length;an<aj;an++){this.renderer._hiBandGridData.push([al.call(this._xaxis,ak.hiData[an][0]),ah.call(this._yaxis,ak.hiData[an][1])])}for(var an=0,aj=ak.lowData.length;an<aj;an++){this.renderer._lowBandGridData.push([al.call(this._xaxis,ak.lowData[an][0]),ah.call(this._yaxis,ak.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&this.gridData.length>2){var ao;if(this.renderer.constrainSmoothing){ao=J.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}else{ao=F.call(this,this.gridData);this.renderer._smoothedData=ao[0];this.renderer._smoothedPlotData=ao[1];if(ak.show){ao=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ao[0];ao=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ao[0]}ao=null}}};L.jqplot.LineRenderer.prototype.makeGridData=function(ao,aq){var am=this._xaxis.series_u2p;var ah=this._yaxis.series_u2p;var ar=[];var aj=[];this.renderer._smoothedData=[];this.renderer._smoothedPlotData=[];this.renderer._hiBandGridData=[];this.renderer._lowBandGridData=[];this.renderer._hiBandSmoothedData=[];this.renderer._lowBandSmoothedData=[];var al=this.renderer.bands;var ai=false;for(var an=0;an<ao.length;an++){if(ao[an][0]!=null&&ao[an][1]!=null){ar.push([am.call(this._xaxis,ao[an][0]),ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][0]==null){ai=true;ar.push([null,ah.call(this._yaxis,ao[an][1])])}else{if(ao[an][1]==null){ai=true;ar.push([am.call(this._xaxis,ao[an][0]),null])}}}}if(ai){this.renderer.smooth=false;if(this._type==="line"){al.show=false}}if(this._type==="line"&&al.show){for(var an=0,ak=al.hiData.length;an<ak;an++){this.renderer._hiBandGridData.push([am.call(this._xaxis,al.hiData[an][0]),ah.call(this._yaxis,al.hiData[an][1])])}for(var an=0,ak=al.lowData.length;an<ak;an++){this.renderer._lowBandGridData.push([am.call(this._xaxis,al.lowData[an][0]),ah.call(this._yaxis,al.lowData[an][1])])}}if(this._type==="line"&&this.renderer.smooth&&ar.length>2){var ap;if(this.renderer.constrainSmoothing){ap=J.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=J.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=J.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}else{ap=F.call(this,ar);this.renderer._smoothedData=ap[0];this.renderer._smoothedPlotData=ap[1];if(al.show){ap=F.call(this,this.renderer._hiBandGridData);this.renderer._hiBandSmoothedData=ap[0];ap=F.call(this,this.renderer._lowBandGridData);this.renderer._lowBandSmoothedData=ap[0]}ap=null}}return ar};L.jqplot.LineRenderer.prototype.draw=function(ax,aI,ai,aB){var aC;var aq=L.extend(true,{},ai);var ak=(aq.shadow!=u)?aq.shadow:this.shadow;var aJ=(aq.showLine!=u)?aq.showLine:this.showLine;var aA=(aq.fill!=u)?aq.fill:this.fill;var ah=(aq.fillAndStroke!=u)?aq.fillAndStroke:this.fillAndStroke;var ar,ay,av,aE;ax.save();if(aI.length){if(aJ){if(aA){if(this.fillToZero){var aF=this.negativeColor;if(!this.useNegativeColors){aF=aq.fillStyle}var ao=false;var ap=aq.fillStyle;if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var aw=[];var aL=(this.renderer.smooth)?this.renderer._smoothedPlotData:this._plotData;this._areaPoints=[];var aG=this._yaxis.series_u2p(this.fillToValue);var aj=this._xaxis.series_u2p(this.fillToValue);aq.closePath=true;if(this.fillAxis=="y"){aw.push([aI[0][0],aG]);this._areaPoints.push([aI[0][0],aG]);for(var aC=0;aC<aI.length-1;aC++){aw.push(aI[aC]);this._areaPoints.push(aI[aC]);if(aL[aC][1]*aL[aC+1][1]<=0){if(aL[aC][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}var an=aI[aC][0]+(aI[aC+1][0]-aI[aC][0])*(aG-aI[aC][1])/(aI[aC+1][1]-aI[aC][1]);aw.push([an,aG]);this._areaPoints.push([an,aG]);if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq);aw=[[an,aG]]}}if(aL[aI.length-1][1]<0){ao=true;aq.fillStyle=aF}else{ao=false;aq.fillStyle=ap}aw.push(aI[aI.length-1]);this._areaPoints.push(aI[aI.length-1]);aw.push([aI[aI.length-1][0],aG]);this._areaPoints.push([aI[aI.length-1][0],aG])}if(ak){this.renderer.shadowRenderer.draw(ax,aw,aq)}this.renderer.shapeRenderer.draw(ax,aw,aq)}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this._areaPoints=aI;this.renderer.shapeRenderer.draw(ax,aI,aq)}}else{if(ah){var aH=aI.slice(0)}if(this.index==0||!this._stack){var al=ax.canvas.height;aI.unshift([aI[0][0],al]);var aD=aI.length;aI.push([aI[aD-1][0],al])}else{var au=this._prevGridData;for(var aC=au.length;aC>0;aC--){aI.push(au[aC-1])}}this._areaPoints=aI;if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}if(ah){var az=L.extend(true,{},aq,{fill:false,closePath:false});this.renderer.shapeRenderer.draw(ax,aH,az);if(this.markerRenderer.show){if(this.renderer.smooth){aH=this.gridData}for(aC=0;aC<aH.length;aC++){this.markerRenderer.draw(aH[aC][0],aH[aC][1],ax,aq.markerOptions)}}}}else{if(this.renderer.bands.show){var am;var aK=L.extend(true,{},aq);if(this.renderer.bands.showLines){am=(this.renderer.smooth)?this.renderer._hiBandSmoothedData:this.renderer._hiBandGridData;this.renderer.shapeRenderer.draw(ax,am,aq);am=(this.renderer.smooth)?this.renderer._lowBandSmoothedData:this.renderer._lowBandGridData;this.renderer.shapeRenderer.draw(ax,am,aK)}if(this.renderer.bands.fill){if(this.renderer.smooth){am=this.renderer._hiBandSmoothedData.concat(this.renderer._lowBandSmoothedData.reverse())}else{am=this.renderer._hiBandGridData.concat(this.renderer._lowBandGridData.reverse())}this._areaPoints=am;aK.closePath=true;aK.fill=true;aK.fillStyle=this.renderer.bands.fillColor;this.renderer.shapeRenderer.draw(ax,am,aK)}}if(ak){this.renderer.shadowRenderer.draw(ax,aI,aq)}this.renderer.shapeRenderer.draw(ax,aI,aq)}}var ar=av=ay=aE=null;for(aC=0;aC<this._areaPoints.length;aC++){var at=this._areaPoints[aC];if(ar>at[0]||ar==null){ar=at[0]}if(aE<at[1]||aE==null){aE=at[1]}if(av<at[0]||av==null){av=at[0]}if(ay>at[1]||ay==null){ay=at[1]}}if(this.type==="line"&&this.renderer.bands.show){aE=this._yaxis.series_u2p(this.renderer.bands._min);ay=this._yaxis.series_u2p(this.renderer.bands._max)}this._boundingBox=[[ar,aE],[av,ay]];if(this.markerRenderer.show&&!aA){if(this.renderer.smooth){aI=this.gridData}for(aC=0;aC<aI.length;aC++){if(aI[aC][0]!=null&&aI[aC][1]!=null){this.markerRenderer.draw(aI[aC][0],aI[aC][1],ax,aq.markerOptions)}}}}ax.restore()};L.jqplot.LineRenderer.prototype.drawShadow=function(ah,aj,ai){};function z(ak,aj,ah){for(var ai=0;ai<this.series.length;ai++){if(this.series[ai].renderer.constructor==L.jqplot.LineRenderer){if(this.series[ai].highlightMouseOver){this.series[ai].highlightMouseDown=false}}}}function af(){if(this.plugins.lineRenderer&&this.plugins.lineRenderer.highlightCanvas){this.plugins.lineRenderer.highlightCanvas.resetCanvas();this.plugins.lineRenderer.highlightCanvas=null}this.plugins.lineRenderer.highlightedSeriesIndex=null;this.plugins.lineRenderer.highlightCanvas=new L.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-lineRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.lineRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(ah){aa(ah.data.plot)})}function ac(an,am,ak,aj){var ai=an.series[am];var ah=an.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);ai._highlightedPoint=ak;an.plugins.lineRenderer.highlightedSeriesIndex=am;var al={fillStyle:ai.highlightColor};if(ai.type==="line"&&ai.renderer.bands.show){al.fill=true;al.closePath=true}ai.renderer.shapeRenderer.draw(ah._ctx,aj,al);ah=null}function aa(aj){var ah=aj.plugins.lineRenderer.highlightCanvas;ah._ctx.clearRect(0,0,ah._ctx.canvas.width,ah._ctx.canvas.height);for(var ai=0;ai<aj.series.length;ai++){aj.series[ai]._highlightedPoint=null}aj.plugins.lineRenderer.highlightedSeriesIndex=null;aj.target.trigger("jqplotDataUnhighlight");ah=null}function h(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ai=jQuery.Event("jqplotDataMouseOver");ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj);if(am.series[aj[0]].highlightMouseOver&&!(aj[0]==am.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=al.which;ah.pageX=al.pageX;ah.pageY=al.pageY;am.target.trigger(ah,aj);ac(am,an.seriesIndex,an.pointIndex,an.points)}}else{if(an==null){aa(am)}}}function e(ak,aj,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];if(al.series[ai[0]].highlightMouseDown&&!(ai[0]==al.plugins.lineRenderer.highlightedSeriesIndex)){var ah=jQuery.Event("jqplotDataHighlight");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai);ac(al,am.seriesIndex,am.pointIndex,am.points)}}else{if(am==null){aa(al)}}}function ad(aj,ai,am,al,ak){var ah=ak.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&ak.series[ah].highlightMouseDown){aa(ak)}}function g(ak,aj,an,am,al){if(am){var ai=[am.seriesIndex,am.pointIndex,am.data];var ah=jQuery.Event("jqplotDataClick");ah.which=ak.which;ah.pageX=ak.pageX;ah.pageY=ak.pageY;al.target.trigger(ah,ai)}}function s(al,ak,ao,an,am){if(an){var aj=[an.seriesIndex,an.pointIndex,an.data];var ah=am.plugins.lineRenderer.highlightedSeriesIndex;if(ah!=null&&am.series[ah].highlightMouseDown){aa(am)}var ai=jQuery.Event("jqplotDataRightClick");ai.which=al.which;ai.pageX=al.pageX;ai.pageY=al.pageY;am.target.trigger(ai,aj)}}L.jqplot.LinearAxisRenderer=function(){};L.jqplot.LinearAxisRenderer.prototype.init=function(ah){this.breakPoints=null;this.breakTickLabel="≈";this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.forceTickAt0=false;this.forceTickAt100=false;this.tickInset=0;this.minorTicks=0;this.alignTicks=false;this._autoFormatString="";this._overrideFormatString=false;this._scalefact=1;L.extend(true,this,ah);if(this.breakPoints){if(!L.isArray(this.breakPoints)){this.breakPoints=null}else{if(this.breakPoints.length<2||this.breakPoints[1]<=this.breakPoints[0]){this.breakPoints=null}}}if(this.numberTicks!=null&&this.numberTicks<2){this.numberTicks=2}this.resetDataBounds()};L.jqplot.LinearAxisRenderer.prototype.draw=function(ah,ao){if(this.show){this.renderer.createTicks.call(this,ao);var an=0;var ai;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=L(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var am=this._label.draw(ah,ao);am.appendTo(this._elem);am=null}var al=this._ticks;var ak;for(var aj=0;aj<al.length;aj++){ak=al[aj];if(ak.show&&ak.showLabel&&(!ak.isMinorTick||this.showMinorTicks)){this._elem.append(ak.draw(ah,ao))}}ak=null;al=null}return this._elem};L.jqplot.LinearAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}};L.jqplot.LinearAxisRenderer.prototype.set=function(){var ao=0;var aj;var ai=0;var an=0;var ah=(this._label==null)?false:this._label.show;if(this.show){var am=this._ticks;var al;for(var ak=0;ak<am.length;ak++){al=am[ak];if(!al._breakTick&&al.show&&al.showLabel&&(!al.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){aj=al._elem.outerHeight(true)}else{aj=al._elem.outerWidth(true)}if(aj>ao){ao=aj}}}al=null;am=null;if(ah){ai=this._label._elem.outerWidth(true);an=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){ao=ao+an;this._elem.css({height:ao+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){ao=ao+ai;this._elem.css({width:ao+"px",left:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}else{ao=ao+ai;this._elem.css({width:ao+"px",right:"0px",top:"0px"});if(ah&&this._label.constructor==L.jqplot.AxisLabelRenderer){this._label._elem.css("width",ai+"px")}}}}}};L.jqplot.LinearAxisRenderer.prototype.createTicks=function(aj){var aT=this._ticks;var aK=this.ticks;var az=this.name;var aB=this._dataBounds;var ah=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var an;var a6,aI;var ap,ao;var a4,a0;var aH=this.min;var a5=this.max;var aW=this.numberTicks;var ba=this.tickInterval;var am=30;this._scalefact=(Math.max(ah,am+1)-am)/300;if(aK.length){for(a0=0;a0<aK.length;a0++){var aO=aK[a0];var aU=new this.tickRenderer(this.tickOptions);if(L.isArray(aO)){aU.value=aO[0];if(this.breakPoints){if(aO[0]==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO[0]>this.breakPoints[0]&&aO[0]<=this.breakPoints[1]){aU.show=false;aU.showGridline=false;aU.label=aO[1]}else{aU.label=aO[1]}}}else{aU.label=aO[1]}aU.setTick(aO[0],this.name);this._ticks.push(aU)}else{if(L.isPlainObject(aO)){L.extend(true,aU,aO);aU.axis=this.name;this._ticks.push(aU)}else{aU.value=aO;if(this.breakPoints){if(aO==this.breakPoints[0]){aU.label=this.breakTickLabel;aU._breakTick=true;aU.showGridline=false;aU.showMark=false}else{if(aO>this.breakPoints[0]&&aO<=this.breakPoints[1]){aU.show=false;aU.showGridline=false}}}aU.setTick(aO,this.name);this._ticks.push(aU)}}}this.numberTicks=aK.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(az=="xaxis"||az=="x2axis"){ah=this._plotDimensions.width}else{ah=this._plotDimensions.height}var ax=this.numberTicks;if(this.alignTicks){if(this.name==="x2axis"&&aj.axes.xaxis.show){ax=aj.axes.xaxis.numberTicks}else{if(this.name.charAt(0)==="y"&&this.name!=="yaxis"&&this.name!=="yMidAxis"&&aj.axes.yaxis.show){ax=aj.axes.yaxis.numberTicks}}}a6=((this.min!=null)?this.min:aB.min);aI=((this.max!=null)?this.max:aB.max);var av=aI-a6;var aS,ay;var at;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(this.min==null||this.max==null&&this.tickInterval==null&&!this.autoscale){if(this.forceTickAt0){if(a6>0){a6=0}if(aI<0){aI=0}}if(this.forceTickAt100){if(a6>100){a6=100}if(aI<100){aI=100}}var aE=false,a1=false;if(this.min!=null){aE=true}else{if(this.max!=null){a1=true}}var aP=L.jqplot.LinearTickGenerator(a6,aI,this._scalefact,ax,aE,a1);var aw=(this.min!=null)?a6:a6+av*(this.padMin-1);var aQ=(this.max!=null)?aI:aI-av*(this.padMax-1);if(a6<aw||aI>aQ){aw=(this.min!=null)?a6:a6-av*(this.padMin-1);aQ=(this.max!=null)?aI:aI+av*(this.padMax-1);aP=L.jqplot.LinearTickGenerator(aw,aQ,this._scalefact,ax,aE,a1)}this.min=aP[0];this.max=aP[1];this.numberTicks=aP[2];this._autoFormatString=aP[3];this.tickInterval=aP[4]}else{if(a6==aI){var ai=0.05;if(a6>0){ai=Math.max(Math.log(a6)/Math.LN10,0.05)}a6-=ai;aI+=ai}if(this.autoscale&&this.min==null&&this.max==null){var ak,al,ar;var aC=false;var aN=false;var aA={min:null,max:null,average:null,stddev:null};for(var a0=0;a0<this._series.length;a0++){var aV=this._series[a0];var aD=(aV.fillAxis=="x")?aV._xaxis.name:aV._yaxis.name;if(this.name==aD){var aR=aV._plotValues[aV.fillAxis];var aG=aR[0];var a2=aR[0];for(var aZ=1;aZ<aR.length;aZ++){if(aR[aZ]<aG){aG=aR[aZ]}else{if(aR[aZ]>a2){a2=aR[aZ]}}}var au=(a2-aG)/a2;if(aV.renderer.constructor==L.jqplot.BarRenderer){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{aC=false;if(aV.fill&&aV.fillToZero&&aG<0&&a2>0){aN=true}else{aN=false}}}else{if(aV.fill){if(aG>=0&&(aV.fillToZero||au>0.1)){aC=true}else{if(aG<0&&a2>0&&aV.fillToZero){aC=false;aN=true}else{aC=false;aN=false}}}else{if(aG<0){aC=false}}}}}if(aC){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);this.min=0;aH=0;al=aI/(this.numberTicks-1);at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));if(al/at==parseInt(al/at,10)){al+=at}this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*(this.numberTicks-1)}else{if(aN){this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing);var aJ=Math.ceil(Math.abs(a6)/av*(this.numberTicks-1));var a9=this.numberTicks-1-aJ;al=Math.max(Math.abs(a6/aJ),Math.abs(aI/a9));at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)));this.tickInterval=Math.ceil(al/at)*at;this.max=this.tickInterval*a9;this.min=-this.tickInterval*aJ}else{if(this.numberTicks==null){if(this.tickInterval){this.numberTicks=3+Math.ceil(av/this.tickInterval)}else{this.numberTicks=2+Math.ceil((ah-(this.tickSpacing-1))/this.tickSpacing)}}if(this.tickInterval==null){al=av/(this.numberTicks-1);if(al<1){at=Math.pow(10,Math.abs(Math.floor(Math.log(al)/Math.LN10)))}else{at=1}this.tickInterval=Math.ceil(al*at*this.pad)/at}else{at=1/this.tickInterval}ak=this.tickInterval*(this.numberTicks-1);ar=(ak-av)/2;if(this.min==null){this.min=Math.floor(at*(a6-ar))/at}if(this.max==null){this.max=this.min+ak}}}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM}else{aS=(this.min!=null)?this.min:a6-av*(this.padMin-1);ay=(this.max!=null)?this.max:aI+av*(this.padMax-1);av=ay-aS;if(this.numberTicks==null){if(this.tickInterval!=null){this.numberTicks=Math.ceil((ay-aS)/this.tickInterval)+1}else{if(ah>100){this.numberTicks=parseInt(3+(ah-100)/75,10)}else{this.numberTicks=2}}}if(this.tickInterval==null){this.tickInterval=av/(this.numberTicks-1)}if(this.max==null){ay=aS+this.tickInterval*(this.numberTicks-1)}if(this.min==null){aS=ay-this.tickInterval*(this.numberTicks-1)}var aF=L.jqplot.getSignificantFigures(this.tickInterval);var aM;if(aF.digitsLeft>=aF.significantDigits){aM="%d"}else{var at=Math.max(0,5-aF.digitsLeft);at=Math.min(at,aF.digitsRight);aM="%."+at+"f"}this._autoFormatString=aM;this.min=aS;this.max=ay}if(this.renderer.constructor==L.jqplot.LinearAxisRenderer&&this._autoFormatString==""){av=this.max-this.min;var a7=new this.tickRenderer(this.tickOptions);var aL=a7.formatString||L.jqplot.config.defaultTickFormatString;var aL=aL.match(L.jqplot.sprintf.regex)[0];var a3=0;if(aL){if(aL.search(/[fFeEgGpP]/)>-1){var aY=aL.match(/\%\.(\d{0,})?[eEfFgGpP]/);if(aY){a3=parseInt(aY[1],10)}else{a3=6}}else{if(aL.search(/[di]/)>-1){a3=0}}var aq=Math.pow(10,-a3);if(this.tickInterval<aq){if(aW==null&&ba==null){this.tickInterval=aq;if(a5==null&&aH==null){this.min=Math.floor(this._dataBounds.min/aq)*aq;if(this.min==this._dataBounds.min){this.min=this._dataBounds.min-this.tickInterval}this.max=Math.ceil(this._dataBounds.max/aq)*aq;if(this.max==this._dataBounds.max){this.max=this._dataBounds.max+this.tickInterval}var aX=(this.max-this.min)/this.tickInterval;aX=aX.toFixed(11);aX=Math.ceil(aX);this.numberTicks=aX+1}else{if(a5==null){var aX=(this._dataBounds.max-this.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.max=this.min+this.tickInterval*(this.numberTicks-1)}else{if(aH==null){var aX=(this.max-this._dataBounds.min)/this.tickInterval;aX=aX.toFixed(11);this.numberTicks=Math.ceil(aX)+2;this.min=this.max-this.tickInterval*(this.numberTicks-1)}else{this.numberTicks=Math.ceil((a5-aH)/this.tickInterval)+1;this.min=Math.floor(aH*Math.pow(10,a3))/Math.pow(10,a3);this.max=Math.ceil(a5*Math.pow(10,a3))/Math.pow(10,a3);this.numberTicks=Math.ceil((this.max-this.min)/this.tickInterval)+1}}}}}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var aU,a8;for(var a0=0;a0<this.numberTicks;a0++){a4=this.min+a0*this.tickInterval;aU=new this.tickRenderer(this.tickOptions);aU.setTick(a4,this.name);this._ticks.push(aU);if(a0<this.numberTicks-1){for(var aZ=0;aZ<this.minorTicks;aZ++){a4+=this.tickInterval/(this.minorTicks+1);a8=L.extend(true,{},this.tickOptions,{name:this.name,value:a4,label:"",isMinorTick:true});aU=new this.tickRenderer(a8);this._ticks.push(aU)}}aU=null}}if(this.tickInset){this.min=this.min-this.tickInset*this.tickInterval;this.max=this.max+this.tickInset*this.tickInterval}aT=null};L.jqplot.LinearAxisRenderer.prototype.resetTickValues=function(aj){if(L.isArray(aj)&&aj.length==this._ticks.length){var ai;for(var ah=0;ah<aj.length;ah++){ai=this._ticks[ah];ai.value=aj[ah];ai.label=ai.formatter(ai.formatString,aj[ah]);ai.label=ai.prefix+ai.label;ai._elem.html(ai.label)}ai=null;this.min=L.jqplot.arrayMin(aj);this.max=L.jqplot.arrayMax(aj);this.pack()}};L.jqplot.LinearAxisRenderer.prototype.pack=function(aj,ai){aj=aj||{};ai=ai||this._offsets;var ay=this._ticks;var au=this.max;var at=this.min;var ao=ai.max;var am=ai.min;var aq=(this._label==null)?false:this._label.show;for(var ar in aj){this._elem.css(ar,aj[ar])}this._offsets=ai;var ak=ao-am;var al=au-at;if(this.breakPoints){al=al-this.breakPoints[1]+this.breakPoints[0];this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al+am}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al+am}};if(this.name.charAt(0)=="x"){this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA<=this.breakPoints[0]){return(aA-at)*ak/al}else{return(aA-this.breakPoints[1]+this.breakPoints[0]-at)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){if(aA>this.breakPoints[0]&&aA<this.breakPoints[1]){aA=this.breakPoints[0]}if(aA>=this.breakPoints[1]){return(aA-au)*ak/al}else{return(aA+this.breakPoints[1]-this.breakPoints[0]-au)*ak/al}};this.series_p2u=function(aA){return aA*al/ak+au}}}else{this.p2u=function(aA){return(aA-am)*al/ak+at};this.u2p=function(aA){return(aA-at)*ak/al+am};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(aA){return(aA-at)*ak/al};this.series_p2u=function(aA){return aA*al/ak+at}}else{this.series_u2p=function(aA){return(aA-au)*ak/al};this.series_p2u=function(aA){return aA*al/ak+au}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="xaxis")?1:-1;switch(ap.labelPosition){case"auto":if(ax*ap.angle<0){ah=-ap.getWidth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2}else{ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2}break;case"end":ah=-ap.getWidth()+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;case"start":ah=-ap._textRenderer.height*Math.sin(ap._textRenderer.angle)/2;break;case"middle":ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break;default:ah=-ap.getWidth()/2+ap._textRenderer.height*Math.sin(-ap._textRenderer.angle)/2;break}}else{ah=-ap.getWidth()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("left",az);ap.pack()}}if(aq){var an=this._label._elem.outerWidth(true);this._label._elem.css("left",am+ak/2-an/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var av=0;av<ay.length;av++){var ap=ay[av];if(ap.show&&ap.showLabel){var ah;if(ap.constructor==L.jqplot.CanvasAxisTickRenderer&&ap.angle){var ax=(this.name=="yaxis")?1:-1;switch(ap.labelPosition){case"auto":case"end":if(ax*ap.angle<0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"start":if(ap.angle>0){ah=-ap._textRenderer.height*Math.cos(-ap._textRenderer.angle)/2}else{ah=-ap.getHeight()+ap._textRenderer.height*Math.cos(ap._textRenderer.angle)/2}break;case"middle":ah=-ap.getHeight()/2;break;default:ah=-ap.getHeight()/2;break}}else{ah=-ap.getHeight()/2}var az=this.u2p(ap.value)+ah+"px";ap._elem.css("top",az);ap.pack()}}if(aq){var aw=this._label._elem.outerHeight(true);this._label._elem.css("top",ao-ak/2-aw/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}ay=null};function i(ai){var ah;ai=Math.abs(ai);if(ai>=10){ah="%d"}else{if(ai>1){if(ai===parseInt(ai,10)){ah="%d"}else{ah="%.1f"}}else{var aj=-Math.floor(Math.log(ai)/Math.LN10);ah="%."+aj+"f"}}return ah}var b=[0.1,0.2,0.3,0.4,0.5,0.8,1,2,3,4,5];var c=function(ai){var ah=b.indexOf(ai);if(ah>0){return b[ah-1]}else{return b[b.length-1]/100}};var k=function(ai){var ah=b.indexOf(ai);if(ah<b.length-1){return b[ah+1]}else{return b[0]*100}};function d(al,au,at){var aq=Math.floor(at/2);var ai=Math.ceil(at*1.5);var ak=Number.MAX_VALUE;var ah=(au-al);var ax;var ap;var ar;var ay=L.jqplot.getSignificantFigures;var aw;var an;var ao;var av;for(var am=0,aj=ai-aq+1;am<aj;am++){ao=aq+am;ax=ah/(ao-1);ap=ay(ax);ax=Math.abs(at-ao)+ap.digitsRight;if(ax<ak){ak=ax;ar=ao;av=ap.digitsRight}else{if(ax===ak){if(ap.digitsRight<av){ar=ao;av=ap.digitsRight}}}}aw=Math.max(av,Math.max(ay(al).digitsRight,ay(au).digitsRight));if(aw===0){an="%d"}else{an="%."+aw+"f"}ax=ah/(ar-1);return[al,au,ar,an,ax]}function W(ai,al){al=al||7;var ak=ai/(al-1);var aj=Math.pow(10,Math.floor(Math.log(ak)/Math.LN10));var am=ak/aj;var ah;if(aj<1){if(am>5){ah=10*aj}else{if(am>2){ah=5*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}else{if(am>5){ah=10*aj}else{if(am>4){ah=5*aj}else{if(am>3){ah=4*aj}else{if(am>2){ah=3*aj}else{if(am>1){ah=2*aj}else{ah=aj}}}}}}return ah}function Q(ai,ah){ah=ah||1;var ak=Math.floor(Math.log(ai)/Math.LN10);var am=Math.pow(10,ak);var al=ai/am;var aj;al=al/ah;if(al<=0.38){aj=0.1}else{if(al<=1.6){aj=0.2}else{if(al<=4){aj=0.5}else{if(al<=8){aj=1}else{if(al<=16){aj=2}else{aj=5}}}}}return aj*am}function x(aj,ai){var al=Math.floor(Math.log(aj)/Math.LN10);var an=Math.pow(10,al);var am=aj/an;var ah;var ak;am=am/ai;if(am<=0.38){ak=0.1}else{if(am<=1.6){ak=0.2}else{if(am<=4){ak=0.5}else{if(am<=8){ak=1}else{if(am<=16){ak=2}else{ak=5}}}}}ah=ak*an;return[ah,ak,an]}L.jqplot.LinearTickGenerator=function(an,aq,aj,ak,ao,ar){ao=(ao===null)?false:ao;ar=(ar===null||ao)?false:ar;if(an===aq){aq=(aq)?0:1}aj=aj||1;if(aq<an){var at=aq;aq=an;an=at}var ai=[];var aw=Q(aq-an,aj);var av=L.jqplot.getSignificantFigures;if(ak==null){if(!ao&&!ar){ai[0]=Math.floor(an/aw)*aw;ai[1]=Math.ceil(aq/aw)*aw;ai[2]=Math.round((ai[1]-ai[0])/aw+1);ai[3]=i(aw);ai[4]=aw}else{if(ao){ai[0]=an;ai[2]=Math.ceil((aq-an)/aw+1);ai[1]=an+(ai[2]-1)*aw;var au=av(an).digitsRight;var ap=av(aw).digitsRight;if(au<ap){ai[3]=i(aw)}else{ai[3]="%."+au+"f"}ai[4]=aw}else{if(ar){ai[1]=aq;ai[2]=Math.ceil((aq-an)/aw+1);ai[0]=aq-(ai[2]-1)*aw;var al=av(aq).digitsRight;var ap=av(aw).digitsRight;if(al<ap){ai[3]=i(aw)}else{ai[3]="%."+al+"f"}ai[4]=aw}}}}else{var am=[];am[0]=Math.floor(an/aw)*aw;am[1]=Math.ceil(aq/aw)*aw;am[2]=Math.round((am[1]-am[0])/aw+1);am[3]=i(aw);am[4]=aw;if(am[2]===ak){ai=am}else{var ah=W(am[1]-am[0],ak);ai[0]=am[0];ai[2]=ak;ai[4]=ah;ai[3]=i(ah);ai[1]=ai[0]+(ai[2]-1)*ai[4]}}return ai};L.jqplot.LinearTickGenerator.bestLinearInterval=Q;L.jqplot.LinearTickGenerator.bestInterval=W;L.jqplot.LinearTickGenerator.bestLinearComponents=x;L.jqplot.LinearTickGenerator.bestConstrainedInterval=d;L.jqplot.MarkerRenderer=function(ah){this.show=true;this.style="filledCircle";this.lineWidth=2;this.size=9;this.color="#666666";this.shadow=true;this.shadowAngle=45;this.shadowOffset=1;this.shadowDepth=3;this.shadowAlpha="0.07";this.shadowRenderer=new L.jqplot.ShadowRenderer();this.shapeRenderer=new L.jqplot.ShapeRenderer();L.extend(true,this,ah)};L.jqplot.MarkerRenderer.prototype.init=function(ah){L.extend(true,this,ah);var aj={angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,lineWidth:this.lineWidth,depth:this.shadowDepth,closePath:true};if(this.style.indexOf("filled")!=-1){aj.fill=true}if(this.style.indexOf("ircle")!=-1){aj.isarc=true;aj.closePath=false}this.shadowRenderer.init(aj);var ai={fill:false,isarc:false,strokeStyle:this.color,fillStyle:this.color,lineWidth:this.lineWidth,closePath:true};if(this.style.indexOf("filled")!=-1){ai.fill=true}if(this.style.indexOf("ircle")!=-1){ai.isarc=true;ai.closePath=false}this.shapeRenderer.init(ai)};L.jqplot.MarkerRenderer.prototype.drawDiamond=function(aj,ai,am,al,ao){var ah=1.2;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj,ai+an],[aj+ap,ai],[aj,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawPlus=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ap=[[ak,aj-ao],[ak,aj+ao]];var al=[[ak+ar,aj],[ak-ar,aj]];var ah=L.extend(true,{},this.options,{closePath:false});if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawX=function(ak,aj,an,am,aq){var ai=1;var ar=this.size/2*ai;var ao=this.size/2*ai;var ah=L.extend(true,{},this.options,{closePath:false});var ap=[[ak-ar,aj-ao],[ak+ar,aj+ao]];var al=[[ak-ar,aj+ao],[ak+ar,aj-ao]];if(this.shadow){this.shadowRenderer.draw(an,ap,{closePath:false});this.shadowRenderer.draw(an,al,{closePath:false})}this.shapeRenderer.draw(an,ap,ah);this.shapeRenderer.draw(an,al,ah)};L.jqplot.MarkerRenderer.prototype.drawDash=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2*ah;var an=this.size/2*ah;var ak=[[aj-ap,ai],[aj+ap,ai]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawLine=function(am,al,ah,ak,ai){var aj=[am,al];if(this.shadow){this.shadowRenderer.draw(ah,aj)}this.shapeRenderer.draw(ah,aj,ai)};L.jqplot.MarkerRenderer.prototype.drawSquare=function(aj,ai,am,al,ao){var ah=1;var ap=this.size/2/ah;var an=this.size/2*ah;var ak=[[aj-ap,ai-an],[aj-ap,ai+an],[aj+ap,ai+an],[aj+ap,ai-an]];if(this.shadow){this.shadowRenderer.draw(am,ak)}this.shapeRenderer.draw(am,ak,ao)};L.jqplot.MarkerRenderer.prototype.drawCircle=function(ai,ao,ak,an,al){var ah=this.size/2;var aj=2*Math.PI;var am=[ai,ao,ah,0,aj,true];if(this.shadow){this.shadowRenderer.draw(ak,am)}this.shapeRenderer.draw(ak,am,al)};L.jqplot.MarkerRenderer.prototype.draw=function(ah,ak,ai,aj){aj=aj||{};if(aj.show==null||aj.show!=false){if(aj.color&&!aj.fillStyle){aj.fillStyle=aj.color}if(aj.color&&!aj.strokeStyle){aj.strokeStyle=aj.color}switch(this.style){case"diamond":this.drawDiamond(ah,ak,ai,false,aj);break;case"filledDiamond":this.drawDiamond(ah,ak,ai,true,aj);break;case"circle":this.drawCircle(ah,ak,ai,false,aj);break;case"filledCircle":this.drawCircle(ah,ak,ai,true,aj);break;case"square":this.drawSquare(ah,ak,ai,false,aj);break;case"filledSquare":this.drawSquare(ah,ak,ai,true,aj);break;case"x":this.drawX(ah,ak,ai,true,aj);break;case"plus":this.drawPlus(ah,ak,ai,true,aj);break;case"dash":this.drawDash(ah,ak,ai,true,aj);break;case"line":this.drawLine(ah,ak,ai,false,aj);break;default:this.drawDiamond(ah,ak,ai,false,aj);break}}};L.jqplot.ShadowRenderer=function(ah){this.angle=45;this.offset=1;this.alpha=0.07;this.lineWidth=1.5;this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.depth=3;this.strokeStyle="rgba(0,0,0,0.1)";this.isarc=false;L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShadowRenderer.prototype.draw=function(av,at,ax){av.save();var ah=(ax!=null)?ax:{};var au=(ah.fill!=null)?ah.fill:this.fill;var ap=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ao=(ah.closePath!=null)?ah.closePath:this.closePath;var al=(ah.offset!=null)?ah.offset:this.offset;var aj=(ah.alpha!=null)?ah.alpha:this.alpha;var an=(ah.depth!=null)?ah.depth:this.depth;var aw=(ah.isarc!=null)?ah.isarc:this.isarc;var aq=(ah.linePattern!=null)?ah.linePattern:this.linePattern;av.lineWidth=(ah.lineWidth!=null)?ah.lineWidth:this.lineWidth;av.lineJoin=(ah.lineJoin!=null)?ah.lineJoin:this.lineJoin;av.lineCap=(ah.lineCap!=null)?ah.lineCap:this.lineCap;av.strokeStyle=ah.strokeStyle||this.strokeStyle||"rgba(0,0,0,"+aj+")";av.fillStyle=ah.fillStyle||this.fillStyle||"rgba(0,0,0,"+aj+")";for(var ak=0;ak<an;ak++){var ar=L.jqplot.LinePattern(av,aq);av.translate(Math.cos(this.angle*Math.PI/180)*al,Math.sin(this.angle*Math.PI/180)*al);ar.beginPath();if(aw){av.arc(at[0],at[1],at[2],at[3],at[4],true)}else{if(ap){if(ap){av.fillRect(at[0],at[1],at[2],at[3])}}else{if(at&&at.length){var ai=true;for(var am=0;am<at.length;am++){if(at[am][0]!=null&&at[am][1]!=null){if(ai){ar.moveTo(at[am][0],at[am][1]);ai=false}else{ar.lineTo(at[am][0],at[am][1])}}else{ai=true}}}}}if(ao){ar.closePath()}if(au){av.fill()}else{av.stroke()}}av.restore()};L.jqplot.ShapeRenderer=function(ah){this.lineWidth=1.5;this.linePattern="solid";this.lineJoin="miter";this.lineCap="round";this.closePath=false;this.fill=false;this.isarc=false;this.fillRect=false;this.strokeRect=false;this.clearRect=false;this.strokeStyle="#999999";this.fillStyle="#999999";L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.ShapeRenderer.prototype.draw=function(at,aq,av){at.save();var ah=(av!=null)?av:{};var ar=(ah.fill!=null)?ah.fill:this.fill;var am=(ah.closePath!=null)?ah.closePath:this.closePath;var an=(ah.fillRect!=null)?ah.fillRect:this.fillRect;var ak=(ah.strokeRect!=null)?ah.strokeRect:this.strokeRect;var ai=(ah.clearRect!=null)?ah.clearRect:this.clearRect;var au=(ah.isarc!=null)?ah.isarc:this.isarc;var ao=(ah.linePattern!=null)?ah.linePattern:this.linePattern;var ap=L.jqplot.LinePattern(at,ao);at.lineWidth=ah.lineWidth||this.lineWidth;at.lineJoin=ah.lineJoin||this.lineJoin;at.lineCap=ah.lineCap||this.lineCap;at.strokeStyle=(ah.strokeStyle||ah.color)||this.strokeStyle;at.fillStyle=ah.fillStyle||this.fillStyle;at.beginPath();if(au){at.arc(aq[0],aq[1],aq[2],aq[3],aq[4],true);if(am){at.closePath()}if(ar){at.fill()}else{at.stroke()}at.restore();return}else{if(ai){at.clearRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}else{if(an||ak){if(an){at.fillRect(aq[0],aq[1],aq[2],aq[3])}if(ak){at.strokeRect(aq[0],aq[1],aq[2],aq[3]);at.restore();return}}else{if(aq&&aq.length){var aj=true;for(var al=0;al<aq.length;al++){if(aq[al][0]!=null&&aq[al][1]!=null){if(aj){ap.moveTo(aq[al][0],aq[al][1]);aj=false}else{ap.lineTo(aq[al][0],aq[al][1])}}else{aj=true}}if(am){ap.closePath()}if(ar){at.fill()}else{at.stroke()}}}}}at.restore()};L.jqplot.TableLegendRenderer=function(){};L.jqplot.TableLegendRenderer.prototype.init=function(ah){L.extend(true,this,ah)};L.jqplot.TableLegendRenderer.prototype.addrow=function(aq,ak,ah,ao){var al=(ah)?this.rowSpacing+"px":"0px";var ap;var aj;var ai;var an;var am;ai=document.createElement("tr");ap=L(ai);ap.addClass("jqplot-table-legend");ai=null;if(ao){ap.prependTo(this._elem)}else{ap.appendTo(this._elem)}if(this.showSwatches){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-swatch");aj.css({textAlign:"center",paddingTop:al});an=L(document.createElement("div"));an.addClass("jqplot-table-legend-swatch-outline");am=L(document.createElement("div"));am.addClass("jqplot-table-legend-swatch");am.css({backgroundColor:ak,borderColor:ak});ap.append(aj.append(an.append(am)))}if(this.showLabels){aj=L(document.createElement("td"));aj.addClass("jqplot-table-legend jqplot-table-legend-label");aj.css("paddingTop",al);ap.append(aj);if(this.escapeHtml){aj.text(aq)}else{aj.html(aq)}}aj=null;an=null;am=null;ap=null;ai=null};L.jqplot.TableLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var am=this._series;var ai=document.createElement("table");this._elem=L(ai);this._elem.addClass("jqplot-table-legend");var ar={position:"absolute"};if(this.background){ar.background=this.background}if(this.border){ar.border=this.border}if(this.fontSize){ar.fontSize=this.fontSize}if(this.fontFamily){ar.fontFamily=this.fontFamily}if(this.textColor){ar.textColor=this.textColor}if(this.marginTop!=null){ar.marginTop=this.marginTop}if(this.marginBottom!=null){ar.marginBottom=this.marginBottom}if(this.marginLeft!=null){ar.marginLeft=this.marginLeft}if(this.marginRight!=null){ar.marginRight=this.marginRight}var ah=false,ao=false,aq;for(var an=0;an<am.length;an++){aq=am[an];if(aq._stack||aq.renderer.constructor==L.jqplot.BezierCurveRenderer){ao=true}if(aq.show&&aq.showLabel){var al=this.labels[an]||aq.label.toString();if(al){var aj=aq.color;if(ao&&an<am.length-1){ah=true}else{if(ao&&an==am.length-1){ah=false}}this.renderer.addrow.call(this,al,aj,ah,ao);ah=true}for(var ak=0;ak<L.jqplot.addLegendRowHooks.length;ak++){var ap=L.jqplot.addLegendRowHooks[ak].call(this,aq);if(ap){this.renderer.addrow.call(this,ap.label,ap.color,ah);ah=true}}al=null}}}return this._elem};L.jqplot.TableLegendRenderer.prototype.pack=function(aj){if(this.show){if(this.placement=="insideGrid"){switch(this.location){case"nw":var ai=aj.left;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.top;this._elem.css("left",ai);this._elem.css("top",ah);break;case"ne":var ai=aj.right;var ah=aj.top;this._elem.css({right:ai,top:ah});break;case"e":var ai=aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;case"se":var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"sw":var ai=aj.left;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"w":var ai=aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{if(this.placement=="outside"){switch(this.location){case"nw":var ai=this._plotDimensions.width-aj.left;var ah=aj.top;this._elem.css("right",ai);this._elem.css("top",ah);break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.top;this._elem.css("left",ai);this._elem.css("bottom",ah);break;case"ne":var ai=this._plotDimensions.width-aj.right;var ah=aj.top;this._elem.css({left:ai,top:ah});break;case"e":var ai=this._plotDimensions.width-aj.right;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:ai,top:ah});break;case"se":var ai=this._plotDimensions.width-aj.right;var ah=aj.bottom;this._elem.css({left:ai,bottom:ah});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;var ah=this._plotDimensions.height-aj.bottom;this._elem.css({left:ai,top:ah});break;case"sw":var ai=this._plotDimensions.width-aj.left;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break;case"w":var ai=this._plotDimensions.width-aj.left;var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:ai,top:ah});break;default:var ai=aj.right;var ah=aj.bottom;this._elem.css({right:ai,bottom:ah});break}}else{switch(this.location){case"nw":this._elem.css({left:0,top:aj.top});break;case"n":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,top:aj.top});break;case"ne":this._elem.css({right:0,top:aj.top});break;case"e":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({right:aj.right,top:ah});break;case"se":this._elem.css({right:aj.right,bottom:aj.bottom});break;case"s":var ai=(aj.left+(this._plotDimensions.width-aj.right))/2-this.getWidth()/2;this._elem.css({left:ai,bottom:aj.bottom});break;case"sw":this._elem.css({left:aj.left,bottom:aj.bottom});break;case"w":var ah=(aj.top+(this._plotDimensions.height-aj.bottom))/2-this.getHeight()/2;this._elem.css({left:aj.left,top:ah});break;default:this._elem.css({right:aj.right,bottom:aj.bottom});break}}}}};L.jqplot.ThemeEngine=function(){this.themes={};this.activeTheme=null};L.jqplot.ThemeEngine.prototype.init=function(){var ak=new L.jqplot.Theme({_name:"Default"});var an,ai,am;for(an in ak.target){if(an=="textColor"){ak.target[an]=this.target.css("color")}else{ak.target[an]=this.target.css(an)}}if(this.title.show&&this.title._elem){for(an in ak.title){if(an=="textColor"){ak.title[an]=this.title._elem.css("color")}else{ak.title[an]=this.title._elem.css(an)}}}for(an in ak.grid){ak.grid[an]=this.grid[an]}if(ak.grid.backgroundColor==null&&this.grid.background!=null){ak.grid.backgroundColor=this.grid.background}if(this.legend.show&&this.legend._elem){for(an in ak.legend){if(an=="textColor"){ak.legend[an]=this.legend._elem.css("color")}else{ak.legend[an]=this.legend._elem.css(an)}}}var aj;for(ai=0;ai<this.series.length;ai++){aj=this.series[ai];if(aj.renderer.constructor==L.jqplot.LineRenderer){ak.series.push(new p())}else{if(aj.renderer.constructor==L.jqplot.BarRenderer){ak.series.push(new T())}else{if(aj.renderer.constructor==L.jqplot.PieRenderer){ak.series.push(new f())}else{if(aj.renderer.constructor==L.jqplot.DonutRenderer){ak.series.push(new G())}else{if(aj.renderer.constructor==L.jqplot.FunnelRenderer){ak.series.push(new Z())}else{if(aj.renderer.constructor==L.jqplot.MeterGaugeRenderer){ak.series.push(new D())}else{ak.series.push({})}}}}}}for(an in ak.series[ai]){ak.series[ai][an]=aj[an]}}var ah,al;for(an in this.axes){al=this.axes[an];ah=ak.axes[an]=new P();ah.borderColor=al.borderColor;ah.borderWidth=al.borderWidth;if(al._ticks&&al._ticks[0]){for(am in ah.ticks){if(al._ticks[0].hasOwnProperty(am)){ah.ticks[am]=al._ticks[0][am]}else{if(al._ticks[0]._elem){ah.ticks[am]=al._ticks[0]._elem.css(am)}}}}if(al._label&&al._label.show){for(am in ah.label){if(al._label[am]){ah.label[am]=al._label[am]}else{if(al._label._elem){if(am=="textColor"){ah.label[am]=al._label._elem.css("color")}else{ah.label[am]=al._label._elem.css(am)}}}}}}this.themeEngine._add(ak);this.themeEngine.activeTheme=this.themeEngine.themes[ak._name]};L.jqplot.ThemeEngine.prototype.get=function(ah){if(!ah){return this.activeTheme}else{return this.themes[ah]}};function O(ai,ah){return ai-ah}L.jqplot.ThemeEngine.prototype.getThemeNames=function(){var ah=[];for(var ai in this.themes){ah.push(ai)}return ah.sort(O)};L.jqplot.ThemeEngine.prototype.getThemes=function(){var ai=[];var ah=[];for(var ak in this.themes){ai.push(ak)}ai.sort(O);for(var aj=0;aj<ai.length;aj++){ah.push(this.themes[ai[aj]])}return ah};L.jqplot.ThemeEngine.prototype.activate=function(av,aB){var ah=false;if(!aB&&this.activeTheme&&this.activeTheme._name){aB=this.activeTheme._name}if(!this.themes.hasOwnProperty(aB)){throw new Error("No theme of that name")}else{var am=this.themes[aB];this.activeTheme=am;var aA,at=false,ar=false;var ai=["xaxis","x2axis","yaxis","y2axis"];for(aw=0;aw<ai.length;aw++){var an=ai[aw];if(am.axesStyles.borderColor!=null){av.axes[an].borderColor=am.axesStyles.borderColor}if(am.axesStyles.borderWidth!=null){av.axes[an].borderWidth=am.axesStyles.borderWidth}}for(var az in av.axes){var ak=av.axes[az];if(ak.show){var aq=am.axes[az]||{};var ao=am.axesStyles;var al=L.jqplot.extend(true,{},aq,ao);aA=(am.axesStyles.borderColor!=null)?am.axesStyles.borderColor:al.borderColor;if(al.borderColor!=null){ak.borderColor=al.borderColor;ah=true}aA=(am.axesStyles.borderWidth!=null)?am.axesStyles.borderWidth:al.borderWidth;if(al.borderWidth!=null){ak.borderWidth=al.borderWidth;ah=true}if(ak._ticks&&ak._ticks[0]){for(var aj in al.ticks){aA=al.ticks[aj];if(aA!=null){ak.tickOptions[aj]=aA;ak._ticks=[];ah=true}}}if(ak._label&&ak._label.show){for(var aj in al.label){aA=al.label[aj];if(aA!=null){ak.labelOptions[aj]=aA;ah=true}}}}}for(var au in am.grid){if(am.grid[au]!=null){av.grid[au]=am.grid[au]}}if(!ah){av.grid.draw()}if(av.legend.show){for(au in am.legend){if(am.legend[au]!=null){av.legend[au]=am.legend[au]}}}if(av.title.show){for(au in am.title){if(am.title[au]!=null){av.title[au]=am.title[au]}}}var aw;for(aw=0;aw<am.series.length;aw++){var ap={};var ay=false;for(au in am.series[aw]){aA=(am.seriesStyles[au]!=null)?am.seriesStyles[au]:am.series[aw][au];if(aA!=null){ap[au]=aA;if(au=="color"){av.series[aw].renderer.shapeRenderer.fillStyle=aA;av.series[aw].renderer.shapeRenderer.strokeStyle=aA;av.series[aw][au]=aA}else{if((au=="lineWidth")||(au=="linePattern")){av.series[aw].renderer.shapeRenderer[au]=aA;av.series[aw][au]=aA}else{if(au=="markerOptions"){V(av.series[aw].markerOptions,aA);V(av.series[aw].markerRenderer,aA)}else{av.series[aw][au]=aA}}}ah=true}}}if(ah){av.target.empty();av.draw()}for(au in am.target){if(am.target[au]!=null){av.target.css(au,am.target[au])}}}};L.jqplot.ThemeEngine.prototype._add=function(ai,ah){if(ah){ai._name=ah}if(!ai._name){ai._name=Date.parse(new Date())}if(!this.themes.hasOwnProperty(ai._name)){this.themes[ai._name]=ai}else{throw new Error("jqplot.ThemeEngine Error: Theme already in use")}};L.jqplot.ThemeEngine.prototype.remove=function(ah){if(ah=="Default"){return false}return delete this.themes[ah]};L.jqplot.ThemeEngine.prototype.newTheme=function(ah,aj){if(typeof(ah)=="object"){aj=aj||ah;ah=null}if(aj&&aj._name){ah=aj._name}else{ah=ah||Date.parse(new Date())}var ai=this.copy(this.themes.Default._name,ah);L.jqplot.extend(ai,aj);return ai};function B(aj){if(aj==null||typeof(aj)!="object"){return aj}var ah=new aj.constructor();for(var ai in aj){ah[ai]=B(aj[ai])}return ah}L.jqplot.clone=B;function V(aj,ai){if(ai==null||typeof(ai)!="object"){return}for(var ah in ai){if(ah=="highlightColors"){aj[ah]=B(ai[ah])}if(ai[ah]!=null&&typeof(ai[ah])=="object"){if(!aj.hasOwnProperty(ah)){aj[ah]={}}V(aj[ah],ai[ah])}else{aj[ah]=ai[ah]}}}L.jqplot.merge=V;L.jqplot.extend=function(){var am=arguments[0]||{},ak=1,al=arguments.length,ah=false,aj;if(typeof am==="boolean"){ah=am;am=arguments[1]||{};ak=2}if(typeof am!=="object"&&!toString.call(am)==="[object Function]"){am={}}for(;ak<al;ak++){if((aj=arguments[ak])!=null){for(var ai in aj){var an=am[ai],ao=aj[ai];if(am===ao){continue}if(ah&&ao&&typeof ao==="object"&&!ao.nodeType){am[ai]=L.jqplot.extend(ah,an||(ao.length!=null?[]:{}),ao)}else{if(ao!==u){am[ai]=ao}}}}}return am};L.jqplot.ThemeEngine.prototype.rename=function(ai,ah){if(ai=="Default"||ah=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot rename from/to Default")}if(this.themes.hasOwnProperty(ah)){throw new Error("jqplot.ThemeEngine Error: New name already in use.")}else{if(this.themes.hasOwnProperty(ai)){var aj=this.copy(ai,ah);this.remove(ai);return aj}}throw new Error("jqplot.ThemeEngine Error: Old name or new name invalid")};L.jqplot.ThemeEngine.prototype.copy=function(ah,aj,al){if(aj=="Default"){throw new Error("jqplot.ThemeEngine Error: Cannot copy over Default theme")}if(!this.themes.hasOwnProperty(ah)){var ai="jqplot.ThemeEngine Error: Source name invalid";throw new Error(ai)}if(this.themes.hasOwnProperty(aj)){var ai="jqplot.ThemeEngine Error: Target name invalid";throw new Error(ai)}else{var ak=B(this.themes[ah]);ak._name=aj;L.jqplot.extend(true,ak,al);this._add(ak);return ak}};L.jqplot.Theme=function(ah,ai){if(typeof(ah)=="object"){ai=ai||ah;ah=null}ah=ah||Date.parse(new Date());this._name=ah;this.target={backgroundColor:null};this.legend={textColor:null,fontFamily:null,fontSize:null,border:null,background:null};this.title={textColor:null,fontFamily:null,fontSize:null,textAlign:null};this.seriesStyles={};this.series=[];this.grid={drawGridlines:null,gridLineColor:null,gridLineWidth:null,backgroundColor:null,borderColor:null,borderWidth:null,shadow:null};this.axesStyles={label:{},ticks:{}};this.axes={};if(typeof(ai)=="string"){this._name=ai}else{if(typeof(ai)=="object"){L.jqplot.extend(true,this,ai)}}};var P=function(){this.borderColor=null;this.borderWidth=null;this.ticks=new o();this.label=new t()};var o=function(){this.show=null;this.showGridline=null;this.showLabel=null;this.showMark=null;this.size=null;this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null};var t=function(){this.textColor=null;this.whiteSpace=null;this.fontSize=null;this.fontFamily=null;this.fontWeight=null};var p=function(){this.color=null;this.lineWidth=null;this.linePattern=null;this.shadow=null;this.fillColor=null;this.showMarker=null;this.markerOptions=new I()};var I=function(){this.show=null;this.style=null;this.lineWidth=null;this.size=null;this.color=null;this.shadow=null};var T=function(){this.color=null;this.seriesColors=null;this.lineWidth=null;this.shadow=null;this.barPadding=null;this.barMargin=null;this.barWidth=null;this.highlightColors=null};var f=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.highlightColors=null};var G=function(){this.seriesColors=null;this.padding=null;this.sliceMargin=null;this.fill=null;this.shadow=null;this.startAngle=null;this.lineWidth=null;this.innerDiameter=null;this.thickness=null;this.ringMargin=null;this.highlightColors=null};var Z=function(){this.color=null;this.lineWidth=null;this.shadow=null;this.padding=null;this.sectionMargin=null;this.seriesColors=null;this.highlightColors=null};var D=function(){this.padding=null;this.backgroundColor=null;this.ringColor=null;this.tickColor=null;this.ringWidth=null;this.intervalColors=null;this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.hubRadius=null;this.needleThickness=null;this.needlePad=null};L.fn.jqplotChildText=function(){return L(this).contents().filter(function(){return this.nodeType==3}).text()};L.fn.jqplotGetComputedFontStyle=function(){var ak=window.getComputedStyle?window.getComputedStyle(this[0],""):this[0].currentStyle;var ai=ak["font-style"]?["font-style","font-weight","font-size","font-family"]:["fontStyle","fontWeight","fontSize","fontFamily"];var al=[];for(var aj=0;aj<ai.length;++aj){var ah=String(ak[ai[aj]]);if(ah&&ah!="normal"){al.push(ah)}}return al.join(" ")};L.fn.jqplotToImageCanvas=function(aj){aj=aj||{};var av=(aj.x_offset==null)?0:aj.x_offset;var ax=(aj.y_offset==null)?0:aj.y_offset;var al=(aj.backgroundColor==null)?"rgb(255,255,255)":aj.backgroundColor;if(L(this).width()==0||L(this).height()==0){return null}if(L.jqplot.use_excanvas){return null}var an=document.createElement("canvas");var aA=L(this).outerHeight(true);var at=L(this).outerWidth(true);var am=L(this).offset();var ao=am.left;var aq=am.top;var au=0,ar=0;var ay=["jqplot-table-legend","jqplot-xaxis-tick","jqplot-x2axis-tick","jqplot-yaxis-tick","jqplot-y2axis-tick","jqplot-y3axis-tick","jqplot-y4axis-tick","jqplot-y5axis-tick","jqplot-y6axis-tick","jqplot-y7axis-tick","jqplot-y8axis-tick","jqplot-y9axis-tick","jqplot-xaxis-label","jqplot-x2axis-label","jqplot-yaxis-label","jqplot-y2axis-label","jqplot-y3axis-label","jqplot-y4axis-label","jqplot-y5axis-label","jqplot-y6axis-label","jqplot-y7axis-label","jqplot-y8axis-label","jqplot-y9axis-label"];var ap,ah,ai,aB;for(var az=0;az<ay.length;az++){L(this).find("."+ay[az]).each(function(){ap=L(this).offset().top-aq;ah=L(this).offset().left-ao;aB=ah+L(this).outerWidth(true)+au;ai=ap+L(this).outerHeight(true)+ar;if(ah<-au){at=at-au-ah;au=-ah}if(ap<-ar){aA=aA-ar-ap;ar=-ap}if(aB>at){at=aB}if(ai>aA){aA=ai}})}an.width=at+Number(av);an.height=aA+Number(ax);var ak=an.getContext("2d");ak.save();ak.fillStyle=al;ak.fillRect(0,0,an.width,an.height);ak.restore();ak.translate(au,ar);ak.textAlign="left";ak.textBaseline="top";function aC(aE){var aF=parseInt(L(aE).css("line-height"),10);if(isNaN(aF)){aF=parseInt(L(aE).css("font-size"),10)*1.2}return aF}function aD(aF,aE,aS,aG,aO,aH){var aQ=aC(aF);var aK=L(aF).innerWidth();var aL=L(aF).innerHeight();var aN=aS.split(/\s+/);var aR=aN.length;var aP="";var aM=[];var aU=aO;var aT=aG;for(var aJ=0;aJ<aR;aJ++){aP+=aN[aJ];if(aE.measureText(aP).width>aK){aM.push(aJ);aP="";aJ--}}if(aM.length===0){if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aS,aT,aO)}else{aP=aN.slice(0,aM[0]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ;for(var aJ=1,aI=aM.length;aJ<aI;aJ++){aP=aN.slice(aM[aJ-1],aM[aJ]).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU);aU+=aQ}aP=aN.slice(aM[aJ-1],aN.length).join(" ");if(L(aF).css("textAlign")==="center"){aT=aG+(aH-aE.measureText(aP).width)/2-au}aE.fillText(aP,aT,aU)}}function aw(aG,aJ,aE){var aN=aG.tagName.toLowerCase();var aF=L(aG).position();var aK=window.getComputedStyle?window.getComputedStyle(aG,""):aG.currentStyle;var aI=aJ+aF.left+parseInt(aK.marginLeft,10)+parseInt(aK.borderLeftWidth,10)+parseInt(aK.paddingLeft,10);var aL=aE+aF.top+parseInt(aK.marginTop,10)+parseInt(aK.borderTopWidth,10)+parseInt(aK.paddingTop,10);var aM=an.width;if((aN=="div"||aN=="span")&&!L(aG).hasClass("jqplot-highlighter-tooltip")){L(aG).children().each(function(){aw(this,aI,aL)});var aO=L(aG).jqplotChildText();if(aO){ak.font=L(aG).jqplotGetComputedFontStyle();ak.fillStyle=L(aG).css("color");aD(aG,ak,aO,aI,aL,aM)}}else{if(aN==="table"&&L(aG).hasClass("jqplot-table-legend")){ak.strokeStyle=L(aG).css("border-top-color");ak.fillStyle=L(aG).css("background-color");ak.fillRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight());if(parseInt(L(aG).css("border-top-width"),10)>0){ak.strokeRect(aI,aL,L(aG).innerWidth(),L(aG).innerHeight())}L(aG).find("div.jqplot-table-legend-swatch-outline").each(function(){var aU=L(this);ak.strokeStyle=aU.css("border-top-color");var aQ=aI+aU.position().left;var aR=aL+aU.position().top;ak.strokeRect(aQ,aR,aU.innerWidth(),aU.innerHeight());aQ+=parseInt(aU.css("padding-left"),10);aR+=parseInt(aU.css("padding-top"),10);var aT=aU.innerHeight()-2*parseInt(aU.css("padding-top"),10);var aP=aU.innerWidth()-2*parseInt(aU.css("padding-left"),10);var aS=aU.children("div.jqplot-table-legend-swatch");ak.fillStyle=aS.css("background-color");ak.fillRect(aQ,aR,aP,aT)});L(aG).find("td.jqplot-table-legend-label").each(function(){var aR=L(this);var aP=aI+aR.position().left;var aQ=aL+aR.position().top+parseInt(aR.css("padding-top"),10);ak.font=aR.jqplotGetComputedFontStyle();ak.fillStyle=aR.css("color");aD(aR,ak,aR.text(),aP,aQ,aM)});var aH=null}else{if(aN=="canvas"){ak.drawImage(aG,aI,aL)}}}}L(this).children().each(function(){aw(this,av,ax)});return an};L.fn.jqplotToImageStr=function(ai){var ah=L(this).jqplotToImageCanvas(ai);if(ah){return ah.toDataURL("image/png")}else{return null}};L.fn.jqplotToImageElem=function(ah){var ai=document.createElement("img");var aj=L(this).jqplotToImageStr(ah);ai.src=aj;return ai};L.fn.jqplotToImageElemStr=function(ah){var ai="<img src="+L(this).jqplotToImageStr(ah)+" />";return ai};L.fn.jqplotSaveImage=function(){var ah=L(this).jqplotToImageStr({});if(ah){window.location.href=ah.replace("image/png","image/octet-stream")}};L.fn.jqplotViewImage=function(){var ai=L(this).jqplotToImageElemStr({});var aj=L(this).jqplotToImageStr({});if(ai){var ah=window.open("");ah.document.open("image/png");ah.document.write(ai);ah.document.close();ah=null}};var ag=function(){this.syntax=ag.config.syntax;this._type="jsDate";this.proxy=new Date();this.options={};this.locale=ag.regional.getLocale();this.formatString="";this.defaultCentury=ag.config.defaultCentury;switch(arguments.length){case 0:break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}};ag.config={defaultLocale:"en",syntax:"perl",defaultCentury:1900};ag.prototype.add=function(aj,ai){var ah=E[ai]||E.day;if(typeof ah=="number"){this.proxy.setTime(this.proxy.getTime()+(ah*aj))}else{ah.add(this,aj)}return this};ag.prototype.clone=function(){return new ag(this.proxy.getTime())};ag.prototype.getUtcOffset=function(){return this.proxy.getTimezoneOffset()*60000};ag.prototype.diff=function(ai,al,ah){ai=new ag(ai);if(ai===null){return null}var aj=E[al]||E.day;if(typeof aj=="number"){var ak=(this.proxy.getTime()-ai.proxy.getTime())/aj}else{var ak=aj.diff(this.proxy,ai.proxy)}return(ah?ak:Math[ak>0?"floor":"ceil"](ak))};ag.prototype.getAbbrDayName=function(){return ag.regional[this.locale]["dayNamesShort"][this.proxy.getDay()]};ag.prototype.getAbbrMonthName=function(){return ag.regional[this.locale]["monthNamesShort"][this.proxy.getMonth()]};ag.prototype.getAMPM=function(){return this.proxy.getHours()>=12?"PM":"AM"};ag.prototype.getAmPm=function(){return this.proxy.getHours()>=12?"pm":"am"};ag.prototype.getCentury=function(){return parseInt(this.proxy.getFullYear()/100,10)};ag.prototype.getDate=function(){return this.proxy.getDate()};ag.prototype.getDay=function(){return this.proxy.getDay()};ag.prototype.getDayOfWeek=function(){var ah=this.proxy.getDay();return ah===0?7:ah};ag.prototype.getDayOfYear=function(){var ai=this.proxy;var ah=ai-new Date(""+ai.getFullYear()+"/1/1 GMT");ah+=ai.getTimezoneOffset()*60000;ai=null;return parseInt(ah/60000/60/24,10)+1};ag.prototype.getDayName=function(){return ag.regional[this.locale]["dayNames"][this.proxy.getDay()]};ag.prototype.getFullWeekOfYear=function(){var ak=this.proxy;var ah=this.getDayOfYear();var aj=6-ak.getDay();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getFullYear=function(){return this.proxy.getFullYear()};ag.prototype.getGmtOffset=function(){var ah=this.proxy.getTimezoneOffset()/60;var ai=ah<0?"+":"-";ah=Math.abs(ah);return ai+N(Math.floor(ah),2)+":"+N((ah%1)*60,2)};ag.prototype.getHours=function(){return this.proxy.getHours()};ag.prototype.getHours12=function(){var ah=this.proxy.getHours();return ah>12?ah-12:(ah==0?12:ah)};ag.prototype.getIsoWeek=function(){var ak=this.proxy;var aj=this.getWeekOfYear();var ah=(new Date(""+ak.getFullYear()+"/1/1")).getDay();var ai=aj+(ah>4||ah<=1?0:1);if(ai==53&&(new Date(""+ak.getFullYear()+"/12/31")).getDay()<4){ai=1}else{if(ai===0){ak=new ag(new Date(""+(ak.getFullYear()-1)+"/12/31"));ai=ak.getIsoWeek()}}ak=null;return ai};ag.prototype.getMilliseconds=function(){return this.proxy.getMilliseconds()};ag.prototype.getMinutes=function(){return this.proxy.getMinutes()};ag.prototype.getMonth=function(){return this.proxy.getMonth()};ag.prototype.getMonthName=function(){return ag.regional[this.locale]["monthNames"][this.proxy.getMonth()]};ag.prototype.getMonthNumber=function(){return this.proxy.getMonth()+1};ag.prototype.getSeconds=function(){return this.proxy.getSeconds()};ag.prototype.getShortYear=function(){return this.proxy.getYear()%100};ag.prototype.getTime=function(){return this.proxy.getTime()};ag.prototype.getTimezoneAbbr=function(){return this.proxy.toString().replace(/^.*\(([^)]+)\)$/,"$1")};ag.prototype.getTimezoneName=function(){var ah=/(?:\((.+)\)$| ([A-Z]{3}) )/.exec(this.toString());return ah[1]||ah[2]||"GMT"+this.getGmtOffset()};ag.prototype.getTimezoneOffset=function(){return this.proxy.getTimezoneOffset()};ag.prototype.getWeekOfYear=function(){var ah=this.getDayOfYear();var aj=7-this.getDayOfWeek();var ai=parseInt((ah+aj)/7,10);return ai};ag.prototype.getUnix=function(){return Math.round(this.proxy.getTime()/1000,0)};ag.prototype.getYear=function(){return this.proxy.getYear()};ag.prototype.next=function(ah){ah=ah||"day";return this.clone().add(1,ah)};ag.prototype.set=function(){switch(arguments.length){case 0:this.proxy=new Date();break;case 1:if(l(arguments[0])=="[object Object]"&&arguments[0]._type!="jsDate"){var aj=this.options=arguments[0];this.syntax=aj.syntax||this.syntax;this.defaultCentury=aj.defaultCentury||this.defaultCentury;this.proxy=ag.createDate(aj.date)}else{this.proxy=ag.createDate(arguments[0])}break;default:var ah=[];for(var ai=0;ai<arguments.length;ai++){ah.push(arguments[ai])}this.proxy=new Date();this.proxy.setFullYear.apply(this.proxy,ah.slice(0,3));if(ah.slice(3).length){this.proxy.setHours.apply(this.proxy,ah.slice(3))}break}return this};ag.prototype.setDate=function(ah){this.proxy.setDate(ah);return this};ag.prototype.setFullYear=function(){this.proxy.setFullYear.apply(this.proxy,arguments);return this};ag.prototype.setHours=function(){this.proxy.setHours.apply(this.proxy,arguments);return this};ag.prototype.setMilliseconds=function(ah){this.proxy.setMilliseconds(ah);return this};ag.prototype.setMinutes=function(){this.proxy.setMinutes.apply(this.proxy,arguments);return this};ag.prototype.setMonth=function(){this.proxy.setMonth.apply(this.proxy,arguments);return this};ag.prototype.setSeconds=function(){this.proxy.setSeconds.apply(this.proxy,arguments);return this};ag.prototype.setTime=function(ah){this.proxy.setTime(ah);return this};ag.prototype.setYear=function(){this.proxy.setYear.apply(this.proxy,arguments);return this};ag.prototype.strftime=function(ah){ah=ah||this.formatString||ag.regional[this.locale]["formatString"];return ag.strftime(this,ah,this.syntax)};ag.prototype.toString=function(){return this.proxy.toString()};ag.prototype.toYmdInt=function(){return(this.proxy.getFullYear()*10000)+(this.getMonthNumber()*100)+this.proxy.getDate()};ag.regional={en:{monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],formatString:"%Y-%m-%d %H:%M:%S"},fr:{monthNames:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],monthNamesShort:["Jan","Fév","Mar","Avr","Mai","Jun","Jul","Aoû","Sep","Oct","Nov","Déc"],dayNames:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],dayNamesShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],formatString:"%Y-%m-%d %H:%M:%S"},de:{monthNames:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],monthNamesShort:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"],dayNames:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"],dayNamesShort:["So","Mo","Di","Mi","Do","Fr","Sa"],formatString:"%Y-%m-%d %H:%M:%S"},es:{monthNames:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],monthNamesShort:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],dayNames:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],dayNamesShort:["Dom","Lun","Mar","Mié","Juv","Vie","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},ru:{monthNames:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],monthNamesShort:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],dayNames:["воскресенье","понедельник","вторник","среда","четверг","пятница","суббота"],dayNamesShort:["вск","пнд","втр","срд","чтв","птн","сбт"],formatString:"%Y-%m-%d %H:%M:%S"},ar:{monthNames:["كانون الثاني","شباط","آذار","نيسان","آذار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],monthNamesShort:["1","2","3","4","5","6","7","8","9","10","11","12"],dayNames:["السبت","الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة"],dayNamesShort:["سبت","أحد","اثنين","ثلاثاء","أربعاء","خميس","جمعة"],formatString:"%Y-%m-%d %H:%M:%S"},pt:{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},"pt-BR":{monthNames:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],monthNamesShort:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],dayNames:["Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado"],dayNamesShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],formatString:"%Y-%m-%d %H:%M:%S"},pl:{monthNames:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],monthNamesShort:["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],dayNames:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],dayNamesShort:["Ni","Pn","Wt","Śr","Cz","Pt","Sb"],formatString:"%Y-%m-%d %H:%M:%S"},nl:{monthNames:["Januari","Februari","Maart","April","Mei","Juni","July","Augustus","September","Oktober","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],dayNames:","["Zondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrijdag","Zaterdag"],dayNamesShort:["Zo","Ma","Di","Wo","Do","Vr","Za"],formatString:"%Y-%m-%d %H:%M:%S"},sv:{monthNames:["januari","februari","mars","april","maj","juni","juli","augusti","september","oktober","november","december"],monthNamesShort:["jan","feb","mar","apr","maj","jun","jul","aug","sep","okt","nov","dec"],dayNames:["söndag","måndag","tisdag","onsdag","torsdag","fredag","lördag"],dayNamesShort:["sön","mån","tis","ons","tor","fre","lör"],formatString:"%Y-%m-%d %H:%M:%S"}};ag.regional["en-US"]=ag.regional["en-GB"]=ag.regional.en;ag.regional.getLocale=function(){var ah=ag.config.defaultLocale;if(document&&document.getElementsByTagName("html")&&document.getElementsByTagName("html")[0].lang){ah=document.getElementsByTagName("html")[0].lang;if(!ag.regional.hasOwnProperty(ah)){ah=ag.config.defaultLocale}}return ah};var C=24*60*60*1000;var N=function(ah,ak){ah=String(ah);var ai=ak-ah.length;var aj=String(Math.pow(10,ai)).slice(1);return aj.concat(ah)};var E={millisecond:1,second:1000,minute:60*1000,hour:60*60*1000,day:C,week:7*C,month:{add:function(aj,ah){E.year.add(aj,Math[ah>0?"floor":"ceil"](ah/12));var ai=aj.getMonth()+(ah%12);if(ai==12){ai=0;aj.setYear(aj.getFullYear()+1)}else{if(ai==-1){ai=11;aj.setYear(aj.getFullYear()-1)}}aj.setMonth(ai)},diff:function(al,aj){var ah=al.getFullYear()-aj.getFullYear();var ai=al.getMonth()-aj.getMonth()+(ah*12);var ak=al.getDate()-aj.getDate();return ai+(ak/30)}},year:{add:function(ai,ah){ai.setYear(ai.getFullYear()+Math[ah>0?"floor":"ceil"](ah))},diff:function(ai,ah){return E.month.diff(ai,ah)/12}}};for(var Y in E){if(Y.substring(Y.length-1)!="s"){E[Y+"s"]=E[Y]}}var H=function(al,ak,ai){if(ag.formats[ai]["shortcuts"][ak]){return ag.strftime(al,ag.formats[ai]["shortcuts"][ak],ai)}else{var ah=(ag.formats[ai]["codes"][ak]||"").split(".");var aj=al["get"+ah[0]]?al["get"+ah[0]]():"";if(ah[1]){aj=N(aj,ah[1])}return aj}};ag.strftime=function(an,ak,aj,ao){var ai="perl";var am=ag.regional.getLocale();if(aj&&ag.formats.hasOwnProperty(aj)){ai=aj}else{if(aj&&ag.regional.hasOwnProperty(aj)){am=aj}}if(ao&&ag.formats.hasOwnProperty(ao)){ai=ao}else{if(ao&&ag.regional.hasOwnProperty(ao)){am=ao}}if(l(an)!="[object Object]"||an._type!="jsDate"){an=new ag(an);an.locale=am}if(!ak){ak=an.formatString||ag.regional[am]["formatString"]}var ah=ak||"%Y-%m-%d",ap="",al;while(ah.length>0){if(al=ah.match(ag.formats[ai].codes.matcher)){ap+=ah.slice(0,al.index);ap+=(al[1]||"")+H(an,al[2],ai);ah=ah.slice(al.index+al[0].length)}else{ap+=ah;ah=""}}return ap};ag.formats={ISO:"%Y-%m-%dT%H:%M:%S.%N%G",SQL:"%Y-%m-%d %H:%M:%S"};ag.formats.perl={codes:{matcher:/()%(#?(%|[a-z]))/i,Y:"FullYear",y:"ShortYear.2",m:"MonthNumber.2","#m":"MonthNumber",B:"MonthName",b:"AbbrMonthName",d:"Date.2","#d":"Date",e:"Date",A:"DayName",a:"AbbrDayName",w:"Day",H:"Hours.2","#H":"Hours",I:"Hours12.2","#I":"Hours12",p:"AMPM",M:"Minutes.2","#M":"Minutes",S:"Seconds.2","#S":"Seconds",s:"Unix",N:"Milliseconds.3","#N":"Milliseconds",O:"TimezoneOffset",Z:"TimezoneName",G:"GmtOffset"},shortcuts:{F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",D:"%m/%d/%y","#c":"%a %b %e %H:%M:%S %Y",v:"%e-%b-%Y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.formats.php={codes:{matcher:/()%((%|[a-z]))/i,a:"AbbrDayName",A:"DayName",d:"Date.2",e:"Date",j:"DayOfYear.3",u:"DayOfWeek",w:"Day",U:"FullWeekOfYear.2",V:"IsoWeek.2",W:"WeekOfYear.2",b:"AbbrMonthName",B:"MonthName",m:"MonthNumber.2",h:"AbbrMonthName",C:"Century.2",y:"ShortYear.2",Y:"FullYear",H:"Hours.2",I:"Hours12.2",l:"Hours12",p:"AMPM",P:"AmPm",M:"Minutes.2",S:"Seconds.2",s:"Unix",O:"TimezoneOffset",z:"GmtOffset",Z:"TimezoneAbbr"},shortcuts:{D:"%m/%d/%y",F:"%Y-%m-%d",T:"%H:%M:%S",X:"%H:%M:%S",x:"%m/%d/%y",R:"%H:%M",r:"%I:%M:%S %p",t:"\t",n:"\n","%":"%"}};ag.createDate=function(aj){if(aj==null){return new Date()}if(aj instanceof Date){return aj}if(typeof aj=="number"){return new Date(aj)}var ao=String(aj).replace(/^\s*(.+)\s*$/g,"$1");ao=ao.replace(/^([0-9]{1,4})-([0-9]{1,2})-([0-9]{1,4})/,"$1/$2/$3");ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{4})/i,"$1 $2 $3");var an=ao.match(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i);if(an&&an.length>3){var at=parseFloat(an[3]);var am=ag.config.defaultCentury+at;am=String(am);ao=ao.replace(/^(3[01]|[0-2]?\d)[-\/]([a-z]{3,})[-\/](\d{2})\D*/i,an[1]+" "+an[2]+" "+am)}an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})[^0-9]/);function ar(ax,aw){var aC=parseFloat(aw[1]);var aB=parseFloat(aw[2]);var aA=parseFloat(aw[3]);var az=ag.config.defaultCentury;var av,au,aD,ay;if(aC>31){au=aA;aD=aB;av=az+aC}else{au=aB;aD=aC;av=az+aA}ay=aD+"/"+au+"/"+av;return ax.replace(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})/,ay)}if(an&&an.length>3){ao=ar(ao,an)}var an=ao.match(/^([0-9]{1,2})[-\/]([0-9]{1,2})[-\/]([0-9]{1,2})$/);if(an&&an.length>3){ao=ar(ao,an)}var al=0;var ai=ag.matchers.length;var aq,ah,ap=ao,ak;while(al<ai){ah=Date.parse(ap);if(!isNaN(ah)){return new Date(ah)}aq=ag.matchers[al];if(typeof aq=="function"){ak=aq.call(ag,ap);if(ak instanceof Date){return ak}}else{ap=ao.replace(aq[0],aq[1])}al++}return NaN};ag.daysInMonth=function(ah,ai){if(ai==2){return new Date(ah,1,29).getDate()==29?29:28}return[u,31,u,31,30,31,30,31,31,30,31,30,31][ai]};ag.matchers=[[/(3[01]|[0-2]\d)\s*\.\s*(1[0-2]|0\d)\s*\.\s*([1-9]\d{3})/,"$2/$1/$3"],[/([1-9]\d{3})\s*-\s*(1[0-2]|0\d)\s*-\s*(3[01]|[0-2]\d)/,"$2/$3/$1"],function(ak){var ai=ak.match(/^(?:(.+)\s+)?([012]?\d)(?:\s*\:\s*(\d\d))?(?:\s*\:\s*(\d\d(\.\d*)?))?\s*(am|pm)?\s*$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);if(ai[6]){ah=ai[6].toLowerCase()=="am"?(ah==12?0:ah):(ah==12?12:ah+12)}aj.setHours(ah,parseInt(ai[3]||0,10),parseInt(ai[4]||0,10),((parseFloat(ai[5]||0))||0)*1000);return aj}else{return ak}},function(ak){var ai=ak.match(/^(?:(.+))[T|\s+]([012]\d)(?:\:(\d\d))(?:\:(\d\d))(?:\.\d+)([\+\-]\d\d\:\d\d)$/i);if(ai){if(ai[1]){var aj=this.createDate(ai[1]);if(isNaN(aj)){return}}else{var aj=new Date();aj.setMilliseconds(0)}var ah=parseFloat(ai[2]);aj.setHours(ah,parseInt(ai[3],10),parseInt(ai[4],10),parseFloat(ai[5])*1000);return aj}else{return ak}},function(al){var aj=al.match(/^([0-3]?\d)\s*[-\/.\s]{1}\s*([a-zA-Z]{3,9})\s*[-\/.\s]{1}\s*([0-3]?\d)$/);if(aj){var ak=new Date();var am=ag.config.defaultCentury;var ao=parseFloat(aj[1]);var an=parseFloat(aj[3]);var ai,ah,ap;if(ao>31){ah=an;ai=am+ao}else{ah=ao;ai=am+an}var ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNamesShort"]);if(ap==-1){ap=ab(aj[2],ag.regional[ag.regional.getLocale()]["monthNames"])}ak.setFullYear(ai,ap,ah);ak.setHours(0,0,0,0);return ak}else{return al}}];function ab(aj,ak){if(ak.indexOf){return ak.indexOf(aj)}for(var ah=0,ai=ak.length;ah<ai;ah++){if(ak[ah]===aj){return ah}}return -1}function l(ah){if(ah===null){return"[object Null]"}return Object.prototype.toString.call(ah)}L.jsDate=ag;L.jqplot.sprintf=function(){function an(au,ap,aq,at){var ar=(au.length>=ap)?"":Array(1+ap-au.length>>>0).join(aq);return at?au+ar:ar+au}function ak(ar){var aq=new String(ar);for(var ap=10;ap>0;ap--){if(aq==(aq=aq.replace(/^(\d+)(\d{3})/,"$1"+L.jqplot.sprintf.thousandsSeparator+"$2"))){break}}return aq}function aj(av,au,ax,ar,at,aq){var aw=ar-av.length;if(aw>0){var ap=" ";if(aq){ap=" "}if(ax||!at){av=an(av,ar,ap,ax)}else{av=av.slice(0,au.length)+an("",aw,"0",true)+av.slice(au.length)}}return av}function ao(ay,aq,aw,ar,ap,av,ax,au){var at=ay>>>0;aw=aw&&at&&{"2":"0b","8":"0","16":"0x"}[aq]||"";ay=aw+an(at.toString(aq),av||0,"0",false);return aj(ay,aw,ar,ap,ax,au)}function ah(au,av,ar,ap,at,aq){if(ap!=null){au=au.slice(0,ap)}return aj(au,"",av,ar,at,aq)}var ai=arguments,al=0,am=ai[al++];return am.replace(L.jqplot.sprintf.regex,function(aM,ax,ay,aB,aO,aJ,av){if(aM=="%%"){return"%"}var aD=false,az="",aA=false,aL=false,aw=false,au=false;for(var aI=0;ay&&aI<ay.length;aI++){switch(ay.charAt(aI)){case" ":az=" ";break;case"+":az="+";break;case"-":aD=true;break;case"0":aA=true;break;case"#":aL=true;break;case"&":aw=true;break;case"'":au=true;break}}if(!aB){aB=0}else{if(aB=="*"){aB=+ai[al++]}else{if(aB.charAt(0)=="*"){aB=+ai[aB.slice(1,-1)]}else{aB=+aB}}}if(aB<0){aB=-aB;aD=true}if(!isFinite(aB)){throw new Error("$.jqplot.sprintf: (minimum-)width must be finite")}if(!aJ){aJ="fFeE".indexOf(av)>-1?6:(av=="d")?0:void (0)}else{if(aJ=="*"){aJ=+ai[al++]}else{if(aJ.charAt(0)=="*"){aJ=+ai[aJ.slice(1,-1)]}else{aJ=+aJ}}}var aF=ax?ai[ax.slice(0,-1)]:ai[al++];switch(av){case"s":if(aF==null){return""}return ah(String(aF),aD,aB,aJ,aA,aw);case"c":return ah(String.fromCharCode(+aF),aD,aB,aJ,aA,aw);case"b":return ao(aF,2,aL,aD,aB,aJ,aA,aw);case"o":return ao(aF,8,aL,aD,aB,aJ,aA,aw);case"x":return ao(aF,16,aL,aD,aB,aJ,aA,aw);case"X":return ao(aF,16,aL,aD,aB,aJ,aA,aw).toUpperCase();case"u":return ao(aF,10,aL,aD,aB,aJ,aA,aw);case"i":var ar=parseInt(+aF,10);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"d":var ar=Math.round(+aF);if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aK=au?ak(String(Math.abs(ar))):String(Math.abs(ar));aF=aH+an(aK,aJ,"0",false);return aj(aF,aH,aD,aB,aA,aw);case"e":case"E":case"f":case"F":case"g":case"G":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var at=["toExponential","toFixed","toPrecision"]["efg".indexOf(av.toLowerCase())];var aN=["toString","toUpperCase"]["eEfFgG".indexOf(av)%2];var aK=Math.abs(ar)[at](aJ);var aE=aK.toString().split(".");aE[0]=au?ak(aE[0]):aE[0];aK=aE.join(L.jqplot.sprintf.decimalMark);aF=aH+aK;var aC=aj(aF,aH,aD,aB,aA,aw)[aN]();return aC;case"p":case"P":var ar=+aF;if(isNaN(ar)){return""}var aH=ar<0?"-":az;var aE=String(Number(Math.abs(ar)).toExponential()).split(/e|E/);var aq=(aE[0].indexOf(".")!=-1)?aE[0].length-1:String(ar).length;var aG=(aE[1]<0)?-aE[1]-1:0;if(Math.abs(ar)<1){if(aq+aG<=aJ){aF=aH+Math.abs(ar).toPrecision(aq)}else{if(aq<=aJ-1){aF=aH+Math.abs(ar).toExponential(aq-1)}else{aF=aH+Math.abs(ar).toExponential(aJ-1)}}}else{var ap=(aq<=aJ)?aq:aJ;aF=aH+Math.abs(ar).toPrecision(ap)}var aN=["toString","toUpperCase"]["pP".indexOf(av)%2];return aj(aF,aH,aD,aB,aA,aw)[aN]();case"n":return"";default:return aM}})};L.jqplot.sprintf.thousandsSeparator=",";L.jqplot.sprintf.decimalMark=".";L.jqplot.sprintf.regex=/%%|%(\d+\$)?([-+#0&\' ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([nAscboxXuidfegpEGP])/g;L.jqplot.getSignificantFigures=function(al){var an=String(Number(Math.abs(al)).toExponential()).split(/e|E/);var am=(an[0].indexOf(".")!=-1)?an[0].length-1:an[0].length;var ai=(an[1]<0)?-an[1]-1:0;var ah=parseInt(an[1],10);var aj=(ah+1>0)?ah+1:0;var ak=(am<=aj)?0:am-ah-1;return{significantDigits:am,digitsLeft:aj,digitsRight:ak,zeros:ai,exponent:ah}};L.jqplot.getPrecision=function(ah){return L.jqplot.getSignificantFigures(ah).digitsRight};var X=L.uiBackCompat!==false;L.jqplot.effects={effect:{}};var m="jqplot.storage.";L.extend(L.jqplot.effects,{version:"1.9pre",save:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.data(m+aj[ah],ai[0].style[aj[ah]])}}},restore:function(ai,aj){for(var ah=0;ah<aj.length;ah++){if(aj[ah]!==null){ai.css(aj[ah],ai.data(m+aj[ah]))}}},setMode:function(ah,ai){if(ai==="toggle"){ai=ah.is(":hidden")?"show":"hide"}return ai},createWrapper:function(ai){if(ai.parent().is(".ui-effects-wrapper")){return ai.parent()}var aj={width:ai.outerWidth(true),height:ai.outerHeight(true),"float":ai.css("float")},al=L("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),ah={width:ai.width(),height:ai.height()},ak=document.activeElement;ai.wrap(al);if(ai[0]===ak||L.contains(ai[0],ak)){L(ak).focus()}al=ai.parent();if(ai.css("position")==="static"){al.css({position:"relative"});ai.css({position:"relative"})}else{L.extend(aj,{position:ai.css("position"),zIndex:ai.css("z-index")});L.each(["top","left","bottom","right"],function(am,an){aj[an]=ai.css(an);if(isNaN(parseInt(aj[an],10))){aj[an]="auto"}});ai.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}ai.css(ah);return al.css(aj).show()},removeWrapper:function(ah){var ai=document.activeElement;if(ah.parent().is(".ui-effects-wrapper")){ah.parent().replaceWith(ah);if(ah[0]===ai||L.contains(ah[0],ai)){L(ai).focus()}}return ah}});function j(ai,ah,aj,ak){if(L.isPlainObject(ai)){return ai}ai={effect:ai};if(ah===u){ah={}}if(L.isFunction(ah)){ak=ah;aj=null;ah={}}if(L.type(ah)==="number"||L.fx.speeds[ah]){ak=aj;aj=ah;ah={}}if(L.isFunction(aj)){ak=aj;aj=null}if(ah){L.extend(ai,ah)}aj=aj||ah.duration;ai.duration=L.fx.off?0:typeof aj==="number"?aj:aj in L.fx.speeds?L.fx.speeds[aj]:L.fx.speeds._default;ai.complete=ak||ah.complete;return ai}function ae(ah){if(!ah||typeof ah==="number"||L.fx.speeds[ah]){return true}if(typeof ah==="string"&&!L.jqplot.effects.effect[ah]){if(X&&L.jqplot.effects[ah]){return false}return true}return false}L.fn.extend({jqplotEffect:function(ap,aq,ai,ao){var an=j.apply(this,arguments),ak=an.mode,al=an.queue,am=L.jqplot.effects.effect[an.effect],ah=!am&&X&&L.jqplot.effects[an.effect];if(L.fx.off||!(am||ah)){if(ak){return this[ak](an.duration,an.complete)}else{return this.each(function(){if(an.complete){an.complete.call(this)}})}}function aj(au){var av=L(this),at=an.complete,aw=an.mode;function ar(){if(L.isFunction(at)){at.call(av[0])}if(L.isFunction(au)){au()}}if(av.is(":hidden")?aw==="hide":aw==="show"){ar()}else{am.call(av[0],an,ar)}}if(am){return al===false?this.each(aj):this.queue(al||"fx",aj)}else{return ah.call(this,{options:an,duration:an.duration,callback:an.complete,mode:an.mode})}}});var a=/up|down|vertical/,v=/up|left|vertical|horizontal/;L.jqplot.effects.effect.blind=function(aj,ao){var ak=L(this),ar=["position","top","bottom","left","right","height","width"],ap=L.jqplot.effects.setMode(ak,aj.mode||"hide"),au=aj.direction||"up",am=a.test(au),al=am?"height":"width",aq=am?"top":"left",aw=v.test(au),an={},av=ap==="show",ai,ah,at;if(ak.parent().is(".ui-effects-wrapper")){L.jqplot.effects.save(ak.parent(),ar)}else{L.jqplot.effects.save(ak,ar)}ak.show();at=parseInt(ak.css("top"),10);ai=L.jqplot.effects.createWrapper(ak).css({overflow:"hidden"});ah=am?ai[al]()+at:ai[al]();an[al]=av?String(ah):"0";if(!aw){ak.css(am?"bottom":"right",0).css(am?"top":"left","").css({position:"absolute"});an[aq]=av?"0":String(ah)}if(av){ai.css(al,0);if(!aw){ai.css(aq,ah)}}ai.animate(an,{duration:aj.duration,easing:aj.easing,queue:false,complete:function(){if(ap==="hide"){ak.hide()}L.jqplot.effects.restore(ak,ar);L.jqplot.effects.removeWrapper(ak);ao()}})}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.js new file mode 100644 index 0000000..1c7b031 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.js @@ -0,0 +1,314 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + // Class: $.jqplot.BezierCurveRenderer.js + // Renderer which draws lines as stacked bezier curves. + // Data for the line will not be specified as an array of + // [x, y] data point values, but as a an array of [start piont, bezier curve] + // So, the line is specified as: [[xstart, ystart], [cp1x, cp1y, cp2x, cp2y, xend, yend]]. + $.jqplot.BezierCurveRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BezierCurveRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BezierCurveRenderer.prototype.constructor = $.jqplot.BezierCurveRenderer; + + + // Method: setGridData + // converts the user data values to grid coordinates and stores them + // in the gridData array. + // Called with scope of a series. + $.jqplot.BezierCurveRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + // this._plotData should be same as this.data + var data = this.data; + this.gridData = []; + this._prevGridData = []; + // if seriesIndex = 0, fill to x axis. + // if seriesIndex > 0, fill to previous series data. + var idx = this.index; + if (data.length == 2) { + if (idx == 0) { + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, psd[1][4]), yp.call(this._yaxis, psd[1][5])], + [xp.call(this._xaxis, psd[1][2]), yp.call(this._yaxis, psd[1][3]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + else { + if (idx == 0) { + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, data[3][1]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, psd[3][0]), yp.call(this._yaxis, psd[3][1])], + [xp.call(this._xaxis, psd[2][0]), yp.call(this._yaxis, psd[2][1]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + }; + + // Method: makeGridData + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.BezierCurveRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var gd = []; + var pgd = []; + // if seriesIndex = 0, fill to x axis. + // if seriesIndex > 0, fill to previous series data. + var idx = this.index; + if (data.length == 2) { + if (idx == 0) { + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, psd[1][4]), yp.call(this._yaxis, psd[1][5])], + [xp.call(this._xaxis, psd[1][2]), yp.call(this._yaxis, psd[1][3]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + else { + if (idx == 0) { + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, data[3][1]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, psd[3][0]), yp.call(this._yaxis, psd[3][1])], + [xp.call(this._xaxis, psd[2][0]), yp.call(this._yaxis, psd[2][1]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + return gd; + }; + + + // called within scope of series. + $.jqplot.BezierCurveRenderer.prototype.draw = function(ctx, gd, options) { + var i; + ctx.save(); + if (gd.length) { + if (this.showLine) { + ctx.save(); + var opts = (options != null) ? options : {}; + ctx.fillStyle = opts.fillStyle || this.color; + ctx.beginPath(); + ctx.moveTo(gd[0][0], gd[0][1]); + ctx.bezierCurveTo(gd[1][0], gd[1][1], gd[1][2], gd[1][3], gd[1][4], gd[1][5]); + ctx.lineTo(gd[2][0], gd[2][1]); + if (gd[3].length == 2) { + ctx.lineTo(gd[3][0], gd[3][1]); + } + else { + ctx.bezierCurveTo(gd[3][0], gd[3][1], gd[3][2], gd[3][3], gd[3][4], gd[3][5]); + } + ctx.closePath(); + ctx.fill(); + ctx.restore(); + } + } + + ctx.restore(); + }; + + $.jqplot.BezierCurveRenderer.prototype.drawShadow = function(ctx, gd, options) { + // This is a no-op, shadows drawn with lines. + }; + + $.jqplot.BezierAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.BezierAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.BezierAxisRenderer.prototype.constructor = $.jqplot.BezierAxisRenderer; + + + // Axes on a plot with Bezier Curves + $.jqplot.BezierAxisRenderer.prototype.init = function(options){ + $.extend(true, this, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + var d = s.data; + if (d.length == 4) { + for (var j=0; j<d.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + if (d[j][0] < db.min || db.min == null) { + db.min = d[j][0]; + } + if (d[j][0] > db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + else { + if (this.name == 'xaxis' || this.name == 'x2axis') { + if (d[0][0] < db.min || db.min == null) { + db.min = d[0][0]; + } + if (d[0][0] > db.max || db.max == null) { + db.max = d[0][0]; + } + for (var j=0; j<5; j+=2) { + if (d[1][j] < db.min || db.min == null) { + db.min = d[1][j]; + } + if (d[1][j] > db.max || db.max == null) { + db.max = d[1][j]; + } + } + } + else { + if (d[0][1] < db.min || db.min == null) { + db.min = d[0][1]; + } + if (d[0][1] > db.max || db.max == null) { + db.max = d[0][1]; + } + for (var j=1; j<6; j+=2) { + if (d[1][j] < db.min || db.min == null) { + db.min = d[1][j]; + } + if (d[1][j] > db.max || db.max == null) { + db.max = d[1][j]; + } + } + } + } + } + }; + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = $.extend(true, {pad:0}, options.axesDefaults); + options.seriesDefaults = options.seriesDefaults || {}; + options.legend = $.extend(true, {placement:'outside'}, options.legend); + // only set these if there is a pie series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.BezierCurveRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.BezierCurveRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.BezierAxisRenderer; + } + } + + $.jqplot.preInitHooks.push(preInit); + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.min.js new file mode 100644 index 0000000..fb36057 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.BezierCurveRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(b){b.jqplot.BezierCurveRenderer=function(){b.jqplot.LineRenderer.call(this)};b.jqplot.BezierCurveRenderer.prototype=new b.jqplot.LineRenderer();b.jqplot.BezierCurveRenderer.prototype.constructor=b.jqplot.BezierCurveRenderer;b.jqplot.BezierCurveRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var g=this._yaxis.series_u2p;var f=this.data;this.gridData=[];this._prevGridData=[];var d=this.index;if(f.length==2){if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,f[1][4]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,c[1][4]),g.call(this._yaxis,c[1][5])],[e.call(this._xaxis,c[1][2]),g.call(this._yaxis,c[1][3]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}else{if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,f[3][1]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,c[3][0]),g.call(this._yaxis,c[3][1])],[e.call(this._xaxis,c[2][0]),g.call(this._yaxis,c[2][1]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}};b.jqplot.BezierCurveRenderer.prototype.makeGridData=function(g,i){var f=this._xaxis.series_u2p;var h=this._yaxis.series_u2p;var e=[];var j=[];var d=this.index;if(g.length==2){if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,g[1][4]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,c[1][4]),h.call(this._yaxis,c[1][5])],[f.call(this._xaxis,c[1][2]),h.call(this._yaxis,c[1][3]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}else{if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,g[3][1]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,c[3][0]),h.call(this._yaxis,c[3][1])],[f.call(this._xaxis,c[2][0]),h.call(this._yaxis,c[2][1]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}return e};b.jqplot.BezierCurveRenderer.prototype.draw=function(c,g,d){var e;c.save();if(g.length){if(this.showLine){c.save();var f=(d!=null)?d:{};c.fillStyle=f.fillStyle||this.color;c.beginPath();c.moveTo(g[0][0],g[0][1]);c.bezierCurveTo(g[1][0],g[1][1],g[1][2],g[1][3],g[1][4],g[1][5]);c.lineTo(g[2][0],g[2][1]);if(g[3].length==2){c.lineTo(g[3][0],g[3][1])}else{c.bezierCurveTo(g[3][0],g[3][1],g[3][2],g[3][3],g[3][4],g[3][5])}c.closePath();c.fill();c.restore()}}c.restore()};b.jqplot.BezierCurveRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.BezierAxisRenderer=function(){b.jqplot.LinearAxisRenderer.call(this)};b.jqplot.BezierAxisRenderer.prototype=new b.jqplot.LinearAxisRenderer();b.jqplot.BezierAxisRenderer.prototype.constructor=b.jqplot.BezierAxisRenderer;b.jqplot.BezierAxisRenderer.prototype.init=function(f){b.extend(true,this,f);var c=this._dataBounds;for(var g=0;g<this._series.length;g++){var h=this._series[g];var k=h.data;if(k.length==4){for(var e=0;e<k.length;e++){if(this.name=="xaxis"||this.name=="x2axis"){if(k[e][0]<c.min||c.min==null){c.min=k[e][0]}if(k[e][0]>c.max||c.max==null){c.max=k[e][0]}}else{if(k[e][1]<c.min||c.min==null){c.min=k[e][1]}if(k[e][1]>c.max||c.max==null){c.max=k[e][1]}}}}else{if(this.name=="xaxis"||this.name=="x2axis"){if(k[0][0]<c.min||c.min==null){c.min=k[0][0]}if(k[0][0]>c.max||c.max==null){c.max=k[0][0]}for(var e=0;e<5;e+=2){if(k[1][e]<c.min||c.min==null){c.min=k[1][e]}if(k[1][e]>c.max||c.max==null){c.max=k[1][e]}}}else{if(k[0][1]<c.min||c.min==null){c.min=k[0][1]}if(k[0][1]>c.max||c.max==null){c.max=k[0][1]}for(var e=1;e<6;e+=2){if(k[1][e]<c.min||c.min==null){c.min=k[1][e]}if(k[1][e]>c.max||c.max==null){c.max=k[1][e]}}}}}};function a(g,f,d){d=d||{};d.axesDefaults=b.extend(true,{pad:0},d.axesDefaults);d.seriesDefaults=d.seriesDefaults||{};d.legend=b.extend(true,{placement:"outside"},d.legend);var c=false;if(d.seriesDefaults.renderer==b.jqplot.BezierCurveRenderer){c=true}else{if(d.series){for(var e=0;e<d.series.length;e++){if(d.series[e].renderer==b.jqplot.BezierCurveRenderer){c=true}}}}if(c){d.axesDefaults.renderer=b.jqplot.BezierAxisRenderer}}b.jqplot.preInitHooks.push(a)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.js new file mode 100644 index 0000000..9b714e9 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.js @@ -0,0 +1,801 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + // Class: $.jqplot.BarRenderer + // A plugin renderer for jqPlot to draw a bar plot. + // Draws series as a line. + + $.jqplot.BarRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; + + // called with scope of series. + $.jqplot.BarRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + // prop: barPadding + // Number of pixels between adjacent bars at the same axis value. + this.barPadding = 8; + // prop: barMargin + // Number of pixels between groups of bars at adjacent axis values. + this.barMargin = 10; + // prop: barDirection + // 'vertical' = up and down bars, 'horizontal' = side to side bars + this.barDirection = 'vertical'; + // prop: barWidth + // Width of the bar in pixels (auto by devaul). null = calculated automatically. + this.barWidth = null; + // prop: shadowOffset + // offset of the shadow from the slice and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.08; + // prop: waterfall + // true to enable waterfall plot. + this.waterfall = false; + // prop: groups + // group bars into this many groups + this.groups = 1; + // prop: varyBarColor + // true to color each bar of a series separately rather than + // have every bar of a given series the same color. + // If used for non-stacked multiple series bar plots, user should + // specify a separate 'seriesColors' array for each series. + // Otherwise, each series will set their bars to the same color array. + // This option has no Effect for stacked bar charts and is disabled. + this.varyBarColor = false; + // prop: highlightMouseOver + // True to highlight slice when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a slice. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a slice. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // an array of colors to use when highlighting a bar. + this.highlightColors = []; + // prop: transposedData + // NOT IMPLEMENTED YET. True if this is a horizontal bar plot and + // x and y values are "transposed". Tranposed, or "swapped", data is + // required prior to rev. 894 builds of jqPlot with horizontal bars. + // Allows backward compatability of bar renderer horizontal bars with + // old style data sets. + this.transposedData = true; + this.renderer.animation = { + show: false, + direction: 'down', + speed: 3000, + _supported: true + }; + this._type = 'bar'; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + ////// + // This is probably wrong here. + // After going back and forth on whether renderer should be the thing + // or extend the thing, it seems that it it best if it is a property + // on the thing. This should be something that is commonized + // among series renderers in the future. + ////// + $.extend(true, this, options); + + // really should probably do this + $.extend(true, this.renderer, options); + // fill is still needed to properly draw the legend. + // bars have to be filled. + this.fill = true; + + // if horizontal bar and animating, reset the default direction + if (this.barDirection === 'horizontal' && this.rendererOptions.animation && this.rendererOptions.animation.direction == null) { + this.renderer.animation.direction = 'left'; + } + + if (this.waterfall) { + this.fillToZero = false; + this.disableStack = true; + } + + if (this.barDirection == 'vertical' ) { + this._primaryAxis = '_xaxis'; + this._stackAxis = 'y'; + this.fillAxis = 'y'; + } + else { + this._primaryAxis = '_yaxis'; + this._stackAxis = 'x'; + this.fillAxis = 'x'; + } + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + // total number of values for all bar series, total number of bar series, and position of this series + this._plotSeriesInfo = null; + // Array of actual data colors used for each data point. + this._dataColors = []; + this._barPoints = []; + + // set the shape renderer options + var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; + this.renderer.shapeRenderer.init(opts); + // set the shadow renderer options + var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; + this.renderer.shadowRenderer.init(sopts); + + plot.postInitHooks.addOnce(postInit); + plot.postDrawHooks.addOnce(postPlotDraw); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + }; + + // called with scope of series + function barPreInit(target, data, seriesDefaults, options) { + if (this.rendererOptions.barDirection == 'horizontal') { + this._stackAxis = 'x'; + this._primaryAxis = '_yaxis'; + } + if (this.rendererOptions.waterfall == true) { + this._data = $.extend(true, [], this.data); + var sum = 0; + var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection === 'vertical' || this.transposedData === false) ? 1 : 0; + for(var i=0; i<this.data.length; i++) { + sum += this.data[i][pos]; + if (i>0) { + this.data[i][pos] += this.data[i-1][pos]; + } + } + this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; + this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; + } + if (this.rendererOptions.groups > 1) { + this.breakOnNull = true; + var l = this.data.length; + var skip = parseInt(l/this.rendererOptions.groups, 10); + var count = 0; + for (var i=skip; i<l; i+=skip) { + this.data.splice(i+count, 0, [null, null]); + this._plotData.splice(i+count, 0, [null, null]); + this._stackData.splice(i+count, 0, [null, null]); + count++; + } + for (i=0; i<this.data.length; i++) { + if (this._primaryAxis == '_xaxis') { + this.data[i][0] = i+1; + this._plotData[i][0] = i+1; + this._stackData[i][0] = i+1; + } + else { + this.data[i][1] = i+1; + this._plotData[i][1] = i+1; + this._stackData[i][1] = i+1; + } + } + } + } + + $.jqplot.preSeriesInitHooks.push(barPreInit); + + // needs to be called with scope of series, not renderer. + $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + // loop through all series on this axis + for (var i=0; i < paxis._series.length; i++) { + series = paxis._series[i]; + if (series === this) { + pos = i; + } + // is the series rendered as a bar? + if (series.renderer.constructor == $.jqplot.BarRenderer) { + // gridData may not be computed yet, use data length insted + nvals += series.data.length; + nseries += 1; + } + } + // return total number of values for all bar series, total number of bar series, and position of this series + return [nvals, nseries, pos]; + }; + + $.jqplot.BarRenderer.prototype.setBarWidth = function() { + // need to know how many data values we have on the approprate axis and figure it out. + var i; + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + var nticks = paxis.numberTicks; + var nbins = (nticks-1)/2; + // so, now we have total number of axis values. + if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { + if (this._stack) { + this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; + } + } + else { + if (this._stack) { + this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; + } + else { + this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; + // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; + } + } + return [nvals, nseries]; + }; + + function computeHighlightColors (colors) { + var ret = []; + for (var i=0; i<colors.length; i++){ + var rgba = $.jqplot.getColorComponents(colors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); + } + return ret; + } + + function getStart(sidx, didx, comp, plot, axis) { + // check if sign change + var seriesIndex = sidx, + prevSeriesIndex = sidx - 1, + start, + prevVal, + aidx = (axis === 'x') ? 0 : 1; + + // is this not the first series? + if (seriesIndex > 0) { + prevVal = plot.series[prevSeriesIndex]._plotData[didx][aidx]; + + // is there a sign change + if ((comp * prevVal) < 0) { + start = getStart(prevSeriesIndex, didx, comp, plot, axis); + } + + // no sign change. + else { + start = plot.series[prevSeriesIndex].gridData[didx][aidx]; + } + + } + + // if first series, return value at 0 + else { + + start = (aidx === 0) ? plot.series[seriesIndex]._xaxis.series_u2p(0) : plot.series[seriesIndex]._yaxis.series_u2p(0); + } + + return start; + } + + + $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options, plot) { + var i; + // Ughhh, have to make a copy of options b/c it may be modified later. + var opts = $.extend({}, options); + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy; + // clear out data colors. + this._dataColors = []; + this._barPoints = []; + + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); + var nvals = temp[0]; + var nseries = temp[1]; + var pos = temp[2]; + var points = []; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); + var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); + var negativeColor = negativeColors.get(this.index); + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var positiveColor = opts.fillStyle; + var base; + var xstart; + var ystart; + + if (this.barDirection == 'vertical') { + for (var i=0; i<gridData.length; i++) { + if (!this._stack && this.data[i][1] == null) { + continue; + } + points = []; + base = gridData[i][0] + this._barNudge; + + // stacked + if (this._stack && this._prevGridData.length) { + ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); + } + + // not stacked + else { + if (this.fillToZero) { + ystart = this._yaxis.series_u2p(0); + } + else if (this.waterfall && i > 0 && i < this.gridData.length-1) { + ystart = this.gridData[i-1][1]; + } + else if (this.waterfall && i == 0 && i < this.gridData.length-1) { + if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { + ystart = this._yaxis.series_u2p(0); + } + else if (this._yaxis.min > 0) { + ystart = ctx.canvas.height; + } + else { + ystart = 0; + } + } + else if (this.waterfall && i == this.gridData.length - 1) { + if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { + ystart = this._yaxis.series_u2p(0); + } + else if (this._yaxis.min > 0) { + ystart = ctx.canvas.height; + } + else { + ystart = 0; + } + } + else { + ystart = ctx.canvas.height; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor && !this._stack) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + else { + opts.fillStyle = negativeColor; + } + } + else { + if (this.varyBarColor && !this._stack) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + if (!this.fillToZero || this._plotData[i][1] >= 0) { + points.push([base-this.barWidth/2, ystart]); + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, ystart]); + } + // for negative bars make sure points are always ordered clockwise + else { + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base-this.barWidth/2, ystart]); + points.push([base+this.barWidth/2, ystart]); + points.push([base+this.barWidth/2, gridData[i][1]]); + } + this._barPoints.push(points); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + var sopts = $.extend(true, {}, opts); + // need to get rid of fillStyle on shadow. + delete sopts.fillStyle; + this.renderer.shadowRenderer.draw(ctx, points, sopts); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + + else if (this.barDirection == 'horizontal'){ + for (var i=0; i<gridData.length; i++) { + if (!this._stack && this.data[i][0] == null) { + continue; + } + points = []; + base = gridData[i][1] - this._barNudge; + xstart; + + if (this._stack && this._prevGridData.length) { + xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); + } + // not stacked + else { + if (this.fillToZero) { + xstart = this._xaxis.series_u2p(0); + } + else if (this.waterfall && i > 0 && i < this.gridData.length-1) { + xstart = this.gridData[i-1][0]; + } + else if (this.waterfall && i == 0 && i < this.gridData.length-1) { + if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { + xstart = this._xaxis.series_u2p(0); + } + else if (this._xaxis.min > 0) { + xstart = 0; + } + else { + xstart = 0; + } + } + else if (this.waterfall && i == this.gridData.length - 1) { + if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { + xstart = this._xaxis.series_u2p(0); + } + else if (this._xaxis.min > 0) { + xstart = 0; + } + else { + xstart = ctx.canvas.width; + } + } + else { + xstart = 0; + } + } + if ((this.fillToZero && this._plotData[i][0] < 0) || (this.waterfall && this._data[i][0] < 0)) { + if (this.varyBarColor && !this._stack) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + else { + opts.fillStyle = negativeColor; + } + } + else { + if (this.varyBarColor && !this._stack) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + + if (!this.fillToZero || this._plotData[i][0] >= 0) { + points.push([xstart, base + this.barWidth / 2]); + points.push([xstart, base - this.barWidth / 2]); + points.push([gridData[i][0], base - this.barWidth / 2]); + points.push([gridData[i][0], base + this.barWidth / 2]); + } + else { + points.push([gridData[i][0], base + this.barWidth / 2]); + points.push([gridData[i][0], base - this.barWidth / 2]); + points.push([xstart, base - this.barWidth / 2]); + points.push([xstart, base + this.barWidth / 2]); + } + + this._barPoints.push(points); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + var sopts = $.extend(true, {}, opts); + delete sopts.fillStyle; + this.renderer.shadowRenderer.draw(ctx, points, sopts); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + } + + if (this.highlightColors.length == 0) { + this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors); + } + + else if (typeof(this.highlightColors) == 'string') { + var temp = this.highlightColors; + this.highlightColors = []; + for (var i=0; i<this._dataColors.length; i++) { + this.highlightColors.push(temp); + } + } + + }; + + + // for stacked plots, shadows will be pre drawn by drawShadow. + $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options, plot) { + var i; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, points, pointy, nvals, nseries, pos; + + if (this._stack && this.shadow) { + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); + nvals = temp[0]; + nseries = temp[1]; + pos = temp[2]; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + + if (this.barDirection == 'vertical') { + for (var i=0; i<gridData.length; i++) { + if (this.data[i][1] == null) { + continue; + } + points = []; + var base = gridData[i][0] + this._barNudge; + var ystart; + + if (this._stack && this._prevGridData.length) { + ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); + } + else { + if (this.fillToZero) { + ystart = this._yaxis.series_u2p(0); + } + else { + ystart = ctx.canvas.height; + } + } + + points.push([base-this.barWidth/2, ystart]); + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, ystart]); + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + } + + else if (this.barDirection == 'horizontal'){ + for (var i=0; i<gridData.length; i++) { + if (this.data[i][0] == null) { + continue; + } + points = []; + var base = gridData[i][1] - this._barNudge; + var xstart; + + if (this._stack && this._prevGridData.length) { + xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); + } + else { + if (this.fillToZero) { + xstart = this._xaxis.series_u2p(0); + } + else { + xstart = 0; + } + } + + points.push([xstart, base+this.barWidth/2]); + points.push([gridData[i][0], base+this.barWidth/2]); + points.push([gridData[i][0], base-this.barWidth/2]); + points.push([xstart, base-this.barWidth/2]); + this.renderer.shadowRenderer.draw(ctx, points, opts); + } + } + } + + } + }; + + function postInit(target, data, options) { + for (var i=0; i<this.series.length; i++) { + if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) { + // don't allow mouseover and mousedown at same time. + if (this.series[i].highlightMouseOver) { + this.series[i].highlightMouseDown = false; + } + } + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.barRenderer && this.plugins.barRenderer.highlightCanvas) { + + this.plugins.barRenderer.highlightCanvas.resetCanvas(); + this.plugins.barRenderer.highlightCanvas = null; + } + + this.plugins.barRenderer = {highlightedSeriesIndex:null}; + this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this)); + this.plugins.barRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + function highlight (plot, sidx, pidx, points) { + var s = plot.series[sidx]; + var canvas = plot.plugins.barRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.barRenderer.highlightedSeriesIndex = sidx; + var opts = {fillStyle: s.highlightColors[pidx]}; + s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); + canvas = null; + } + + function unhighlight (plot) { + var canvas = plot.plugins.barRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.barRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + canvas = null; + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].show && plot.series[ins[0]].highlightMouseOver && + !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.barRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var idx = plot.plugins.barRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.min.js new file mode 100644 index 0000000..6f95500 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.barRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(d){d.jqplot.BarRenderer=function(){d.jqplot.LineRenderer.call(this)};d.jqplot.BarRenderer.prototype=new d.jqplot.LineRenderer();d.jqplot.BarRenderer.prototype.constructor=d.jqplot.BarRenderer;d.jqplot.BarRenderer.prototype.init=function(o,q){this.barPadding=8;this.barMargin=10;this.barDirection="vertical";this.barWidth=null;this.shadowOffset=2;this.shadowDepth=5;this.shadowAlpha=0.08;this.waterfall=false;this.groups=1;this.varyBarColor=false;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.transposedData=true;this.renderer.animation={show:false,direction:"down",speed:3000,_supported:true};this._type="bar";if(o.highlightMouseDown&&o.highlightMouseOver==null){o.highlightMouseOver=false}d.extend(true,this,o);d.extend(true,this.renderer,o);this.fill=true;if(this.barDirection==="horizontal"&&this.rendererOptions.animation&&this.rendererOptions.animation.direction==null){this.renderer.animation.direction="left"}if(this.waterfall){this.fillToZero=false;this.disableStack=true}if(this.barDirection=="vertical"){this._primaryAxis="_xaxis";this._stackAxis="y";this.fillAxis="y"}else{this._primaryAxis="_yaxis";this._stackAxis="x";this.fillAxis="x"}this._highlightedPoint=null;this._plotSeriesInfo=null;this._dataColors=[];this._barPoints=[];var p={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill};this.renderer.shapeRenderer.init(p);var n={lineJoin:"miter",lineCap:"round",fill:true,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill};this.renderer.shadowRenderer.init(n);q.postInitHooks.addOnce(h);q.postDrawHooks.addOnce(j);q.eventListenerHooks.addOnce("jqplotMouseMove",b);q.eventListenerHooks.addOnce("jqplotMouseDown",a);q.eventListenerHooks.addOnce("jqplotMouseUp",l);q.eventListenerHooks.addOnce("jqplotClick",e);q.eventListenerHooks.addOnce("jqplotRightClick",m)};function g(t,p,o,w){if(this.rendererOptions.barDirection=="horizontal"){this._stackAxis="x";this._primaryAxis="_yaxis"}if(this.rendererOptions.waterfall==true){this._data=d.extend(true,[],this.data);var s=0;var u=(!this.rendererOptions.barDirection||this.rendererOptions.barDirection==="vertical"||this.transposedData===false)?1:0;for(var q=0;q<this.data.length;q++){s+=this.data[q][u];if(q>0){this.data[q][u]+=this.data[q-1][u]}}this.data[this.data.length]=(u==1)?[this.data.length+1,s]:[s,this.data.length+1];this._data[this._data.length]=(u==1)?[this._data.length+1,s]:[s,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var n=this.data.length;var v=parseInt(n/this.rendererOptions.groups,10);var r=0;for(var q=v;q<n;q+=v){this.data.splice(q+r,0,[null,null]);this._plotData.splice(q+r,0,[null,null]);this._stackData.splice(q+r,0,[null,null]);r++}for(q=0;q<this.data.length;q++){if(this._primaryAxis=="_xaxis"){this.data[q][0]=q+1;this._plotData[q][0]=q+1;this._stackData[q][0]=q+1}else{this.data[q][1]=q+1;this._plotData[q][1]=q+1;this._stackData[q][1]=q+1}}}}d.jqplot.preSeriesInitHooks.push(g);d.jqplot.BarRenderer.prototype.calcSeriesNumbers=function(){var r=0;var t=0;var q=this[this._primaryAxis];var p,o,u;for(var n=0;n<q._series.length;n++){o=q._series[n];if(o===this){u=n}if(o.renderer.constructor==d.jqplot.BarRenderer){r+=o.data.length;t+=1}}return[r,t,u]};d.jqplot.BarRenderer.prototype.setBarWidth=function(){var q;var n=0;var o=0;var t=this[this._primaryAxis];var x,r,v;var w=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);n=w[0];o=w[1];var u=t.numberTicks;var p=(u-1)/2;if(t.name=="xaxis"||t.name=="x2axis"){if(this._stack){this.barWidth=(t._offsets.max-t._offsets.min)/n*o-this.barMargin}else{this.barWidth=((t._offsets.max-t._offsets.min)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}else{if(this._stack){this.barWidth=(t._offsets.min-t._offsets.max)/n*o-this.barMargin}else{this.barWidth=((t._offsets.min-t._offsets.max)/p-this.barPadding*(o-1)-this.barMargin*2)/o}}return[n,o]};function f(o){var q=[];for(var s=0;s<o.length;s++){var r=d.jqplot.getColorComponents(o[s]);var n=[r[0],r[1],r[2]];var t=n[0]+n[1]+n[2];for(var p=0;p<3;p++){n[p]=(t>570)?n[p]*0.8:n[p]+0.3*(255-n[p]);n[p]=parseInt(n[p],10)}q.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}return q}function i(v,u,s,t,o){var q=v,w=v-1,n,p,r=(o==="x")?0:1;if(q>0){p=t.series[w]._plotData[u][r];if((s*p)<0){n=i(w,u,s,t,o)}else{n=t.series[w].gridData[u][r]}}else{n=(r===0)?t.series[q]._xaxis.series_u2p(0):t.series[q]._yaxis.series_u2p(0)}return n}d.jqplot.BarRenderer.prototype.draw=function(E,L,q,G){var I;var A=d.extend({},q);var w=(A.shadow!=undefined)?A.shadow:this.shadow;var O=(A.showLine!=undefined)?A.showLine:this.showLine;var F=(A.fill!=undefined)?A.fill:this.fill;var p=this.xaxis;var J=this.yaxis;var y=this._xaxis.series_u2p;var K=this._yaxis.series_u2p;var D,C;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var N=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var x=N[0];var v=N[1];var s=N[2];var H=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+s)*(this.barWidth+this.barPadding)}if(O){var u=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var B=new d.jqplot.ColorGenerator(this.seriesColors);var M=u.get(this.index);if(!this.useNegativeColors){M=A.fillStyle}var t=A.fillStyle;var r;var P;var o;if(this.barDirection=="vertical"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][1]==null){continue}H=[];r=L[I][0]+this._barNudge;if(this._stack&&this._prevGridData.length){o=i(this.index,I,this._plotData[I][1],G,"y")}else{if(this.fillToZero){o=this._yaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){o=this.gridData[I-1][1]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){o=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){o=E.canvas.height}else{o=0}}}else{o=E.canvas.height}}}}}if((this.fillToZero&&this._plotData[I][1]<0)||(this.waterfall&&this._data[I][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][1]>=0){H.push([r-this.barWidth/2,o]);H.push([r-this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,L[I][1]]);H.push([r+this.barWidth/2,o])}else{H.push([r-this.barWidth/2,L[I][1]]);H.push([r-this.barWidth/2,o]);H.push([r+this.barWidth/2,o]);H.push([r+this.barWidth/2,L[I][1]])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}else{if(this.barDirection=="horizontal"){for(var I=0;I<L.length;I++){if(!this._stack&&this.data[I][0]==null){continue}H=[];r=L[I][1]-this._barNudge;P;if(this._stack&&this._prevGridData.length){P=i(this.index,I,this._plotData[I][0],G,"x")}else{if(this.fillToZero){P=this._xaxis.series_u2p(0)}else{if(this.waterfall&&I>0&&I<this.gridData.length-1){P=this.gridData[I-1][0]}else{if(this.waterfall&&I==0&&I<this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=0}}}else{if(this.waterfall&&I==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){P=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){P=0}else{P=E.canvas.width}}}else{P=0}}}}}if((this.fillToZero&&this._plotData[I][0]<0)||(this.waterfall&&this._data[I][0]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){A.fillStyle=u.next()}else{A.fillStyle=B.next()}}else{A.fillStyle=M}}else{if(this.varyBarColor&&!this._stack){A.fillStyle=B.next()}else{A.fillStyle=t}}if(!this.fillToZero||this._plotData[I][0]>=0){H.push([P,r+this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([L[I][0],r+this.barWidth/2])}else{H.push([L[I][0],r+this.barWidth/2]);H.push([L[I][0],r-this.barWidth/2]);H.push([P,r-this.barWidth/2]);H.push([P,r+this.barWidth/2])}this._barPoints.push(H);if(w&&!this._stack){var z=d.extend(true,{},A);delete z.fillStyle;this.renderer.shadowRenderer.draw(E,H,z)}var n=A.fillStyle||this.color;this._dataColors.push(n);this.renderer.shapeRenderer.draw(E,H,A)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var N=this.highlightColors;this.highlightColors=[];for(var I=0;I<this._dataColors.length;I++){this.highlightColors.push(N)}}}};d.jqplot.BarRenderer.prototype.drawShadow=function(z,G,p,B){var D;var w=(p!=undefined)?p:{};var t=(w.shadow!=undefined)?w.shadow:this.shadow;var I=(w.showLine!=undefined)?w.showLine:this.showLine;var A=(w.fill!=undefined)?w.fill:this.fill;var o=this.xaxis;var E=this.yaxis;var v=this._xaxis.series_u2p;var F=this._yaxis.series_u2p;var y,C,x,u,s,r;if(this._stack&&this.shadow){if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var H=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);u=H[0];s=H[1];r=H[2];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(s/2-0.5)+r)*(this.barWidth+this.barPadding)}if(I){if(this.barDirection=="vertical"){for(var D=0;D<G.length;D++){if(this.data[D][1]==null){continue}C=[];var q=G[D][0]+this._barNudge;var n;if(this._stack&&this._prevGridData.length){n=i(this.index,D,this._plotData[D][1],B,"y")}else{if(this.fillToZero){n=this._yaxis.series_u2p(0)}else{n=z.canvas.height}}C.push([q-this.barWidth/2,n]);C.push([q-this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,G[D][1]]);C.push([q+this.barWidth/2,n]);this.renderer.shadowRenderer.draw(z,C,w)}}else{if(this.barDirection=="horizontal"){for(var D=0;D<G.length;D++){if(this.data[D][0]==null){continue}C=[];var q=G[D][1]-this._barNudge;var J;if(this._stack&&this._prevGridData.length){J=i(this.index,D,this._plotData[D][0],B,"x")}else{if(this.fillToZero){J=this._xaxis.series_u2p(0)}else{J=0}}C.push([J,q+this.barWidth/2]);C.push([G[D][0],q+this.barWidth/2]);C.push([G[D][0],q-this.barWidth/2]);C.push([J,q-this.barWidth/2]);this.renderer.shadowRenderer.draw(z,C,w)}}}}}};function h(q,p,n){for(var o=0;o<this.series.length;o++){if(this.series[o].renderer.constructor==d.jqplot.BarRenderer){if(this.series[o].highlightMouseOver){this.series[o].highlightMouseDown=false}}}}function j(){if(this.plugins.barRenderer&&this.plugins.barRenderer.highlightCanvas){this.plugins.barRenderer.highlightCanvas.resetCanvas();this.plugins.barRenderer.highlightCanvas=null}this.plugins.barRenderer={highlightedSeriesIndex:null};this.plugins.barRenderer.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-barRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.barRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(n){k(n.data.plot)})}function c(u,t,q,p){var o=u.series[t];var n=u.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);o._highlightedPoint=q;u.plugins.barRenderer.highlightedSeriesIndex=t;var r={fillStyle:o.highlightColors[q]};o.renderer.shapeRenderer.draw(n._ctx,p,r);n=null}function k(p){var n=p.plugins.barRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);for(var o=0;o<p.series.length;o++){p.series[o]._highlightedPoint=null}p.plugins.barRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight");n=null}function b(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataMouseOver");o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);if(s.series[p[0]].show&&s.series[p[0]].highlightMouseOver&&!(p[0]==s.plugins.barRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=r.which;n.pageX=r.pageX;n.pageY=r.pageY;s.target.trigger(n,p);c(s,t.seriesIndex,t.pointIndex,t.points)}}else{if(t==null){k(s)}}}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];if(r.series[o[0]].highlightMouseDown&&!(o[0]==r.plugins.barRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);c(r,s.seriesIndex,s.pointIndex,s.points)}}else{if(s==null){k(r)}}}function l(p,o,s,r,q){var n=q.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&q.series[n].highlightMouseDown){k(q)}}function e(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function m(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var n=s.plugins.barRenderer.highlightedSeriesIndex;if(n!=null&&s.series[n].highlightMouseDown){k(s)}var o=jQuery.Event("jqplotDataRightClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.js new file mode 100644 index 0000000..e7c782c --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.js @@ -0,0 +1,235 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.BlockRenderer + * Plugin renderer to draw a x-y block chart. A Block chart has data points displayed as + * colored squares with a text label inside. Data must be supplied in the form: + * + * > [[x1, y1, "label 1", {css}], [x2, y2, "label 2", {css}], ...] + * + * The label and css object are optional. If the label is ommitted, the + * box will collapse unless a css height and/or width is specified. + * + * The css object is an object specifying css properties + * such as: + * + * > {background:'#4f98a5', border:'3px solid gray', padding:'1px'} + * + * Note that css properties specified with the data point override defaults + * specified with the series. + * + */ + $.jqplot.BlockRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BlockRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BlockRenderer.prototype.constructor = $.jqplot.BlockRenderer; + + // called with scope of a series + $.jqplot.BlockRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: css + // default css styles that will be applied to all data blocks. + // these values will be overridden by css styles supplied with the + // individulal data points. + this.css = {padding:'2px', border:'1px solid #999', textAlign:'center'}; + // prop: escapeHtml + // true to escape html in the box label. + this.escapeHtml = false; + // prop: insertBreaks + // true to turn spaces in data block label into html breaks <br />. + this.insertBreaks = true; + // prop: varyBlockColors + // true to vary the color of each block in this series according to + // the seriesColors array. False to set each block to the color + // specified on this series. This has no effect if a css background color + // option is specified in the renderer css options. + this.varyBlockColors = false; + $.extend(true, this, options); + if (this.css.backgroundColor) { + this.color = this.css.backgroundColor; + } + else if (this.css.background) { + this.color = this.css.background; + } + else if (!this.varyBlockColors) { + this.css.background = this.color; + } + this.canvas = new $.jqplot.BlockCanvas(); + this.shadowCanvas = new $.jqplot.BlockCanvas(); + this.canvas._plotDimensions = this._plotDimensions; + this.shadowCanvas._plotDimensions = this._plotDimensions; + this._type = 'block'; + + // group: Methods + // + // Method: moveBlock + // Moves an individual block. More efficient than redrawing + // the whole series by calling plot.drawSeries(). + // Properties: + // idx - the 0 based index of the block or point in this series. + // x - the x coordinate in data units (value on x axis) to move the block to. + // y - the y coordinate in data units (value on the y axis) to move the block to. + // duration - optional parameter to create an animated movement. Can be a + // number (higher is slower animation) or 'fast', 'normal' or 'slow'. If not + // provided, the element is moved without any animation. + this.moveBlock = function (idx, x, y, duration) { + // update plotData, stackData, data and gridData + // x and y are in data coordinates. + var el = this.canvas._elem.children(':eq('+idx+')'); + this.data[idx][0] = x; + this.data[idx][1] = y; + this._plotData[idx][0] = x; + this._plotData[idx][1] = y; + this._stackData[idx][0] = x; + this._stackData[idx][1] = y; + this.gridData[idx][0] = this._xaxis.series_u2p(x); + this.gridData[idx][1] = this._yaxis.series_u2p(y); + var w = el.outerWidth(); + var h = el.outerHeight(); + var left = this.gridData[idx][0] - w/2 + 'px'; + var top = this.gridData[idx][1] - h/2 + 'px'; + if (duration) { + if (parseInt(duration, 10)) { + duration = parseInt(duration, 10); + } + el.animate({left:left, top:top}, duration); + } + else { + el.css({left:left, top:top}); + } + el = null; + }; + }; + + // called with scope of series + $.jqplot.BlockRenderer.prototype.draw = function (ctx, gd, options) { + if (this.plugins.pointLabels) { + this.plugins.pointLabels.show = false; + } + var i, el, d, gd, t, css, w, h, left, top; + var opts = (options != undefined) ? options : {}; + var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); + this.canvas._elem.empty(); + for (i=0; i<this.gridData.length; i++) { + d = this.data[i]; + gd = this.gridData[i]; + t = ''; + css = {}; + if (typeof d[2] == 'string') { + t = d[2]; + } + else if (typeof d[2] == 'object') { + css = d[2]; + } + if (typeof d[3] == 'object') { + css = d[3]; + } + if (this.insertBreaks){ + t = t.replace(/ /g, '<br />'); + } + css = $.extend(true, {}, this.css, css); + // create a div + el = $('<div style="position:absolute;margin-left:auto;margin-right:auto;"></div>'); + this.canvas._elem.append(el); + // set text + this.escapeHtml ? el.text(t) : el.html(t); + // style it + // remove styles we don't want overridden. + delete css.position; + delete css.marginRight; + delete css.marginLeft; + if (!css.background && !css.backgroundColor && !css.backgroundImage){ + css.background = colorGenerator.next(); + } + el.css(css); + w = el.outerWidth(); + h = el.outerHeight(); + left = gd[0] - w/2 + 'px'; + top = gd[1] - h/2 + 'px'; + el.css({left:left, top:top}); + el = null; + } + }; + + $.jqplot.BlockCanvas = function() { + $.jqplot.ElemContainer.call(this); + this._ctx; + }; + + $.jqplot.BlockCanvas.prototype = new $.jqplot.ElemContainer(); + $.jqplot.BlockCanvas.prototype.constructor = $.jqplot.BlockCanvas; + + $.jqplot.BlockCanvas.prototype.createElement = function(offsets, clss, plotDimensions) { + this._offsets = offsets; + var klass = 'jqplot-blockCanvas'; + if (clss != undefined) { + klass = clss; + } + var elem; + // if this canvas already has a dom element, don't make a new one. + if (this._elem) { + elem = this._elem.get(0); + } + else { + elem = document.createElement('div'); + } + // if new plotDimensions supplied, use them. + if (plotDimensions != undefined) { + this._plotDimensions = plotDimensions; + } + + var w = this._plotDimensions.width - this._offsets.left - this._offsets.right + 'px'; + var h = this._plotDimensions.height - this._offsets.top - this._offsets.bottom + 'px'; + this._elem = $(elem); + this._elem.css({ position: 'absolute', width:w, height:h, left: this._offsets.left, top: this._offsets.top }); + + this._elem.addClass(klass); + return this._elem; + }; + + $.jqplot.BlockCanvas.prototype.setContext = function() { + this._ctx = { + canvas:{ + width:0, + height:0 + }, + clearRect:function(){return null;} + }; + return this._ctx; + }; + +})(jQuery); + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.min.js new file mode 100644 index 0000000..4a01440 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.blockRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.BlockRenderer=function(){a.jqplot.LineRenderer.call(this)};a.jqplot.BlockRenderer.prototype=new a.jqplot.LineRenderer();a.jqplot.BlockRenderer.prototype.constructor=a.jqplot.BlockRenderer;a.jqplot.BlockRenderer.prototype.init=function(b){this.css={padding:"2px",border:"1px solid #999",textAlign:"center"};this.escapeHtml=false;this.insertBreaks=true;this.varyBlockColors=false;a.extend(true,this,b);if(this.css.backgroundColor){this.color=this.css.backgroundColor}else{if(this.css.background){this.color=this.css.background}else{if(!this.varyBlockColors){this.css.background=this.color}}}this.canvas=new a.jqplot.BlockCanvas();this.shadowCanvas=new a.jqplot.BlockCanvas();this.canvas._plotDimensions=this._plotDimensions;this.shadowCanvas._plotDimensions=this._plotDimensions;this._type="block";this.moveBlock=function(l,j,i,e){var c=this.canvas._elem.children(":eq("+l+")");this.data[l][0]=j;this.data[l][1]=i;this._plotData[l][0]=j;this._plotData[l][1]=i;this._stackData[l][0]=j;this._stackData[l][1]=i;this.gridData[l][0]=this._xaxis.series_u2p(j);this.gridData[l][1]=this._yaxis.series_u2p(i);var k=c.outerWidth();var f=c.outerHeight();var d=this.gridData[l][0]-k/2+"px";var g=this.gridData[l][1]-f/2+"px";if(e){if(parseInt(e,10)){e=parseInt(e,10)}c.animate({left:d,top:g},e)}else{c.css({left:d,top:g})}c=null}};a.jqplot.BlockRenderer.prototype.draw=function(q,o,r){if(this.plugins.pointLabels){this.plugins.pointLabels.show=false}var f,c,l,o,p,k,n,g,e,m;var b=(r!=undefined)?r:{};var j=new a.jqplot.ColorGenerator(this.seriesColors);this.canvas._elem.empty();for(f=0;f<this.gridData.length;f++){l=this.data[f];o=this.gridData[f];p="";k={};if(typeof l[2]=="string"){p=l[2]}else{if(typeof l[2]=="object"){k=l[2]}}if(typeof l[3]=="object"){k=l[3]}if(this.insertBreaks){p=p.replace(/ /g,"<br />")}k=a.extend(true,{},this.css,k);c=a('<div style="position:absolute;margin-left:auto;margin-right:auto;"></div>');this.canvas._elem.append(c);this.escapeHtml?c.text(p):c.html(p);delete k.position;delete k.marginRight;delete k.marginLeft;if(!k.background&&!k.backgroundColor&&!k.backgroundImage){k.background=j.next()}c.css(k);n=c.outerWidth();g=c.outerHeight();e=o[0]-n/2+"px";m=o[1]-g/2+"px";c.css({left:e,top:m});c=null}};a.jqplot.BlockCanvas=function(){a.jqplot.ElemContainer.call(this);this._ctx};a.jqplot.BlockCanvas.prototype=new a.jqplot.ElemContainer();a.jqplot.BlockCanvas.prototype.constructor=a.jqplot.BlockCanvas;a.jqplot.BlockCanvas.prototype.createElement=function(i,e,c){this._offsets=i;var b="jqplot-blockCanvas";if(e!=undefined){b=e}var g;if(this._elem){g=this._elem.get(0)}else{g=document.createElement("div")}if(c!=undefined){this._plotDimensions=c}var d=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var f=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=a(g);this._elem.css({position:"absolute",width:d,height:f,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(b);return this._elem};a.jqplot.BlockCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.js new file mode 100644 index 0000000..1629d85 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.js @@ -0,0 +1,759 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + var arrayMax = function( array ){ + return Math.max.apply( Math, array ); + }; + var arrayMin = function( array ){ + return Math.min.apply( Math, array ); + }; + + /** + * Class: $.jqplot.BubbleRenderer + * Plugin renderer to draw a bubble chart. A Bubble chart has data points displayed as + * colored circles with an optional text label inside. To use + * the bubble renderer, you must include the bubble renderer like: + * + * > <script language="javascript" type="text/javascript" src="../src/plugins/jqplot.bubbleRenderer.js"></script> + * + * Data must be supplied in + * the form: + * + * > [[x1, y1, r1, <label or {label:'text', color:color}>], ...] + * + * where the label or options + * object is optional. + * + * Note that all bubble colors will be the same + * unless the "varyBubbleColors" option is set to true. Colors can be specified in the data array + * or in the seriesColors array option on the series. If no colors are defined, the default jqPlot + * series of 16 colors are used. Colors are automatically cycled around again if there are more + * bubbles than colors. + * + * Bubbles are autoscaled by default to fit within the chart area while maintaining + * relative sizes. If the "autoscaleBubbles" option is set to false, the r(adius) values + * in the data array a treated as literal pixel values for the radii of the bubbles. + * + * Properties are passed into the bubble renderer in the rendererOptions object of + * the series options like: + * + * > seriesDefaults: { + * > renderer: $.jqplot.BubbleRenderer, + * > rendererOptions: { + * > bubbleAlpha: 0.7, + * > varyBubbleColors: false + * > } + * > } + * + */ + $.jqplot.BubbleRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BubbleRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BubbleRenderer.prototype.constructor = $.jqplot.BubbleRenderer; + + // called with scope of a series + $.jqplot.BubbleRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + // prop: varyBubbleColors + // True to vary the color of each bubble in this series according to + // the seriesColors array. False to set each bubble to the color + // specified on this series. This has no effect if a css background color + // option is specified in the renderer css options. + this.varyBubbleColors = true; + // prop: autoscaleBubbles + // True to scale the bubble radius based on plot size. + // False will use the radius value as provided as a raw pixel value for + // bubble radius. + this.autoscaleBubbles = true; + // prop: autoscaleMultiplier + // Multiplier the bubble size if autoscaleBubbles is true. + this.autoscaleMultiplier = 1.0; + // prop: autoscalePointsFactor + // Factor which decreases bubble size based on how many bubbles on on the chart. + // 0 means no adjustment for number of bubbles. Negative values will decrease + // size of bubbles as more bubbles are added. Values between 0 and -0.2 + // should work well. + this.autoscalePointsFactor = -0.07; + // prop: escapeHtml + // True to escape html in bubble label text. + this.escapeHtml = true; + // prop: highlightMouseOver + // True to highlight bubbles when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a slice. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a bubble. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // An array of colors to use when highlighting a slice. Calculated automatically + // if not supplied. + this.highlightColors = []; + // prop: bubbleAlpha + // Alpha transparency to apply to all bubbles in this series. + this.bubbleAlpha = 1.0; + // prop: highlightAlpha + // Alpha transparency to apply when highlighting bubble. + // Set to value of bubbleAlpha by default. + this.highlightAlpha = null; + // prop: bubbleGradients + // True to color the bubbles with gradient fills instead of flat colors. + // NOT AVAILABLE IN IE due to lack of excanvas support for radial gradient fills. + // will be ignored in IE. + this.bubbleGradients = false; + // prop: showLabels + // True to show labels on bubbles (if any), false to not show. + this.showLabels = true; + // array of [point index, radius] which will be sorted in descending order to plot + // largest points below smaller points. + this.radii = []; + this.maxRadius = 0; + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + // array of jQuery labels. + this.labels = []; + this.bubbleCanvases = []; + this._type = 'bubble'; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + $.extend(true, this, options); + + if (this.highlightAlpha == null) { + this.highlightAlpha = this.bubbleAlpha; + if (this.bubbleGradients) { + this.highlightAlpha = 0.35; + } + } + + this.autoscaleMultiplier = this.autoscaleMultiplier * Math.pow(this.data.length, this.autoscalePointsFactor); + + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + + // adjust the series colors for options colors passed in with data or for alpha. + // note, this can leave undefined holes in the seriesColors array. + var comps; + for (var i=0; i<this.data.length; i++) { + var color = null; + var d = this.data[i]; + this.maxRadius = Math.max(this.maxRadius, d[2]); + if (d[3]) { + if (typeof(d[3]) == 'object') { + color = d[3]['color']; + } + } + + if (color == null) { + if (this.seriesColors[i] != null) { + color = this.seriesColors[i]; + } + } + + if (color && this.bubbleAlpha < 1.0) { + comps = $.jqplot.getColorComponents(color); + color = 'rgba('+comps[0]+', '+comps[1]+', '+comps[2]+', '+this.bubbleAlpha+')'; + } + + if (color) { + this.seriesColors[i] = color; + } + } + + if (!this.varyBubbleColors) { + this.seriesColors = [this.color]; + } + + this.colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); + + // set highlight colors if none provided + if (this.highlightColors.length == 0) { + for (var i=0; i<this.seriesColors.length; i++){ + var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + this.highlightColors.push('rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+', '+this.highlightAlpha+')'); + } + } + + this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors); + + var sopts = {fill:true, isarc:true, angle:this.shadowAngle, alpha:this.shadowAlpha, closePath:true}; + + this.renderer.shadowRenderer.init(sopts); + + this.canvas = new $.jqplot.DivCanvas(); + this.canvas._plotDimensions = this._plotDimensions; + + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + plot.postDrawHooks.addOnce(postPlotDraw); + + }; + + + // converts the user data values to grid coordinates and stores them + // in the gridData array. + // Called with scope of a series. + $.jqplot.BubbleRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var data = this._plotData; + this.gridData = []; + var radii = []; + this.radii = []; + var dim = Math.min(plot._height, plot._width); + for (var i=0; i<this.data.length; i++) { + if (data[i] != null) { + this.gridData.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1]), data[i][2]]); + this.radii.push([i, data[i][2]]); + radii.push(data[i][2]); + } + } + var r, val, maxr = this.maxRadius = arrayMax(radii); + var l = this.gridData.length; + if (this.autoscaleBubbles) { + for (var i=0; i<l; i++) { + val = radii[i]/maxr; + r = this.autoscaleMultiplier * dim / 6; + this.gridData[i][2] = r * val; + } + } + + this.radii.sort(function(a, b) { return b[1] - a[1]; }); + }; + + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.BubbleRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var gd = []; + var radii = []; + this.radii = []; + var dim = Math.min(plot._height, plot._width); + for (var i=0; i<data.length; i++) { + if (data[i] != null) { + gd.push([xp.call(this._xaxis, data[i][0]), yp.call(this._yaxis, data[i][1]), data[i][2]]); + radii.push(data[i][2]); + this.radii.push([i, data[i][2]]); + } + } + var r, val, maxr = this.maxRadius = arrayMax(radii); + var l = this.gridData.length; + if (this.autoscaleBubbles) { + for (var i=0; i<l; i++) { + val = radii[i]/maxr; + r = this.autoscaleMultiplier * dim / 6; + gd[i][2] = r * val; + } + } + this.radii.sort(function(a, b) { return b[1] - a[1]; }); + return gd; + }; + + // called with scope of series + $.jqplot.BubbleRenderer.prototype.draw = function (ctx, gd, options) { + if (this.plugins.pointLabels) { + this.plugins.pointLabels.show = false; + } + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + this.canvas._elem.empty(); + for (var i=0; i<this.radii.length; i++) { + var idx = this.radii[i][0]; + var t=null; + var color = null; + var el = null; + var tel = null; + var d = this.data[idx]; + var gd = this.gridData[idx]; + if (d[3]) { + if (typeof(d[3]) == 'object') { + t = d[3]['label']; + } + else if (typeof(d[3]) == 'string') { + t = d[3]; + } + } + + // color = (this.varyBubbleColors) ? this.colorGenerator.get(idx) : this.color; + color = this.colorGenerator.get(idx); + + // If we're drawing a shadow, expand the canvas dimensions to accomodate. + var canvasRadius = gd[2]; + var offset, depth; + if (this.shadow) { + offset = (0.7 + gd[2]/40).toFixed(1); + depth = 1 + Math.ceil(gd[2]/15); + canvasRadius += offset*depth; + } + this.bubbleCanvases[idx] = new $.jqplot.BubbleCanvas(); + this.canvas._elem.append(this.bubbleCanvases[idx].createElement(gd[0], gd[1], canvasRadius)); + this.bubbleCanvases[idx].setContext(); + var ctx = this.bubbleCanvases[idx]._ctx; + var x = ctx.canvas.width/2; + var y = ctx.canvas.height/2; + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [x, y, gd[2], 0, 2*Math.PI], {offset: offset, depth: depth}); + } + this.bubbleCanvases[idx].draw(gd[2], color, this.bubbleGradients, this.shadowAngle/180*Math.PI); + + // now draw label. + if (t && this.showLabels) { + tel = $('<div style="position:absolute;" class="jqplot-bubble-label"></div>'); + if (this.escapeHtml) { + tel.text(t); + } + else { + tel.html(t); + } + this.canvas._elem.append(tel); + var h = $(tel).outerHeight(); + var w = $(tel).outerWidth(); + var top = gd[1] - 0.5*h; + var left = gd[0] - 0.5*w; + tel.css({top: top, left: left}); + this.labels[idx] = $(tel); + } + } + }; + + + $.jqplot.DivCanvas = function() { + $.jqplot.ElemContainer.call(this); + this._ctx; + }; + + $.jqplot.DivCanvas.prototype = new $.jqplot.ElemContainer(); + $.jqplot.DivCanvas.prototype.constructor = $.jqplot.DivCanvas; + + $.jqplot.DivCanvas.prototype.createElement = function(offsets, clss, plotDimensions) { + this._offsets = offsets; + var klass = 'jqplot-DivCanvas'; + if (clss != undefined) { + klass = clss; + } + var elem; + // if this canvas already has a dom element, don't make a new one. + if (this._elem) { + elem = this._elem.get(0); + } + else { + elem = document.createElement('div'); + } + // if new plotDimensions supplied, use them. + if (plotDimensions != undefined) { + this._plotDimensions = plotDimensions; + } + + var w = this._plotDimensions.width - this._offsets.left - this._offsets.right + 'px'; + var h = this._plotDimensions.height - this._offsets.top - this._offsets.bottom + 'px'; + this._elem = $(elem); + this._elem.css({ position: 'absolute', width:w, height:h, left: this._offsets.left, top: this._offsets.top }); + + this._elem.addClass(klass); + return this._elem; + }; + + $.jqplot.DivCanvas.prototype.setContext = function() { + this._ctx = { + canvas:{ + width:0, + height:0 + }, + clearRect:function(){return null;} + }; + return this._ctx; + }; + + $.jqplot.BubbleCanvas = function() { + $.jqplot.ElemContainer.call(this); + this._ctx; + }; + + $.jqplot.BubbleCanvas.prototype = new $.jqplot.ElemContainer(); + $.jqplot.BubbleCanvas.prototype.constructor = $.jqplot.BubbleCanvas; + + // initialize with the x,y pont of bubble center and the bubble radius. + $.jqplot.BubbleCanvas.prototype.createElement = function(x, y, r) { + var klass = 'jqplot-bubble-point'; + + var elem; + // if this canvas already has a dom element, don't make a new one. + if (this._elem) { + elem = this._elem.get(0); + } + else { + elem = document.createElement('canvas'); + } + + elem.width = (r != null) ? 2*r : elem.width; + elem.height = (r != null) ? 2*r : elem.height; + this._elem = $(elem); + var l = (x != null && r != null) ? x - r : this._elem.css('left'); + var t = (y != null && r != null) ? y - r : this._elem.css('top'); + this._elem.css({ position: 'absolute', left: l, top: t }); + + this._elem.addClass(klass); + if ($.jqplot.use_excanvas) { + window.G_vmlCanvasManager.init_(document); + elem = window.G_vmlCanvasManager.initElement(elem); + } + + return this._elem; + }; + + $.jqplot.BubbleCanvas.prototype.draw = function(r, color, gradients, angle) { + var ctx = this._ctx; + // r = Math.floor(r*1.04); + // var x = Math.round(ctx.canvas.width/2); + // var y = Math.round(ctx.canvas.height/2); + var x = ctx.canvas.width/2; + var y = ctx.canvas.height/2; + ctx.save(); + if (gradients && !$.jqplot.use_excanvas) { + r = r*1.04; + var comps = $.jqplot.getColorComponents(color); + var colorinner = 'rgba('+Math.round(comps[0]+0.8*(255-comps[0]))+', '+Math.round(comps[1]+0.8*(255-comps[1]))+', '+Math.round(comps[2]+0.8*(255-comps[2]))+', '+comps[3]+')'; + var colorend = 'rgba('+comps[0]+', '+comps[1]+', '+comps[2]+', 0)'; + // var rinner = Math.round(0.35 * r); + // var xinner = Math.round(x - Math.cos(angle) * 0.33 * r); + // var yinner = Math.round(y - Math.sin(angle) * 0.33 * r); + var rinner = 0.35 * r; + var xinner = x - Math.cos(angle) * 0.33 * r; + var yinner = y - Math.sin(angle) * 0.33 * r; + var radgrad = ctx.createRadialGradient(xinner, yinner, rinner, x, y, r); + radgrad.addColorStop(0, colorinner); + radgrad.addColorStop(0.93, color); + radgrad.addColorStop(0.96, colorend); + radgrad.addColorStop(1, colorend); + // radgrad.addColorStop(.98, colorend); + ctx.fillStyle = radgrad; + ctx.fillRect(0,0, ctx.canvas.width, ctx.canvas.height); + } + else { + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = 1; + ctx.beginPath(); + var ang = 2*Math.PI; + ctx.arc(x, y, r, 0, ang, 0); + ctx.closePath(); + ctx.fill(); + } + ctx.restore(); + }; + + $.jqplot.BubbleCanvas.prototype.setContext = function() { + this._ctx = this._elem.get(0).getContext("2d"); + return this._ctx; + }; + + $.jqplot.BubbleAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.BubbleAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.BubbleAxisRenderer.prototype.constructor = $.jqplot.BubbleAxisRenderer; + + // called with scope of axis object. + $.jqplot.BubbleAxisRenderer.prototype.init = function(options){ + $.extend(true, this, options); + var db = this._dataBounds; + var minsidx = 0, + minpidx = 0, + maxsidx = 0, + maxpidx = 0, + maxr = 0, + minr = 0, + minMaxRadius = 0, + maxMaxRadius = 0, + maxMult = 0, + minMult = 0; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + var d = s._plotData; + + for (var j=0; j<d.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + if (d[j][0] < db.min || db.min == null) { + db.min = d[j][0]; + minsidx=i; + minpidx=j; + minr = d[j][2]; + minMaxRadius = s.maxRadius; + minMult = s.autoscaleMultiplier; + } + if (d[j][0] > db.max || db.max == null) { + db.max = d[j][0]; + maxsidx=i; + maxpidx=j; + maxr = d[j][2]; + maxMaxRadius = s.maxRadius; + maxMult = s.autoscaleMultiplier; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + minsidx=i; + minpidx=j; + minr = d[j][2]; + minMaxRadius = s.maxRadius; + minMult = s.autoscaleMultiplier; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + maxsidx=i; + maxpidx=j; + maxr = d[j][2]; + maxMaxRadius = s.maxRadius; + maxMult = s.autoscaleMultiplier; + } + } + } + } + + var minRatio = minr/minMaxRadius; + var maxRatio = maxr/maxMaxRadius; + + // need to estimate the effect of the radius on total axis span and adjust axis accordingly. + var span = db.max - db.min; + // var dim = (this.name == 'xaxis' || this.name == 'x2axis') ? this._plotDimensions.width : this._plotDimensions.height; + var dim = Math.min(this._plotDimensions.width, this._plotDimensions.height); + + var minfact = minRatio * minMult/3 * span; + var maxfact = maxRatio * maxMult/3 * span; + db.max += maxfact; + db.min -= minfact; + }; + + function highlight (plot, sidx, pidx) { + plot.plugins.bubbleRenderer.highlightLabelCanvas.empty(); + var s = plot.series[sidx]; + var canvas = plot.plugins.bubbleRenderer.highlightCanvas; + var ctx = canvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.bubbleRenderer.highlightedSeriesIndex = sidx; + + var color = s.highlightColorGenerator.get(pidx); + var x = s.gridData[pidx][0], + y = s.gridData[pidx][1], + r = s.gridData[pidx][2]; + ctx.save(); + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = 1; + ctx.beginPath(); + ctx.arc(x, y, r, 0, 2*Math.PI, 0); + ctx.closePath(); + ctx.fill(); + ctx.restore(); + // bring label to front + if (s.labels[pidx]) { + plot.plugins.bubbleRenderer.highlightLabel = s.labels[pidx].clone(); + plot.plugins.bubbleRenderer.highlightLabel.appendTo(plot.plugins.bubbleRenderer.highlightLabelCanvas); + plot.plugins.bubbleRenderer.highlightLabel.addClass('jqplot-bubble-label-highlight'); + } + } + + function unhighlight (plot) { + var canvas = plot.plugins.bubbleRenderer.highlightCanvas; + var sidx = plot.plugins.bubbleRenderer.highlightedSeriesIndex; + plot.plugins.bubbleRenderer.highlightLabelCanvas.empty(); + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.bubbleRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var si = neighbor.seriesIndex; + var pi = neighbor.pointIndex; + var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.bubbleRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var si = neighbor.seriesIndex; + var pi = neighbor.pointIndex; + var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.bubbleRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.bubbleRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var si = neighbor.seriesIndex; + var pi = neighbor.pointIndex; + var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var si = neighbor.seriesIndex; + var pi = neighbor.pointIndex; + var ins = [si, pi, neighbor.data, plot.series[si].gridData[pi][2]]; + var idx = plot.plugins.bubbleRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.bubbleRenderer && this.plugins.bubbleRenderer.highlightCanvas) { + this.plugins.bubbleRenderer.highlightCanvas.resetCanvas(); + this.plugins.bubbleRenderer.highlightCanvas = null; + } + + this.plugins.bubbleRenderer = {highlightedSeriesIndex:null}; + this.plugins.bubbleRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + this.plugins.bubbleRenderer.highlightLabel = null; + this.plugins.bubbleRenderer.highlightLabelCanvas = $('<div style="position:absolute;"></div>'); + var top = this._gridPadding.top; + var left = this._gridPadding.left; + var width = this._plotDimensions.width - this._gridPadding.left - this._gridPadding.right; + var height = this._plotDimensions.height - this._gridPadding.top - this._gridPadding.bottom; + this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:top, left:left, width:width+'px', height:height+'px'}); + + this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-bubbleRenderer-highlight-canvas', this._plotDimensions, this)); + this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas); + + var hctx = this.plugins.bubbleRenderer.highlightCanvas.setContext(); + } + + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.seriesDefaults = options.seriesDefaults || {}; + // only set these if there is a Bubble series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.BubbleRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.BubbleRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.BubbleAxisRenderer; + options.sortData = false; + } + } + + $.jqplot.preInitHooks.push(preInit); + +})(jQuery); + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.min.js new file mode 100644 index 0000000..d44a7cd --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.bubbleRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(f){var d=function(m){return Math.max.apply(Math,m)};var j=function(m){return Math.min.apply(Math,m)};f.jqplot.BubbleRenderer=function(){f.jqplot.LineRenderer.call(this)};f.jqplot.BubbleRenderer.prototype=new f.jqplot.LineRenderer();f.jqplot.BubbleRenderer.prototype.constructor=f.jqplot.BubbleRenderer;f.jqplot.BubbleRenderer.prototype.init=function(w,t){this.varyBubbleColors=true;this.autoscaleBubbles=true;this.autoscaleMultiplier=1;this.autoscalePointsFactor=-0.07;this.escapeHtml=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.bubbleAlpha=1;this.highlightAlpha=null;this.bubbleGradients=false;this.showLabels=true;this.radii=[];this.maxRadius=0;this._highlightedPoint=null;this.labels=[];this.bubbleCanvases=[];this._type="bubble";if(w.highlightMouseDown&&w.highlightMouseOver==null){w.highlightMouseOver=false}f.extend(true,this,w);if(this.highlightAlpha==null){this.highlightAlpha=this.bubbleAlpha;if(this.bubbleGradients){this.highlightAlpha=0.35}}this.autoscaleMultiplier=this.autoscaleMultiplier*Math.pow(this.data.length,this.autoscalePointsFactor);this._highlightedPoint=null;var n;for(var r=0;r<this.data.length;r++){var p=null;var v=this.data[r];this.maxRadius=Math.max(this.maxRadius,v[2]);if(v[3]){if(typeof(v[3])=="object"){p=v[3]["color"]}}if(p==null){if(this.seriesColors[r]!=null){p=this.seriesColors[r]}}if(p&&this.bubbleAlpha<1){n=f.jqplot.getColorComponents(p);p="rgba("+n[0]+", "+n[1]+", "+n[2]+", "+this.bubbleAlpha+")"}if(p){this.seriesColors[r]=p}}if(!this.varyBubbleColors){this.seriesColors=[this.color]}this.colorGenerator=new f.jqplot.ColorGenerator(this.seriesColors);if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var o=f.jqplot.getColorComponents(this.seriesColors[r]);var u=[o[0],o[1],o[2]];var s=u[0]+u[1]+u[2];for(var q=0;q<3;q++){u[q]=(s>570)?u[q]*0.8:u[q]+0.3*(255-u[q]);u[q]=parseInt(u[q],10)}this.highlightColors.push("rgba("+u[0]+","+u[1]+","+u[2]+", "+this.highlightAlpha+")")}}this.highlightColorGenerator=new f.jqplot.ColorGenerator(this.highlightColors);var m={fill:true,isarc:true,angle:this.shadowAngle,alpha:this.shadowAlpha,closePath:true};this.renderer.shadowRenderer.init(m);this.canvas=new f.jqplot.DivCanvas();this.canvas._plotDimensions=this._plotDimensions;t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",k);t.eventListenerHooks.addOnce("jqplotClick",g);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};f.jqplot.BubbleRenderer.prototype.setGridData=function(w){var q=this._xaxis.series_u2p;var m=this._yaxis.series_u2p;var t=this._plotData;this.gridData=[];var s=[];this.radii=[];var v=Math.min(w._height,w._width);for(var u=0;u<this.data.length;u++){if(t[u]!=null){this.gridData.push([q.call(this._xaxis,t[u][0]),m.call(this._yaxis,t[u][1]),t[u][2]]);this.radii.push([u,t[u][2]]);s.push(t[u][2])}}var n,o,x=this.maxRadius=d(s);var p=this.gridData.length;if(this.autoscaleBubbles){for(var u=0;u<p;u++){o=s[u]/x;n=this.autoscaleMultiplier*v/6;this.gridData[u][2]=n*o}}this.radii.sort(function(y,r){return r[1]-y[1]})};f.jqplot.BubbleRenderer.prototype.makeGridData=function(t,w){var q=this._xaxis.series_u2p;var n=this._yaxis.series_u2p;var x=[];var s=[];this.radii=[];var v=Math.min(w._height,w._width);for(var u=0;u<t.length;u++){if(t[u]!=null){x.push([q.call(this._xaxis,t[u][0]),n.call(this._yaxis,t[u][1]),t[u][2]]);s.push(t[u][2]);this.radii.push([u,t[u][2]])}}var m,o,y=this.maxRadius=d(s);var p=this.gridData.length;if(this.autoscaleBubbles){for(var u=0;u<p;u++){o=s[u]/y;m=this.autoscaleMultiplier*v/6;x[u][2]=m*o}}this.radii.sort(function(z,r){return r[1]-z[1]});return x};f.jqplot.BubbleRenderer.prototype.draw=function(D,J,n){if(this.plugins.pointLabels){this.plugins.pointLabels.show=false}var A=(n!=undefined)?n:{};var r=(A.shadow!=undefined)?A.shadow:this.shadow;this.canvas._elem.empty();for(var G=0;G<this.radii.length;G++){var C=this.radii[G][0];var z=null;var F=null;var m=null;var p=null;var I=this.data[C];var J=this.gridData[C];if(I[3]){if(typeof(I[3])=="object"){z=I[3]["label"]}else{if(typeof(I[3])=="string"){z=I[3]}}}F=this.colorGenerator.get(C);var E=J[2];var q,K;if(this.shadow){q=(0.7+J[2]/40).toFixed(1);K=1+Math.ceil(J[2]/15);E+=q*K}this.bubbleCanvases[C]=new f.jqplot.BubbleCanvas();this.canvas._elem.append(this.bubbleCanvases[C].createElement(J[0],J[1],E));this.bubbleCanvases[C].setContext();var D=this.bubbleCanvases[C]._ctx;var u=D.canvas.width/2;var s=D.canvas.height/2;if(this.shadow){this.renderer.shadowRenderer.draw(D,[u,s,J[2],0,2*Math.PI],{offset:q,depth:K})}this.bubbleCanvases[C].draw(J[2],F,this.bubbleGradients,this.shadowAngle/180*Math.PI);if(z&&this.showLabels){p=f('<div style="position:absolute;" class="jqplot-bubble-label"></div>');if(this.escapeHtml){p.text(z)}else{p.html(z)}this.canvas._elem.append(p);var H=f(p).outerHeight();var v=f(p).outerWidth();var B=J[1]-0.5*H;var o=J[0]-0.5*v;p.css({top:B,left:o});this.labels[C]=f(p)}}};f.jqplot.DivCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.DivCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.DivCanvas.prototype.constructor=f.jqplot.DivCanvas;f.jqplot.DivCanvas.prototype.createElement=function(s,p,n){this._offsets=s;var m="jqplot-DivCanvas";if(p!=undefined){m=p}var r;if(this._elem){r=this._elem.get(0)}else{r=document.createElement("div")}if(n!=undefined){this._plotDimensions=n}var o=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var q=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=f(r);this._elem.css({position:"absolute",width:o,height:q,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(m);return this._elem};f.jqplot.DivCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx};f.jqplot.BubbleCanvas=function(){f.jqplot.ElemContainer.call(this);this._ctx};f.jqplot.BubbleCanvas.prototype=new f.jqplot.ElemContainer();f.jqplot.BubbleCanvas.prototype.constructor=f.jqplot.BubbleCanvas;f.jqplot.BubbleCanvas.prototype.createElement=function(n,u,s){var m="jqplot-bubble-point";var q;if(this._elem){q=this._elem.get(0)}else{q=document.createElement("canvas")}q.width=(s!=null)?2*s:q.width;q.height=(s!=null)?2*s:q.height;this._elem=f(q);var o=(n!=null&&s!=null)?n-s:this._elem.css("left");var p=(u!=null&&s!=null)?u-s:this._elem.css("top");this._elem.css({position:"absolute",left:o,top:p});this._elem.addClass(m);if(f.jqplot.use_excanvas){window.G_vmlCanvasManager.init_(document);q=window.G_vmlCanvasManager.initElement(q)}return this._elem};f.jqplot.BubbleCanvas.prototype.draw=function(m,s,v,p){var D=this._ctx;var B=D.canvas.width/2;var z=D.canvas.height/2;D.save();if(v&&!f.jqplot.use_excanvas){m=m*1.04;var o=f.jqplot.getColorComponents(s);var u="rgba("+Math.round(o[0]+0.8*(255-o[0]))+", "+Math.round(o[1]+0.8*(255-o[1]))+", "+Math.round(o[2]+0.8*(255-o[2]))+", "+o[3]+")";var t="rgba("+o[0]+", "+o[1]+", "+o[2]+", 0)";var C=0.35*m;var A=B-Math.cos(p)*0.33*m;var n=z-Math.sin(p)*0.33*m;var w=D.createRadialGradient(A,n,C,B,z,m);w.addColorStop(0,u);w.addColorStop(0.93,s);w.addColorStop(0.96,t);w.addColorStop(1,t);D.fillStyle=w;D.fillRect(0,0,D.canvas.width,D.canvas.height)}else{D.fillStyle=s;D.strokeStyle=s;D.lineWidth=1;D.beginPath();var q=2*Math.PI;D.arc(B,z,m,0,q,0);D.closePath();D.fill()}D.restore()};f.jqplot.BubbleCanvas.prototype.setContext=function(){this._ctx=this._elem.get(0).getContext("2d");return this._ctx};f.jqplot.BubbleAxisRenderer=function(){f.jqplot.LinearAxisRenderer.call(this)};f.jqplot.BubbleAxisRenderer.prototype=new f.jqplot.LinearAxisRenderer();f.jqplot.BubbleAxisRenderer.prototype.constructor=f.jqplot.BubbleAxisRenderer;f.jqplot.BubbleAxisRenderer.prototype.init=function(n){f.extend(true,this,n);var I=this._dataBounds;var H=0,v=0,m=0,y=0,q=0,r=0,D=0,t=0,F=0,z=0;for(var E=0;E<this._series.length;E++){var x=this._series[E];var G=x._plotData;for(var B=0;B<G.length;B++){if(this.name=="xaxis"||this.name=="x2axis"){if(G[B][0]<I.min||I.min==null){I.min=G[B][0];H=E;v=B;r=G[B][2];D=x.maxRadius;z=x.autoscaleMultiplier}if(G[B][0]>I.max||I.max==null){I.max=G[B][0];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}else{if(G[B][1]<I.min||I.min==null){I.min=G[B][1];H=E;v=B;r=G[B][2];D=x.maxRadius;z=x.autoscaleMultiplier}if(G[B][1]>I.max||I.max==null){I.max=G[B][1];m=E;y=B;q=G[B][2];t=x.maxRadius;F=x.autoscaleMultiplier}}}}var o=r/D;var w=q/t;var C=I.max-I.min;var A=Math.min(this._plotDimensions.width,this._plotDimensions.height);var p=o*z/3*C;var u=w*F/3*C;I.max+=u;I.min-=p};function e(p,v,q){p.plugins.bubbleRenderer.highlightLabelCanvas.empty();var z=p.series[v];var n=p.plugins.bubbleRenderer.highlightCanvas;var w=n._ctx;w.clearRect(0,0,w.canvas.width,w.canvas.height);z._highlightedPoint=q;p.plugins.bubbleRenderer.highlightedSeriesIndex=v;var o=z.highlightColorGenerator.get(q);var u=z.gridData[q][0],t=z.gridData[q][1],m=z.gridData[q][2];w.save();w.fillStyle=o;w.strokeStyle=o;w.lineWidth=1;w.beginPath();w.arc(u,t,m,0,2*Math.PI,0);w.closePath();w.fill();w.restore();if(z.labels[q]){p.plugins.bubbleRenderer.highlightLabel=z.labels[q].clone();p.plugins.bubbleRenderer.highlightLabel.appendTo(p.plugins.bubbleRenderer.highlightLabelCanvas);p.plugins.bubbleRenderer.highlightLabel.addClass("jqplot-bubble-label-highlight")}}function i(p){var m=p.plugins.bubbleRenderer.highlightCanvas;var o=p.plugins.bubbleRenderer.highlightedSeriesIndex;p.plugins.bubbleRenderer.highlightLabelCanvas.empty();m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);for(var n=0;n<p.series.length;n++){p.series[n]._highlightedPoint=null}p.plugins.bubbleRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight")}function a(s,p,m,v,r){if(v){var n=v.seriesIndex;var o=v.pointIndex;var q=[n,o,v.data,r.series[n].gridData[o][2]];var t=jQuery.Event("jqplotDataMouseOver");t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q);if(r.series[q[0]].highlightMouseOver&&!(q[0]==r.plugins.bubbleRenderer.highlightedSeriesIndex&&q[1]==r.series[q[0]]._highlightedPoint)){var u=jQuery.Event("jqplotDataHighlight");u.which=s.which;u.pageX=s.pageX;u.pageY=s.pageY;r.target.trigger(u,q);e(r,q[0],q[1])}}else{if(v==null){i(r)}}}function b(s,p,m,u,r){if(u){var n=u.seriesIndex;var o=u.pointIndex;var q=[n,o,u.data,r.series[n].gridData[o][2]];if(r.series[q[0]].highlightMouseDown&&!(q[0]==r.plugins.bubbleRenderer.highlightedSeriesIndex&&q[1]==r.series[q[0]]._highlightedPoint)){var t=jQuery.Event("jqplotDataHighlight");t.which=s.which;t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q);e(r,q[0],q[1])}}else{if(u==null){i(r)}}}function k(o,n,r,q,p){var m=p.plugins.bubbleRenderer.highlightedSeriesIndex;if(m!=null&&p.series[m].highlightMouseDown){i(p)}}function g(s,p,m,u,r){if(u){var n=u.seriesIndex;var o=u.pointIndex;var q=[n,o,u.data,r.series[n].gridData[o][2]];var t=jQuery.Event("jqplotDataClick");t.which=s.which;t.pageX=s.pageX;t.pageY=s.pageY;r.target.trigger(t,q)}}function l(s,p,m,v,r){if(v){var n=v.seriesIndex;var o=v.pointIndex;var q=[n,o,v.data,r.series[n].gridData[o][2]];var t=r.plugins.bubbleRenderer.highlightedSeriesIndex;if(t!=null&&r.series[t].highlightMouseDown){i(r)}var u=jQuery.Event("jqplotDataRightClick");u.which=s.which;u.pageX=s.pageX;u.pageY=s.pageY;r.target.trigger(u,q)}}function h(){if(this.plugins.bubbleRenderer&&this.plugins.bubbleRenderer.highlightCanvas){this.plugins.bubbleRenderer.highlightCanvas.resetCanvas();this.plugins.bubbleRenderer.highlightCanvas=null}this.plugins.bubbleRenderer={highlightedSeriesIndex:null};this.plugins.bubbleRenderer.highlightCanvas=new f.jqplot.GenericCanvas();this.plugins.bubbleRenderer.highlightLabel=null;this.plugins.bubbleRenderer.highlightLabelCanvas=f('<div style="position:absolute;"></div>');var q=this._gridPadding.top;var p=this._gridPadding.left;var n=this._plotDimensions.width-this._gridPadding.left-this._gridPadding.right;var m=this._plotDimensions.height-this._gridPadding.top-this._gridPadding.bottom;this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:q,left:p,width:n+"px",height:m+"px"});this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-bubbleRenderer-highlight-canvas",this._plotDimensions,this));this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas);var o=this.plugins.bubbleRenderer.highlightCanvas.setContext()}function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==f.jqplot.BubbleRenderer){m=true}else{if(n.series){for(var o=0;o<n.series.length;o++){if(n.series[o].renderer==f.jqplot.BubbleRenderer){m=true}}}}if(m){n.axesDefaults.renderer=f.jqplot.BubbleAxisRenderer;n.sortData=false}}f.jqplot.preInitHooks.push(c)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js new file mode 100644 index 0000000..6313dc1 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js @@ -0,0 +1,203 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.CanvasAxisLabelRenderer + * Renderer to draw axis labels with a canvas element to support advanced + * featrues such as rotated text. This renderer uses a separate rendering engine + * to draw the text on the canvas. Two modes of rendering the text are available. + * If the browser has native font support for canvas fonts (currently Mozila 3.5 + * and Safari 4), you can enable text rendering with the canvas fillText method. + * You do so by setting the "enableFontSupport" option to true. + * + * Browsers lacking native font support will have the text drawn on the canvas + * using the Hershey font metrics. Even if the "enableFontSupport" option is true + * non-supporting browsers will still render with the Hershey font. + * + */ + $.jqplot.CanvasAxisLabelRenderer = function(options) { + // Group: Properties + + // prop: angle + // angle of text, measured clockwise from x axis. + this.angle = 0; + // name of the axis associated with this tick + this.axis; + // prop: show + // whether or not to show the tick (mark and label). + this.show = true; + // prop: showLabel + // whether or not to show the label. + this.showLabel = true; + // prop: label + // label for the axis. + this.label = ''; + // prop: fontFamily + // CSS spec for the font-family css attribute. + // Applies only to browsers supporting native font rendering in the + // canvas tag. Currently Mozilla 3.5 and Safari 4. + this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; + // prop: fontSize + // CSS spec for font size. + this.fontSize = '11pt'; + // prop: fontWeight + // CSS spec for fontWeight: normal, bold, bolder, lighter or a number 100 - 900 + this.fontWeight = 'normal'; + // prop: fontStretch + // Multiplier to condense or expand font width. + // Applies only to browsers which don't support canvas native font rendering. + this.fontStretch = 1.0; + // prop: textColor + // css spec for the color attribute. + this.textColor = '#666666'; + // prop: enableFontSupport + // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. + // If true, label will be drawn with canvas tag native support for fonts. + // If false, label will be drawn with Hershey font metrics. + this.enableFontSupport = true; + // prop: pt2px + // Point to pixel scaling factor, used for computing height of bounding box + // around a label. The labels text renderer has a default setting of 1.4, which + // should be suitable for most fonts. Leave as null to use default. If tops of + // letters appear clipped, increase this. If bounding box seems too big, decrease. + // This is an issue only with the native font renderering capabilities of Mozilla + // 3.5 and Safari 4 since they do not provide a method to determine the font height. + this.pt2px = null; + + this._elem; + this._ctx; + this._plotWidth; + this._plotHeight; + this._plotDimensions = {height:null, width:null}; + + $.extend(true, this, options); + + if (options.angle == null && this.axis != 'xaxis' && this.axis != 'x2axis') { + this.angle = -90; + } + + var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; + if (this.pt2px) { + ropts.pt2px = this.pt2px; + } + + if (this.enableFontSupport) { + if ($.jqplot.support_canvas_text()) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisLabelRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisLabelRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.draw = function(ctx, plot) { + // Memory Leaks patch + if (this._elem) { + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); + } + + this._elem.emptyForce(); + this._elem = null; + } + + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + var elem = plot.canvasManager.getCanvas(); + + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + elem.width = w; + elem.height = h; + elem.style.width = w; + elem.style.height = h; + + elem = plot.canvasManager.initCanvas(elem); + + this._elem = $(elem); + this._elem.css({ position: 'absolute'}); + this._elem.addClass('jqplot-'+this.axis+'-label'); + + elem = null; + return this._elem; + }; + + $.jqplot.CanvasAxisLabelRenderer.prototype.pack = function() { + this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js new file mode 100644 index 0000000..4babb74 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.CanvasAxisLabelRenderer=function(b){this.angle=0;this.axis;this.show=true;this.showLabel=true;this.label="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="11pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);if(b.angle==null&&this.axis!="xaxis"&&this.axis!="x2axis"){this.angle=-90}var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisLabelRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisLabelRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisLabelRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisLabelRenderer.prototype.draw=function(c,f){if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css({position:"absolute"});this._elem.addClass("jqplot-"+this.axis+"-label");e=null;return this._elem};a.jqplot.CanvasAxisLabelRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.js new file mode 100644 index 0000000..b6120d0 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.js @@ -0,0 +1,253 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.CanvasAxisTickRenderer + * Renderer to draw axis ticks with a canvas element to support advanced + * featrues such as rotated text. This renderer uses a separate rendering engine + * to draw the text on the canvas. Two modes of rendering the text are available. + * If the browser has native font support for canvas fonts (currently Mozila 3.5 + * and Safari 4), you can enable text rendering with the canvas fillText method. + * You do so by setting the "enableFontSupport" option to true. + * + * Browsers lacking native font support will have the text drawn on the canvas + * using the Hershey font metrics. Even if the "enableFontSupport" option is true + * non-supporting browsers will still render with the Hershey font. + */ + $.jqplot.CanvasAxisTickRenderer = function(options) { + // Group: Properties + + // prop: mark + // tick mark on the axis. One of 'inside', 'outside', 'cross', '' or null. + this.mark = 'outside'; + // prop: showMark + // whether or not to show the mark on the axis. + this.showMark = true; + // prop: showGridline + // whether or not to draw the gridline on the grid at this tick. + this.showGridline = true; + // prop: isMinorTick + // if this is a minor tick. + this.isMinorTick = false; + // prop: angle + // angle of text, measured clockwise from x axis. + this.angle = 0; + // prop: markSize + // Length of the tick marks in pixels. For 'cross' style, length + // will be stoked above and below axis, so total length will be twice this. + this.markSize = 4; + // prop: show + // whether or not to show the tick (mark and label). + this.show = true; + // prop: showLabel + // whether or not to show the label. + this.showLabel = true; + // prop: labelPosition + // 'auto', 'start', 'middle' or 'end'. + // Whether tick label should be positioned so the start, middle, or end + // of the tick mark. + this.labelPosition = 'auto'; + this.label = ''; + this.value = null; + this._styles = {}; + // prop: formatter + // A class of a formatter for the tick text. + // The default $.jqplot.DefaultTickFormatter uses sprintf. + this.formatter = $.jqplot.DefaultTickFormatter; + // prop: formatString + // string passed to the formatter. + this.formatString = ''; + // prop: prefix + // String to prepend to the tick label. + // Prefix is prepended to the formatted tick label. + this.prefix = ''; + // prop: fontFamily + // css spec for the font-family css attribute. + this.fontFamily = '"Trebuchet MS", Arial, Helvetica, sans-serif'; + // prop: fontSize + // CSS spec for font size. + this.fontSize = '10pt'; + // prop: fontWeight + // CSS spec for fontWeight + this.fontWeight = 'normal'; + // prop: fontStretch + // Multiplier to condense or expand font width. + // Applies only to browsers which don't support canvas native font rendering. + this.fontStretch = 1.0; + // prop: textColor + // css spec for the color attribute. + this.textColor = '#666666'; + // prop: enableFontSupport + // true to turn on native canvas font support in Mozilla 3.5+ and Safari 4+. + // If true, tick label will be drawn with canvas tag native support for fonts. + // If false, tick label will be drawn with Hershey font metrics. + this.enableFontSupport = true; + // prop: pt2px + // Point to pixel scaling factor, used for computing height of bounding box + // around a label. The labels text renderer has a default setting of 1.4, which + // should be suitable for most fonts. Leave as null to use default. If tops of + // letters appear clipped, increase this. If bounding box seems too big, decrease. + // This is an issue only with the native font renderering capabilities of Mozilla + // 3.5 and Safari 4 since they do not provide a method to determine the font height. + this.pt2px = null; + + this._elem; + this._ctx; + this._plotWidth; + this._plotHeight; + this._plotDimensions = {height:null, width:null}; + + $.extend(true, this, options); + + var ropts = {fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}; + if (this.pt2px) { + ropts.pt2px = this.pt2px; + } + + if (this.enableFontSupport) { + if ($.jqplot.support_canvas_text()) { + this._textRenderer = new $.jqplot.CanvasFontRenderer(ropts); + } + + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + } + else { + this._textRenderer = new $.jqplot.CanvasTextRenderer(ropts); + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this._textRenderer.init({fontSize:this.fontSize, fontWeight:this.fontWeight, fontStretch:this.fontStretch, fillStyle:this.textColor, angle:this.getAngleRad(), fontFamily:this.fontFamily}); + }; + + // return width along the x axis + // will check first to see if an element exists. + // if not, will return the computed text box width. + $.jqplot.CanvasAxisTickRenderer.prototype.getWidth = function(ctx) { + if (this._elem) { + return this._elem.outerWidth(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.sin(tr.angle)*h) + Math.abs(Math.cos(tr.angle)*l); + return w; + } + }; + + // return height along the y axis. + $.jqplot.CanvasAxisTickRenderer.prototype.getHeight = function(ctx) { + if (this._elem) { + return this._elem.outerHeight(true); + } + else { + var tr = this._textRenderer; + var l = tr.getWidth(ctx); + var h = tr.getHeight(ctx); + var w = Math.abs(Math.cos(tr.angle)*h) + Math.abs(Math.sin(tr.angle)*l); + return w; + } + }; + + // return top. + $.jqplot.CanvasAxisTickRenderer.prototype.getTop = function(ctx) { + if (this._elem) { + return this._elem.position().top; + } + else { + return null; + } + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad = function() { + var a = this.angle * Math.PI/180; + return a; + }; + + + $.jqplot.CanvasAxisTickRenderer.prototype.setTick = function(value, axisName, isMinor) { + this.value = value; + if (isMinor) { + this.isMinorTick = true; + } + return this; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.draw = function(ctx, plot) { + if (!this.label) { + this.label = this.prefix + this.formatter(this.formatString, this.value); + } + + // Memory Leaks patch + if (this._elem) { + if ($.jqplot.use_excanvas && window.G_vmlCanvasManager.uninitElement !== undefined) { + window.G_vmlCanvasManager.uninitElement(this._elem.get(0)); + } + + this._elem.emptyForce(); + this._elem = null; + } + + // create a canvas here, but can't draw on it untill it is appended + // to dom for IE compatability. + + var elem = plot.canvasManager.getCanvas(); + + this._textRenderer.setText(this.label, ctx); + var w = this.getWidth(ctx); + var h = this.getHeight(ctx); + // canvases seem to need to have width and heigh attributes directly set. + elem.width = w; + elem.height = h; + elem.style.width = w; + elem.style.height = h; + elem.style.textAlign = 'left'; + elem.style.position = 'absolute'; + + elem = plot.canvasManager.initCanvas(elem); + + this._elem = $(elem); + this._elem.css(this._styles); + this._elem.addClass('jqplot-'+this.axis+'-tick'); + + elem = null; + return this._elem; + }; + + $.jqplot.CanvasAxisTickRenderer.prototype.pack = function() { + this._textRenderer.draw(this._elem.get(0).getContext("2d"), this.label); + }; + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js new file mode 100644 index 0000000..7ef6096 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.CanvasAxisTickRenderer=function(b){this.mark="outside";this.showMark=true;this.showGridline=true;this.isMinorTick=false;this.angle=0;this.markSize=4;this.show=true;this.showLabel=true;this.labelPosition="auto";this.label="";this.value=null;this._styles={};this.formatter=a.jqplot.DefaultTickFormatter;this.formatString="";this.prefix="";this.fontFamily='"Trebuchet MS", Arial, Helvetica, sans-serif';this.fontSize="10pt";this.fontWeight="normal";this.fontStretch=1;this.textColor="#666666";this.enableFontSupport=true;this.pt2px=null;this._elem;this._ctx;this._plotWidth;this._plotHeight;this._plotDimensions={height:null,width:null};a.extend(true,this,b);var c={fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily};if(this.pt2px){c.pt2px=this.pt2px}if(this.enableFontSupport){if(a.jqplot.support_canvas_text()){this._textRenderer=new a.jqplot.CanvasFontRenderer(c)}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}}else{this._textRenderer=new a.jqplot.CanvasTextRenderer(c)}};a.jqplot.CanvasAxisTickRenderer.prototype.init=function(b){a.extend(true,this,b);this._textRenderer.init({fontSize:this.fontSize,fontWeight:this.fontWeight,fontStretch:this.fontStretch,fillStyle:this.textColor,angle:this.getAngleRad(),fontFamily:this.fontFamily})};a.jqplot.CanvasAxisTickRenderer.prototype.getWidth=function(d){if(this._elem){return this._elem.outerWidth(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.sin(f.angle)*e)+Math.abs(Math.cos(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getHeight=function(d){if(this._elem){return this._elem.outerHeight(true)}else{var f=this._textRenderer;var c=f.getWidth(d);var e=f.getHeight(d);var b=Math.abs(Math.cos(f.angle)*e)+Math.abs(Math.sin(f.angle)*c);return b}};a.jqplot.CanvasAxisTickRenderer.prototype.getTop=function(b){if(this._elem){return this._elem.position().top}else{return null}};a.jqplot.CanvasAxisTickRenderer.prototype.getAngleRad=function(){var b=this.angle*Math.PI/180;return b};a.jqplot.CanvasAxisTickRenderer.prototype.setTick=function(b,d,c){this.value=b;if(c){this.isMinorTick=true}return this};a.jqplot.CanvasAxisTickRenderer.prototype.draw=function(c,f){if(!this.label){this.label=this.prefix+this.formatter(this.formatString,this.value)}if(this._elem){if(a.jqplot.use_excanvas&&window.G_vmlCanvasManager.uninitElement!==undefined){window.G_vmlCanvasManager.uninitElement(this._elem.get(0))}this._elem.emptyForce();this._elem=null}var e=f.canvasManager.getCanvas();this._textRenderer.setText(this.label,c);var b=this.getWidth(c);var d=this.getHeight(c);e.width=b;e.height=d;e.style.width=b;e.style.height=d;e.style.textAlign="left";e.style.position="absolute";e=f.canvasManager.initCanvas(e);this._elem=a(e);this._elem.css(this._styles);this._elem.addClass("jqplot-"+this.axis+"-tick");e=null;return this._elem};a.jqplot.CanvasAxisTickRenderer.prototype.pack=function(){this._textRenderer.draw(this._elem.get(0).getContext("2d"),this.label)}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.js new file mode 100644 index 0000000..4094413 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.js @@ -0,0 +1,1021 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + var objCounter = 0; + // class: $.jqplot.CanvasOverlay + $.jqplot.CanvasOverlay = function(opts){ + var options = opts || {}; + this.options = { + show: $.jqplot.config.enablePlugins, + deferDraw: false + }; + // prop: objects + this.objects = []; + this.objectNames = []; + this.canvas = null; + this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'}); + this.markerRenderer.init(); + this.highlightObjectIndex = null; + if (options.objects) { + var objs = options.objects, + obj; + for (var i=0; i<objs.length; i++) { + obj = objs[i]; + for (var n in obj) { + switch (n) { + case 'line': + this.addLine(obj[n]); + break; + case 'horizontalLine': + this.addHorizontalLine(obj[n]); + break; + case 'dashedHorizontalLine': + this.addDashedHorizontalLine(obj[n]); + break; + case 'verticalLine': + this.addVerticalLine(obj[n]); + break; + case 'dashedVerticalLine': + this.addDashedVerticalLine(obj[n]); + break; + case 'rectangle': + this.addRectangle(obj[n]); + break; + default: + break; + } + } + } + } + $.extend(true, this.options, options); + }; + + // called with scope of a plot object + $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) { + var options = opts || {}; + // add a canvasOverlay attribute to the plot + this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay); + }; + + + function LineBase() { + this.uid = null; + this.type = null; + this.gridStart = null; + this.gridStop = null; + this.tooltipWidthFactor = 0; + this.options = { + // prop: name + // Optional name for the overlay object. + // Can be later used to retrieve the object by name. + name: null, + // prop: show + // true to show (draw), false to not draw. + show: true, + // prop: lineWidth + // Width of the line. + lineWidth: 2, + // prop: lineCap + // Type of ending placed on the line ['round', 'butt', 'square'] + lineCap: 'round', + // prop: color + // color of the line + color: '#666666', + // prop: shadow + // whether or not to draw a shadow on the line + shadow: true, + // prop: shadowAngle + // Shadow angle in degrees + shadowAngle: 45, + // prop: shadowOffset + // Shadow offset from line in pixels + shadowOffset: 1, + // prop: shadowDepth + // Number of times shadow is stroked, each stroke offset shadowOffset from the last. + shadowDepth: 3, + // prop: shadowAlpha + // Alpha channel transparency of shadow. 0 = transparent. + shadowAlpha: '0.07', + // prop: xaxis + // X axis to use for positioning/scaling the line. + xaxis: 'xaxis', + // prop: yaxis + // Y axis to use for positioning/scaling the line. + yaxis: 'yaxis', + // prop: showTooltip + // Show a tooltip with data point values. + showTooltip: false, + // prop: showTooltipPrecision + // Controls how close to line cursor must be to show tooltip. + // Higher number = closer to line, lower number = farther from line. + // 1.0 = cursor must be over line. + showTooltipPrecision: 0.6, + // prop: tooltipLocation + // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + tooltipLocation: 'nw', + // prop: fadeTooltip + // true = fade in/out tooltip, flase = show/hide tooltip + fadeTooltip: true, + // prop: tooltipFadeSpeed + // 'slow', 'def', 'fast', or number of milliseconds. + tooltipFadeSpeed: "fast", + // prop: tooltipOffset + // Pixel offset of tooltip from the highlight. + tooltipOffset: 4, + // prop: tooltipFormatString + // Format string passed the x and y values of the cursor on the line. + // e.g., 'Dogs: %.2f, Cats: %d'. + tooltipFormatString: '%d, %d' + }; + } + + + function Rectangle(options) { + LineBase.call(this); + this.type = 'rectangle'; + var opts = { + // prop: xmin + // x value for the start of the line, null to scale to axis min. + xmin: null, + // prop: xmax + // x value for the end of the line, null to scale to axis max. + xmax: null, + // prop xOffset + // offset ends of the line inside the grid. Number + xOffset: '6px', // number or string. Number interpreted as units, string as pixels. + xminOffset: null, + xmaxOffset: null, + + ymin: null, + ymax: null, + yOffset: '6px', // number or string. Number interpreted as units, string as pixels. + yminOffset: null, + ymaxOffset: null + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + Rectangle.prototype = new LineBase(); + Rectangle.prototype.constructor = Rectangle; + + + /** + * Class: Line + * A straight line. + */ + function Line(options) { + LineBase.call(this); + this.type = 'line'; + var opts = { + // prop: start + // [x, y] coordinates for the start of the line. + start: [], + // prop: stop + // [x, y] coordinates for the end of the line. + stop: [] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + Line.prototype = new LineBase(); + Line.prototype.constructor = Line; + + + /** + * Class: HorizontalLine + * A straight horizontal line. + */ + function HorizontalLine(options) { + LineBase.call(this); + this.type = 'horizontalLine'; + var opts = { + // prop: y + // y value to position the line + y: null, + // prop: xmin + // x value for the start of the line, null to scale to axis min. + xmin: null, + // prop: xmax + // x value for the end of the line, null to scale to axis max. + xmax: null, + // prop xOffset + // offset ends of the line inside the grid. Number + xOffset: '6px', // number or string. Number interpreted as units, string as pixels. + xminOffset: null, + xmaxOffset: null + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + HorizontalLine.prototype = new LineBase(); + HorizontalLine.prototype.constructor = HorizontalLine; + + + /** + * Class: DashedHorizontalLine + * A straight dashed horizontal line. + */ + function DashedHorizontalLine(options) { + LineBase.call(this); + this.type = 'dashedHorizontalLine'; + var opts = { + y: null, + xmin: null, + xmax: null, + xOffset: '6px', // number or string. Number interpreted as units, string as pixels. + xminOffset: null, + xmaxOffset: null, + // prop: dashPattern + // Array of line, space settings in pixels. + // Default is 8 pixel of line, 8 pixel of space. + // Note, limit to a 2 element array b/c of bug with higher order arrays. + dashPattern: [8,8] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + DashedHorizontalLine.prototype = new LineBase(); + DashedHorizontalLine.prototype.constructor = DashedHorizontalLine; + + + /** + * Class: VerticalLine + * A straight vertical line. + */ + function VerticalLine(options) { + LineBase.call(this); + this.type = 'verticalLine'; + var opts = { + x: null, + ymin: null, + ymax: null, + yOffset: '6px', // number or string. Number interpreted as units, string as pixels. + yminOffset: null, + ymaxOffset: null + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + VerticalLine.prototype = new LineBase(); + VerticalLine.prototype.constructor = VerticalLine; + + + /** + * Class: DashedVerticalLine + * A straight dashed vertical line. + */ + function DashedVerticalLine(options) { + LineBase.call(this); + this.type = 'dashedVerticalLine'; + this.start = null; + this.stop = null; + var opts = { + x: null, + ymin: null, + ymax: null, + yOffset: '6px', // number or string. Number interpreted as units, string as pixels. + yminOffset: null, + ymaxOffset: null, + // prop: dashPattern + // Array of line, space settings in pixels. + // Default is 8 pixel of line, 8 pixel of space. + // Note, limit to a 2 element array b/c of bug with higher order arrays. + dashPattern: [8,8] + }; + $.extend(true, this.options, opts, options); + + if (this.options.showTooltipPrecision < 0.01) { + this.options.showTooltipPrecision = 0.01; + } + } + + DashedVerticalLine.prototype = new LineBase(); + DashedVerticalLine.prototype.constructor = DashedVerticalLine; + + $.jqplot.CanvasOverlay.prototype.addLine = function(opts) { + var line = new Line(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) { + var line = new HorizontalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) { + var line = new DashedHorizontalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) { + var line = new VerticalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) { + var line = new DashedVerticalLine(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.addRectangle = function(opts) { + var line = new Rectangle(opts); + line.uid = objCounter++; + this.objects.push(line); + this.objectNames.push(line.options.name); + }; + + $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) { + // check if integer, remove by index + if ($.type(idx) == 'number') { + this.objects.splice(idx, 1); + this.objectNames.splice(idx, 1); + } + // if string, remove by name + else { + var id = $.inArray(idx, this.objectNames); + if (id != -1) { + this.objects.splice(id, 1); + this.objectNames.splice(id, 1); + } + } + }; + + $.jqplot.CanvasOverlay.prototype.getObject = function(idx) { + // check if integer, remove by index + if ($.type(idx) == 'number') { + return this.objects[idx]; + } + // if string, remove by name + else { + var id = $.inArray(idx, this.objectNames); + if (id != -1) { + return this.objects[id]; + } + } + }; + + // Set get as alias for getObject. + $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject; + + $.jqplot.CanvasOverlay.prototype.clear = function(plot) { + this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight()); + }; + + $.jqplot.CanvasOverlay.prototype.draw = function(plot) { + var obj, + objs = this.objects, + mr = this.markerRenderer, + start, + stop; + if (this.options.show) { + this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight()); + for (var k=0; k<objs.length; k++) { + obj = objs[k]; + var opts = $.extend(true, {}, obj.options); + if (obj.options.show) { + // style and shadow properties should be set before + // every draw of marker renderer. + mr.shadow = obj.options.shadow; + obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision; + switch (obj.type) { + case 'line': + // style and shadow properties should be set before + // every draw of marker renderer. + mr.style = 'line'; + opts.closePath = false; + start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])]; + stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])]; + obj.gridStart = start; + obj.gridStop = stop; + mr.draw(start, stop, this.canvas._ctx, opts); + break; + case 'horizontalLine': + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.y != null) { + mr.style = 'line'; + opts.closePath = false; + var xaxis = plot.axes[obj.options.xaxis], + xstart, + xstop, + y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y), + xminoff = obj.options.xminOffset || obj.options.xOffset, + xmaxoff = obj.options.xmaxOffset || obj.options.xOffset; + if (obj.options.xmin != null) { + xstart = xaxis.series_u2p(obj.options.xmin); + } + else if (xminoff != null) { + if ($.type(xminoff) == "number") { + xstart = xaxis.series_u2p(xaxis.min + xminoff); + } + else if ($.type(xminoff) == "string") { + xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff); + } + } + if (obj.options.xmax != null) { + xstop = xaxis.series_u2p(obj.options.xmax); + } + else if (xmaxoff != null) { + if ($.type(xmaxoff) == "number") { + xstop = xaxis.series_u2p(xaxis.max - xmaxoff); + } + else if ($.type(xmaxoff) == "string") { + xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff); + } + } + if (xstop != null && xstart != null) { + obj.gridStart = [xstart, y]; + obj.gridStop = [xstop, y]; + mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts); + } + } + break; + + case 'dashedHorizontalLine': + + var dashPat = obj.options.dashPattern; + var dashPatLen = 0; + for (var i=0; i<dashPat.length; i++) { + dashPatLen += dashPat[i]; + } + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.y != null) { + mr.style = 'line'; + opts.closePath = false; + var xaxis = plot.axes[obj.options.xaxis], + xstart, + xstop, + y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y), + xminoff = obj.options.xminOffset || obj.options.xOffset, + xmaxoff = obj.options.xmaxOffset || obj.options.xOffset; + if (obj.options.xmin != null) { + xstart = xaxis.series_u2p(obj.options.xmin); + } + else if (xminoff != null) { + if ($.type(xminoff) == "number") { + xstart = xaxis.series_u2p(xaxis.min + xminoff); + } + else if ($.type(xminoff) == "string") { + xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff); + } + } + if (obj.options.xmax != null) { + xstop = xaxis.series_u2p(obj.options.xmax); + } + else if (xmaxoff != null) { + if ($.type(xmaxoff) == "number") { + xstop = xaxis.series_u2p(xaxis.max - xmaxoff); + } + else if ($.type(xmaxoff) == "string") { + xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff); + } + } + if (xstop != null && xstart != null) { + obj.gridStart = [xstart, y]; + obj.gridStop = [xstop, y]; + var numDash = Math.ceil((xstop - xstart)/dashPatLen); + var b=xstart, e; + for (var i=0; i<numDash; i++) { + for (var j=0; j<dashPat.length; j+=2) { + e = b+dashPat[j]; + mr.draw([b, y], [e, y], this.canvas._ctx, opts); + b += dashPat[j]; + if (j < dashPat.length-1) { + b += dashPat[j+1]; + } + } + } + } + } + break; + + case 'verticalLine': + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.x != null) { + mr.style = 'line'; + opts.closePath = false; + var yaxis = plot.axes[obj.options.yaxis], + ystart, + ystop, + x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x), + yminoff = obj.options.yminOffset || obj.options.yOffset, + ymaxoff = obj.options.ymaxOffset || obj.options.yOffset; + if (obj.options.ymin != null) { + ystart = yaxis.series_u2p(obj.options.ymin); + } + else if (yminoff != null) { + if ($.type(yminoff) == "number") { + ystart = yaxis.series_u2p(yaxis.min - yminoff); + } + else if ($.type(yminoff) == "string") { + ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff); + } + } + if (obj.options.ymax != null) { + ystop = yaxis.series_u2p(obj.options.ymax); + } + else if (ymaxoff != null) { + if ($.type(ymaxoff) == "number") { + ystop = yaxis.series_u2p(yaxis.max + ymaxoff); + } + else if ($.type(ymaxoff) == "string") { + ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff); + } + } + if (ystop != null && ystart != null) { + obj.gridStart = [x, ystart]; + obj.gridStop = [x, ystop]; + mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts); + } + } + break; + + case 'dashedVerticalLine': + + var dashPat = obj.options.dashPattern; + var dashPatLen = 0; + for (var i=0; i<dashPat.length; i++) { + dashPatLen += dashPat[i]; + } + + // style and shadow properties should be set before + // every draw of marker renderer. + if (obj.options.x != null) { + mr.style = 'line'; + opts.closePath = false; + var yaxis = plot.axes[obj.options.yaxis], + ystart, + ystop, + x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x), + yminoff = obj.options.yminOffset || obj.options.yOffset, + ymaxoff = obj.options.ymaxOffset || obj.options.yOffset; + if (obj.options.ymin != null) { + ystart = yaxis.series_u2p(obj.options.ymin); + } + else if (yminoff != null) { + if ($.type(yminoff) == "number") { + ystart = yaxis.series_u2p(yaxis.min - yminoff); + } + else if ($.type(yminoff) == "string") { + ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff); + } + } + if (obj.options.ymax != null) { + ystop = yaxis.series_u2p(obj.options.ymax); + } + else if (ymaxoff != null) { + if ($.type(ymaxoff) == "number") { + ystop = yaxis.series_u2p(yaxis.max + ymaxoff); + } + else if ($.type(ymaxoff) == "string") { + ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff); + } + } + + + if (ystop != null && ystart != null) { + obj.gridStart = [x, ystart]; + obj.gridStop = [x, ystop]; + var numDash = Math.ceil((ystart - ystop)/dashPatLen); + var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0; + var b=ystart, e, bs, es; + for (var i=0; i<numDash; i++) { + for (var j=0; j<dashPat.length; j+=2) { + e = b - dashPat[j]; + if (e < ystop) { + e = ystop; + } + if (b < ystop) { + b = ystop; + } + // es = e; + // if (i == 0) { + // es += firstDashAdjust; + // } + mr.draw([x, b], [x, e], this.canvas._ctx, opts); + b -= dashPat[j]; + if (j < dashPat.length-1) { + b -= dashPat[j+1]; + } + } + } + } + } + break; + + case 'rectangle': + // style and shadow properties should be set before + // every draw of marker renderer. + mr.style = 'line'; + opts.closePath = true; + + var xaxis = plot.axes[obj.options.xaxis], + xstart, + xstop, + y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y), + xminoff = obj.options.xminOffset || obj.options.xOffset, + xmaxoff = obj.options.xmaxOffset || obj.options.xOffset; + if (obj.options.xmin != null) { + xstart = xaxis.series_u2p(obj.options.xmin); + } + else if (xminoff != null) { + if ($.type(xminoff) == "number") { + xstart = xaxis.series_u2p(xaxis.min + xminoff); + } + else if ($.type(xminoff) == "string") { + xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff); + } + } + if (obj.options.xmax != null) { + xstop = xaxis.series_u2p(obj.options.xmax); + } + else if (xmaxoff != null) { + if ($.type(xmaxoff) == "number") { + xstop = xaxis.series_u2p(xaxis.max - xmaxoff); + } + else if ($.type(xmaxoff) == "string") { + xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff); + } + } + + var yaxis = plot.axes[obj.options.yaxis], + ystart, + ystop, + x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x), + yminoff = obj.options.yminOffset || obj.options.yOffset, + ymaxoff = obj.options.ymaxOffset || obj.options.yOffset; + if (obj.options.ymin != null) { + ystart = yaxis.series_u2p(obj.options.ymin); + } + else if (yminoff != null) { + if ($.type(yminoff) == "number") { + ystart = yaxis.series_u2p(yaxis.min - yminoff); + } + else if ($.type(yminoff) == "string") { + ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff); + } + } + if (obj.options.ymax != null) { + ystop = yaxis.series_u2p(obj.options.ymax); + } + else if (ymaxoff != null) { + if ($.type(ymaxoff) == "number") { + ystop = yaxis.series_u2p(yaxis.max + ymaxoff); + } + else if ($.type(ymaxoff) == "string") { + ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff); + } + } + + + if (xstop != null && xstart != null && ystop != null && ystart != null) { + obj.gridStart = [xstart, ystart]; + obj.gridStop = [xstop, ystop]; + + this.canvas._ctx.fillStyle = obj.options.color; + this.canvas._ctx.fillRect(xstart, ystart, xstop - xstart, ystop - ystart); + } + break; + + default: + break; + } + } + } + } + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + $.jqplot.CanvasOverlay.postPlotDraw = function() { + var co = this.plugins.canvasOverlay; + // Memory Leaks patch + if (co && co.highlightCanvas) { + co.highlightCanvas.resetCanvas(); + co.highlightCanvas = null; + } + co.canvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this)); + co.canvas.setContext(); + if (!co.deferDraw) { + co.draw(this); + } + + var elem = document.createElement('div'); + co._tooltipElem = $(elem); + elem = null; + co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip'); + co._tooltipElem.css({position:'absolute', display:'none'}); + + this.eventCanvas._elem.before(co._tooltipElem); + this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); }); + + var co = null; + }; + + + function showTooltip(plot, obj, gridpos, datapos) { + var co = plot.plugins.canvasOverlay; + var elem = co._tooltipElem; + + var opts = obj.options, x, y; + + elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1])); + + switch (opts.tooltipLocation) { + case 'nw': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'n': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'ne': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + case 'e': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + case 'se': + x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 's': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 'sw': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset; + break; + case 'w': + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + default: // same as 'nw' + x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset; + y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true); + break; + } + + elem.css('left', x); + elem.css('top', y); + if (opts.fadeTooltip) { + // Fix for stacked up animations. Thnanks Trevor! + elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed); + } + else { + elem.show(); + } + elem = null; + } + + + function isNearLine(point, lstart, lstop, width) { + // r is point to test, p and q are end points. + var rx = point[0]; + var ry = point[1]; + var px = Math.round(lstop[0]); + var py = Math.round(lstop[1]); + var qx = Math.round(lstart[0]); + var qy = Math.round(lstart[1]); + + var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2)); + + // scale error term by length of line. + var eps = width*l; + var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px)); + var ret = (res < eps) ? true : false; + return ret; + } + + function isNearRectangle(point, lstart, lstop, width) { + // r is point to test, p and q are end points. + var rx = point[0]; + var ry = point[1]; + var px = Math.round(lstop[0]); + var py = Math.round(lstop[1]); + var qx = Math.round(lstart[0]); + var qy = Math.round(lstart[1]); + + var temp; + if (px > qx) { temp = px; px = qx; qx = temp; } + if (py > qy) { temp = py; py = qy; qy = temp; } + + var ret = (rx >= px && rx <= qx && ry >= py && ry <= qy); + + return ret; + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + var co = plot.plugins.canvasOverlay; + var objs = co.objects; + var l = objs.length; + var obj, haveHighlight=false; + var elem; + for (var i=0; i<l; i++) { + obj = objs[i]; + if (obj.options.showTooltip) { + var n; + if (obj.type === 'rectangle') { + n = isNearRectangle([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor); + } else { + n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor); + } + datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)]; + + // cases: + // near line, no highlighting + // near line, highliting on this line + // near line, highlighting another line + // not near any line, highlighting + // not near any line, no highlighting + + // near line, not currently highlighting + if (n && co.highlightObjectIndex == null) { + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + case 'rectangle': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + default: + break; + } + co.highlightObjectIndex = i; + haveHighlight = true; + break; + } + + // near line, highlighting another line. + else if (n && co.highlightObjectIndex !== i) { + // turn off tooltip. + elem = co._tooltipElem; + if (obj.fadeTooltip) { + elem.fadeOut(obj.tooltipFadeSpeed); + } + else { + elem.hide(); + } + + // turn on right tooltip. + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + case 'rectangle': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + default: + break; + } + + co.highlightObjectIndex = i; + haveHighlight = true; + break; + } + + // near line, already highlighting this line, update + else if (n) { + switch (obj.type) { + case 'line': + showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos); + break; + + case 'horizontalLine': + case 'dashedHorizontalLine': + showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]); + break; + + case 'verticalLine': + case 'dashedVerticalLine': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + case 'rectangle': + showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]); + break; + + default: + break; + } + + haveHighlight = true; + break; + } + } + } + + // check if we are highlighting and not near a line, turn it off. + if (!haveHighlight && co.highlightObjectIndex !== null) { + elem = co._tooltipElem; + obj = co.getObject(co.highlightObjectIndex); + if (obj.fadeTooltip) { + elem.fadeOut(obj.tooltipFadeSpeed); + } + else { + elem.hide(); + } + co.highlightObjectIndex = null; + } + } + + $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit); + $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.min.js new file mode 100644 index 0000000..264f39b --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasOverlay.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(d){var f=0;d.jqplot.CanvasOverlay=function(q){var o=q||{};this.options={show:d.jqplot.config.enablePlugins,deferDraw:false};this.objects=[];this.objectNames=[];this.canvas=null;this.markerRenderer=new d.jqplot.MarkerRenderer({style:"line"});this.markerRenderer.init();this.highlightObjectIndex=null;if(o.objects){var s=o.objects,r;for(var p=0;p<s.length;p++){r=s[p];for(var t in r){switch(t){case"line":this.addLine(r[t]);break;case"horizontalLine":this.addHorizontalLine(r[t]);break;case"dashedHorizontalLine":this.addDashedHorizontalLine(r[t]);break;case"verticalLine":this.addVerticalLine(r[t]);break;case"dashedVerticalLine":this.addDashedVerticalLine(r[t]);break;case"rectangle":this.addRectangle(r[t]);break;default:break}}}}d.extend(true,this.options,o)};d.jqplot.CanvasOverlay.postPlotInit=function(q,p,o){var n=o||{};this.plugins.canvasOverlay=new d.jqplot.CanvasOverlay(n.canvasOverlay)};function i(){this.uid=null;this.type=null;this.gridStart=null;this.gridStop=null;this.tooltipWidthFactor=0;this.options={name:null,show:true,lineWidth:2,lineCap:"round",color:"#666666",shadow:true,shadowAngle:45,shadowOffset:1,shadowDepth:3,shadowAlpha:"0.07",xaxis:"xaxis",yaxis:"yaxis",showTooltip:false,showTooltipPrecision:0.6,tooltipLocation:"nw",fadeTooltip:true,tooltipFadeSpeed:"fast",tooltipOffset:4,tooltipFormatString:"%d, %d"}}function m(n){i.call(this);this.type="rectangle";var o={xmin:null,xmax:null,xOffset:"6px",xminOffset:null,xmaxOffset:null,ymin:null,ymax:null,yOffset:"6px",yminOffset:null,ymaxOffset:null};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}m.prototype=new i();m.prototype.constructor=m;function b(n){i.call(this);this.type="line";var o={start:[],stop:[]};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}b.prototype=new i();b.prototype.constructor=b;function e(n){i.call(this);this.type="horizontalLine";var o={y:null,xmin:null,xmax:null,xOffset:"6px",xminOffset:null,xmaxOffset:null};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}e.prototype=new i();e.prototype.constructor=e;function j(n){i.call(this);this.type="dashedHorizontalLine";var o={y:null,xmin:null,xmax:null,xOffset:"6px",xminOffset:null,xmaxOffset:null,dashPattern:[8,8]};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}j.prototype=new i();j.prototype.constructor=j;function c(n){i.call(this);this.type="verticalLine";var o={x:null,ymin:null,ymax:null,yOffset:"6px",yminOffset:null,ymaxOffset:null};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}c.prototype=new i();c.prototype.constructor=c;function l(n){i.call(this);this.type="dashedVerticalLine";this.start=null;this.stop=null;var o={x:null,ymin:null,ymax:null,yOffset:"6px",yminOffset:null,ymaxOffset:null,dashPattern:[8,8]};d.extend(true,this.options,o,n);if(this.options.showTooltipPrecision<0.01){this.options.showTooltipPrecision=0.01}}l.prototype=new i();l.prototype.constructor=l;d.jqplot.CanvasOverlay.prototype.addLine=function(o){var n=new b(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.addHorizontalLine=function(o){var n=new e(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine=function(o){var n=new j(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.addVerticalLine=function(o){var n=new c(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.addDashedVerticalLine=function(o){var n=new l(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.addRectangle=function(o){var n=new m(o);n.uid=f++;this.objects.push(n);this.objectNames.push(n.options.name)};d.jqplot.CanvasOverlay.prototype.removeObject=function(n){if(d.type(n)=="number"){this.objects.splice(n,1);this.objectNames.splice(n,1)}else{var o=d.inArray(n,this.objectNames);if(o!=-1){this.objects.splice(o,1);this.objectNames.splice(o,1)}}};d.jqplot.CanvasOverlay.prototype.getObject=function(n){if(d.type(n)=="number"){return this.objects[n]}else{var o=d.inArray(n,this.objectNames);if(o!=-1){return this.objects[o]}}};d.jqplot.CanvasOverlay.prototype.get=d.jqplot.CanvasOverlay.prototype.getObject;d.jqplot.CanvasOverlay.prototype.clear=function(n){this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(),this.canvas.getHeight())};d.jqplot.CanvasOverlay.prototype.draw=function(K){var A,v=this.objects,F=this.markerRenderer,s,G;if(this.options.show){this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(),this.canvas.getHeight());for(var H=0;H<v.length;H++){A=v[H];var B=d.extend(true,{},A.options);if(A.options.show){F.shadow=A.options.shadow;A.tooltipWidthFactor=A.options.lineWidth/A.options.showTooltipPrecision;switch(A.type){case"line":F.style="line";B.closePath=false;s=[K.axes[A.options.xaxis].series_u2p(A.options.start[0]),K.axes[A.options.yaxis].series_u2p(A.options.start[1])];G=[K.axes[A.options.xaxis].series_u2p(A.options.stop[0]),K.axes[A.options.yaxis].series_u2p(A.options.stop[1])];A.gridStart=s;A.gridStop=G;F.draw(s,G,this.canvas._ctx,B);break;case"horizontalLine":if(A.options.y!=null){F.style="line";B.closePath=false;var p=K.axes[A.options.xaxis],S,L,w=K.axes[A.options.yaxis].series_u2p(A.options.y),I=A.options.xminOffset||A.options.xOffset,t=A.options.xmaxOffset||A.options.xOffset;if(A.options.xmin!=null){S=p.series_u2p(A.options.xmin)}else{if(I!=null){if(d.type(I)=="number"){S=p.series_u2p(p.min+I)}else{if(d.type(I)=="string"){S=p.series_u2p(p.min)+parseFloat(I)}}}}if(A.options.xmax!=null){L=p.series_u2p(A.options.xmax)}else{if(t!=null){if(d.type(t)=="number"){L=p.series_u2p(p.max-t)}else{if(d.type(t)=="string"){L=p.series_u2p(p.max)-parseFloat(t)}}}}if(L!=null&&S!=null){A.gridStart=[S,w];A.gridStop=[L,w];F.draw([S,w],[L,w],this.canvas._ctx,B)}}break;case"dashedHorizontalLine":var o=A.options.dashPattern;var E=0;for(var M=0;M<o.length;M++){E+=o[M]}if(A.options.y!=null){F.style="line";B.closePath=false;var p=K.axes[A.options.xaxis],S,L,w=K.axes[A.options.yaxis].series_u2p(A.options.y),I=A.options.xminOffset||A.options.xOffset,t=A.options.xmaxOffset||A.options.xOffset;if(A.options.xmin!=null){S=p.series_u2p(A.options.xmin)}else{if(I!=null){if(d.type(I)=="number"){S=p.series_u2p(p.min+I)}else{if(d.type(I)=="string"){S=p.series_u2p(p.min)+parseFloat(I)}}}}if(A.options.xmax!=null){L=p.series_u2p(A.options.xmax)}else{if(t!=null){if(d.type(t)=="number"){L=p.series_u2p(p.max-t)}else{if(d.type(t)=="string"){L=p.series_u2p(p.max)-parseFloat(t)}}}}if(L!=null&&S!=null){A.gridStart=[S,w];A.gridStop=[L,w];var r=Math.ceil((L-S)/E);var Q=S,O;for(var M=0;M<r;M++){for(var J=0;J<o.length;J+=2){O=Q+o[J];F.draw([Q,w],[O,w],this.canvas._ctx,B);Q+=o[J];if(J<o.length-1){Q+=o[J+1]}}}}}break;case"verticalLine":if(A.options.x!=null){F.style="line";B.closePath=false;var N=K.axes[A.options.yaxis],n,u,z=K.axes[A.options.xaxis].series_u2p(A.options.x),D=A.options.yminOffset||A.options.yOffset,q=A.options.ymaxOffset||A.options.yOffset;if(A.options.ymin!=null){n=N.series_u2p(A.options.ymin)}else{if(D!=null){if(d.type(D)=="number"){n=N.series_u2p(N.min-D)}else{if(d.type(D)=="string"){n=N.series_u2p(N.min)-parseFloat(D)}}}}if(A.options.ymax!=null){u=N.series_u2p(A.options.ymax)}else{if(q!=null){if(d.type(q)=="number"){u=N.series_u2p(N.max+q)}else{if(d.type(q)=="string"){u=N.series_u2p(N.max)+parseFloat(q)}}}}if(u!=null&&n!=null){A.gridStart=[z,n];A.gridStop=[z,u];F.draw([z,n],[z,u],this.canvas._ctx,B)}}break;case"dashedVerticalLine":var o=A.options.dashPattern;var E=0;for(var M=0;M<o.length;M++){E+=o[M]}if(A.options.x!=null){F.style="line";B.closePath=false;var N=K.axes[A.options.yaxis],n,u,z=K.axes[A.options.xaxis].series_u2p(A.options.x),D=A.options.yminOffset||A.options.yOffset,q=A.options.ymaxOffset||A.options.yOffset;if(A.options.ymin!=null){n=N.series_u2p(A.options.ymin)}else{if(D!=null){if(d.type(D)=="number"){n=N.series_u2p(N.min-D)}else{if(d.type(D)=="string"){n=N.series_u2p(N.min)-parseFloat(D)}}}}if(A.options.ymax!=null){u=N.series_u2p(A.options.ymax)}else{if(q!=null){if(d.type(q)=="number"){u=N.series_u2p(N.max+q)}else{if(d.type(q)=="string"){u=N.series_u2p(N.max)+parseFloat(q)}}}}if(u!=null&&n!=null){A.gridStart=[z,n];A.gridStop=[z,u];var r=Math.ceil((n-u)/E);var C=((r*E)-(n-u))/2;var Q=n,O,P,R;for(var M=0;M<r;M++){for(var J=0;J<o.length;J+=2){O=Q-o[J];if(O<u){O=u}if(Q<u){Q=u}F.draw([z,Q],[z,O],this.canvas._ctx,B);Q-=o[J];if(J<o.length-1){Q-=o[J+1]}}}}}break;case"rectangle":F.style="line";B.closePath=true;var p=K.axes[A.options.xaxis],S,L,w=K.axes[A.options.yaxis].series_u2p(A.options.y),I=A.options.xminOffset||A.options.xOffset,t=A.options.xmaxOffset||A.options.xOffset;if(A.options.xmin!=null){S=p.series_u2p(A.options.xmin)}else{if(I!=null){if(d.type(I)=="number"){S=p.series_u2p(p.min+I)}else{if(d.type(I)=="string"){S=p.series_u2p(p.min)+parseFloat(I)}}}}if(A.options.xmax!=null){L=p.series_u2p(A.options.xmax)}else{if(t!=null){if(d.type(t)=="number"){L=p.series_u2p(p.max-t)}else{if(d.type(t)=="string"){L=p.series_u2p(p.max)-parseFloat(t)}}}}var N=K.axes[A.options.yaxis],n,u,z=K.axes[A.options.xaxis].series_u2p(A.options.x),D=A.options.yminOffset||A.options.yOffset,q=A.options.ymaxOffset||A.options.yOffset;if(A.options.ymin!=null){n=N.series_u2p(A.options.ymin)}else{if(D!=null){if(d.type(D)=="number"){n=N.series_u2p(N.min-D)}else{if(d.type(D)=="string"){n=N.series_u2p(N.min)-parseFloat(D)}}}}if(A.options.ymax!=null){u=N.series_u2p(A.options.ymax)}else{if(q!=null){if(d.type(q)=="number"){u=N.series_u2p(N.max+q)}else{if(d.type(q)=="string"){u=N.series_u2p(N.max)+parseFloat(q)}}}}if(L!=null&&S!=null&&u!=null&&n!=null){A.gridStart=[S,n];A.gridStop=[L,u];this.canvas._ctx.fillStyle=A.options.color;this.canvas._ctx.fillRect(S,n,L-S,u-n)}break;default:break}}}}};d.jqplot.CanvasOverlay.postPlotDraw=function(){var o=this.plugins.canvasOverlay;if(o&&o.highlightCanvas){o.highlightCanvas.resetCanvas();o.highlightCanvas=null}o.canvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(o.canvas.createElement(this._gridPadding,"jqplot-overlayCanvas-canvas",this._plotDimensions,this));o.canvas.setContext();if(!o.deferDraw){o.draw(this)}var n=document.createElement("div");o._tooltipElem=d(n);n=null;o._tooltipElem.addClass("jqplot-canvasOverlay-tooltip");o._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(o._tooltipElem);this.eventCanvas._elem.bind("mouseleave",{elem:o._tooltipElem},function(p){p.data.elem.hide()});var o=null};function k(s,q,r,p){var u=s.plugins.canvasOverlay;var o=u._tooltipElem;var n=q.options,v,t;o.html(d.jqplot.sprintf(n.tooltipFormatString,p[0],p[1]));switch(n.tooltipLocation){case"nw":v=r[0]+s._gridPadding.left-o.outerWidth(true)-n.tooltipOffset;t=r[1]+s._gridPadding.top-n.tooltipOffset-o.outerHeight(true);break;case"n":v=r[0]+s._gridPadding.left-o.outerWidth(true)/2;t=r[1]+s._gridPadding.top-n.tooltipOffset-o.outerHeight(true);break;case"ne":v=r[0]+s._gridPadding.left+n.tooltipOffset;t=r[1]+s._gridPadding.top-n.tooltipOffset-o.outerHeight(true);break;case"e":v=r[0]+s._gridPadding.left+n.tooltipOffset;t=r[1]+s._gridPadding.top-o.outerHeight(true)/2;break;case"se":v=r[0]+s._gridPadding.left+n.tooltipOffset;t=r[1]+s._gridPadding.top+n.tooltipOffset;break;case"s":v=r[0]+s._gridPadding.left-o.outerWidth(true)/2;t=r[1]+s._gridPadding.top+n.tooltipOffset;break;case"sw":v=r[0]+s._gridPadding.left-o.outerWidth(true)-n.tooltipOffset;t=r[1]+s._gridPadding.top+n.tooltipOffset;break;case"w":v=r[0]+s._gridPadding.left-o.outerWidth(true)-n.tooltipOffset;t=r[1]+s._gridPadding.top-o.outerHeight(true)/2;break;default:v=r[0]+s._gridPadding.left-o.outerWidth(true)-n.tooltipOffset;t=r[1]+s._gridPadding.top-n.tooltipOffset-o.outerHeight(true);break}o.css("left",v);o.css("top",t);if(n.fadeTooltip){o.stop(true,true).fadeIn(n.tooltipFadeSpeed)}else{o.show()}o=null}function h(z,q,s,p){var o=z[0];var n=z[1];var y=Math.round(s[0]);var x=Math.round(s[1]);var u=Math.round(q[0]);var t=Math.round(q[1]);var r=Math.sqrt(Math.pow(y-u,2)+Math.pow(x-t,2));var A=p*r;var w=Math.abs((u-y)*(n-x)-(t-x)*(o-y));var v=(w<A)?true:false;return v}function g(x,q,r,p){var o=x[0];var n=x[1];var w=Math.round(r[0]);var v=Math.round(r[1]);var t=Math.round(q[0]);var s=Math.round(q[1]);var y;if(w>t){y=w;w=t;t=y}if(v>s){y=v;v=s;s=y}var u=(o>=w&&o<=t&&n>=v&&n<=s);return u}function a(z,w,r,A,x){var y=x.plugins.canvasOverlay;var v=y.objects;var s=v.length;var u,o=false;var q;for(var t=0;t<s;t++){u=v[t];if(u.options.showTooltip){var p;if(u.type==="rectangle"){p=g([w.x,w.y],u.gridStart,u.gridStop,u.tooltipWidthFactor)}else{p=h([w.x,w.y],u.gridStart,u.gridStop,u.tooltipWidthFactor)}r=[x.axes[u.options.xaxis].series_p2u(w.x),x.axes[u.options.yaxis].series_p2u(w.y)];if(p&&y.highlightObjectIndex==null){switch(u.type){case"line":k(x,u,[w.x,w.y],r);break;case"horizontalLine":case"dashedHorizontalLine":k(x,u,[w.x,u.gridStart[1]],[r[0],u.options.y]);break;case"verticalLine":case"dashedVerticalLine":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;case"rectangle":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;default:break}y.highlightObjectIndex=t;o=true;break}else{if(p&&y.highlightObjectIndex!==t){q=y._tooltipElem;if(u.fadeTooltip){q.fadeOut(u.tooltipFadeSpeed)}else{q.hide()}switch(u.type){case"line":k(x,u,[w.x,w.y],r);break;case"horizontalLine":case"dashedHorizontalLine":k(x,u,[w.x,u.gridStart[1]],[r[0],u.options.y]);break;case"verticalLine":case"dashedVerticalLine":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;case"rectangle":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;default:break}y.highlightObjectIndex=t;o=true;break}else{if(p){switch(u.type){case"line":k(x,u,[w.x,w.y],r);break;case"horizontalLine":case"dashedHorizontalLine":k(x,u,[w.x,u.gridStart[1]],[r[0],u.options.y]);break;case"verticalLine":case"dashedVerticalLine":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;case"rectangle":k(x,u,[u.gridStart[0],w.y],[u.options.x,r[1]]);break;default:break}o=true;break}}}}}if(!o&&y.highlightObjectIndex!==null){q=y._tooltipElem;u=y.getObject(y.highlightObjectIndex);if(u.fadeTooltip){q.fadeOut(u.tooltipFadeSpeed)}else{q.hide()}y.highlightObjectIndex=null}}d.jqplot.postInitHooks.push(d.jqplot.CanvasOverlay.postPlotInit);d.jqplot.postDrawHooks.push(d.jqplot.CanvasOverlay.postPlotDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",a])})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.js new file mode 100644 index 0000000..dc8434e --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.js @@ -0,0 +1,449 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + * included jsDate library by Chris Leonello: + * + * Copyright (c) 2010-2013 Chris Leonello + * + * jsDate is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * jsDate borrows many concepts and ideas from the Date Instance + * Methods by Ken Snyder along with some parts of Ken's actual code. + * + * Ken's original Date Instance Methods and copyright notice: + * + * Ken Snyder (ken d snyder at gmail dot com) + * 2008-09-10 + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) + * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) + * + * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js. + * Larry has generously given permission to adapt his code for inclusion + * into jqPlot. + * + * Larry's original code can be found here: + * + * https://github.com/lsiden/export-jqplot-to-png + * + * + */ + +(function($) { + // This code is a modified version of the canvastext.js code, copyright below: + // + // This code is released to the public domain by Jim Studt, 2007. + // He may keep some sort of up to date copy at http://www.federated.com/~jim/canvastext/ + // + $.jqplot.CanvasTextRenderer = function(options){ + this.fontStyle = 'normal'; // normal, italic, oblique [not implemented] + this.fontVariant = 'normal'; // normal, small caps [not implemented] + this.fontWeight = 'normal'; // normal, bold, bolder, lighter, 100 - 900 + this.fontSize = '10px'; + this.fontFamily = 'sans-serif'; + this.fontStretch = 1.0; + this.fillStyle = '#666666'; + this.angle = 0; + this.textAlign = 'start'; + this.textBaseline = 'alphabetic'; + this.text; + this.width; + this.height; + this.pt2px = 1.28; + + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + $.jqplot.CanvasTextRenderer.prototype.init = function(options) { + $.extend(true, this, options); + this.normalizedFontSize = this.normalizeFontSize(this.fontSize); + this.setHeight(); + }; + + // convert css spec into point size + // returns float + $.jqplot.CanvasTextRenderer.prototype.normalizeFontSize = function(sz) { + sz = String(sz); + var n = parseFloat(sz); + if (sz.indexOf('px') > -1) { + return n/this.pt2px; + } + else if (sz.indexOf('pt') > -1) { + return n; + } + else if (sz.indexOf('em') > -1) { + return n*12; + } + else if (sz.indexOf('%') > -1) { + return n*12/100; + } + // default to pixels; + else { + return n/this.pt2px; + } + }; + + + $.jqplot.CanvasTextRenderer.prototype.fontWeight2Float = function(w) { + // w = normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 + // return values adjusted for Hershey font. + if (Number(w)) { + return w/400; + } + else { + switch (w) { + case 'normal': + return 1; + break; + case 'bold': + return 1.75; + break; + case 'bolder': + return 2.25; + break; + case 'lighter': + return 0.75; + break; + default: + return 1; + break; + } + } + }; + + $.jqplot.CanvasTextRenderer.prototype.getText = function() { + return this.text; + }; + + $.jqplot.CanvasTextRenderer.prototype.setText = function(t, ctx) { + this.text = t; + this.setWidth(ctx); + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.getWidth = function(ctx) { + return this.width; + }; + + $.jqplot.CanvasTextRenderer.prototype.setWidth = function(ctx, w) { + if (!w) { + this.width = this.measure(ctx, this.text); + } + else { + this.width = w; + } + return this; + }; + + // return height in pixels. + $.jqplot.CanvasTextRenderer.prototype.getHeight = function(ctx) { + return this.height; + }; + + // w - height in pt + // set heigh in px + $.jqplot.CanvasTextRenderer.prototype.setHeight = function(w) { + if (!w) { + //height = this.fontSize /0.75; + this.height = this.normalizedFontSize * this.pt2px; + } + else { + this.height = w; + } + return this; + }; + + $.jqplot.CanvasTextRenderer.prototype.letter = function (ch) + { + return this.letters[ch]; + }; + + $.jqplot.CanvasTextRenderer.prototype.ascent = function() + { + return this.normalizedFontSize; + }; + + $.jqplot.CanvasTextRenderer.prototype.descent = function() + { + return 7.0*this.normalizedFontSize/25.0; + }; + + $.jqplot.CanvasTextRenderer.prototype.measure = function(ctx, str) + { + var total = 0; + var len = str.length; + + for (var i = 0; i < len; i++) { + var c = this.letter(str.charAt(i)); + if (c) { + total += c.width * this.normalizedFontSize / 25.0 * this.fontStretch; + } + } + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.draw = function(ctx,str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + var total = 0; + var len = str.length; + var mag = this.normalizedFontSize / 25.0; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.lineCap = "round"; + // multiplier was 2.0 + var fact = (this.normalizedFontSize > 30) ? 2.0 : 2 + (30 - this.normalizedFontSize)/20; + ctx.lineWidth = fact * mag * this.fontWeight2Float(this.fontWeight); + + for ( var i = 0; i < len; i++) { + var c = this.letter( str.charAt(i)); + if ( !c) { + continue; + } + + ctx.beginPath(); + + var penUp = 1; + var needStroke = 0; + for ( var j = 0; j < c.points.length; j++) { + var a = c.points[j]; + if ( a[0] == -1 && a[1] == -1) { + penUp = 1; + continue; + } + if ( penUp) { + ctx.moveTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + penUp = false; + } else { + ctx.lineTo( x + a[0]*mag*this.fontStretch, y - a[1]*mag); + } + } + ctx.stroke(); + x += c.width*mag*this.fontStretch; + } + ctx.restore(); + return total; + }; + + $.jqplot.CanvasTextRenderer.prototype.letters = { + ' ': { width: 16, points: [] }, + '!': { width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '"': { width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] }, + '#': { width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] }, + '$': { width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + '%': { width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] }, + '&': { width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] }, + '\'': { width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] }, + '(': { width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] }, + ')': { width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] }, + '*': { width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] }, + '+': { width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] }, + ',': { width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '-': { width: 18, points: [[6,9],[12,9]] }, + '.': { width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] }, + '/': { width: 22, points: [[20,25],[2,-7]] }, + '0': { width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] }, + '1': { width: 20, points: [[6,17],[8,18],[11,21],[11,0]] }, + '2': { width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] }, + '3': { width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '4': { width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] }, + '5': { width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] }, + '6': { width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] }, + '7': { width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] }, + '8': { width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] }, + '9': { width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] }, + ':': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] }, + ';': { width: 10, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] }, + '<': { width: 24, points: [[20,18],[4,9],[20,0]] }, + '=': { width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] }, + '>': { width: 24, points: [[4,18],[20,9],[4,0]] }, + '?': { width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] }, + '@': { width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] }, + 'A': { width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] }, + 'B': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] }, + 'C': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] }, + 'D': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] }, + 'E': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] }, + 'F': { width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] }, + 'G': { width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] }, + 'H': { width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] }, + 'I': { width: 8, points: [[4,21],[4,0]] }, + 'J': { width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] }, + 'K': { width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] }, + 'L': { width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] }, + 'M': { width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] }, + 'N': { width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] }, + 'O': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] }, + 'P': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] }, + 'Q': { width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] }, + 'R': { width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] }, + 'S': { width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] }, + 'T': { width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] }, + 'U': { width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] }, + 'V': { width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] }, + 'W': { width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] }, + 'X': { width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] }, + 'Y': { width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] }, + 'Z': { width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] }, + '[': { width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] }, + '\\': { width: 14, points: [[0,21],[14,-3]] }, + ']': { width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] }, + '^': { width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] }, + '_': { width: 16, points: [[0,-2],[16,-2]] }, + '`': { width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] }, + 'a': { width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'b': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'c': { width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'd': { width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'e': { width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'f': { width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] }, + 'g': { width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'h': { width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'i': { width: 8, points: [[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]] }, + 'j': { width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] }, + 'k': { width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] }, + 'l': { width: 8, points: [[4,21],[4,0]] }, + 'm': { width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] }, + 'n': { width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] }, + 'o': { width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] }, + 'p': { width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] }, + 'q': { width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] }, + 'r': { width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] }, + 's': { width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] }, + 't': { width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] }, + 'u': { width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] }, + 'v': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] }, + 'w': { width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] }, + 'x': { width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] }, + 'y': { width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] }, + 'z': { width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] }, + '{': { width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] }, + '|': { width: 8, points: [[4,25],[4,-7]] }, + '}': { width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] }, + '~': { width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] } + }; + + $.jqplot.CanvasFontRenderer = function(options) { + options = options || {}; + if (!options.pt2px) { + options.pt2px = 1.5; + } + $.jqplot.CanvasTextRenderer.call(this, options); + }; + + $.jqplot.CanvasFontRenderer.prototype = new $.jqplot.CanvasTextRenderer({}); + $.jqplot.CanvasFontRenderer.prototype.constructor = $.jqplot.CanvasFontRenderer; + + $.jqplot.CanvasFontRenderer.prototype.measure = function(ctx, str) + { + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.save(); + ctx.font = fstyle; + var w = ctx.measureText(str).width; + ctx.restore(); + return w; + }; + + $.jqplot.CanvasFontRenderer.prototype.draw = function(ctx, str) + { + var x = 0; + // leave room at bottom for descenders. + var y = this.height*0.72; + //var y = 12; + + ctx.save(); + var tx, ty; + + // 1st quadrant + if ((-Math.PI/2 <= this.angle && this.angle <= 0) || (Math.PI*3/2 <= this.angle && this.angle <= Math.PI*2)) { + tx = 0; + ty = -Math.sin(this.angle) * this.width; + } + // 4th quadrant + else if ((0 < this.angle && this.angle <= Math.PI/2) || (-Math.PI*2 <= this.angle && this.angle <= -Math.PI*3/2)) { + tx = Math.sin(this.angle) * this.height; + ty = 0; + } + // 2nd quadrant + else if ((-Math.PI < this.angle && this.angle < -Math.PI/2) || (Math.PI <= this.angle && this.angle <= Math.PI*3/2)) { + tx = -Math.cos(this.angle) * this.width; + ty = -Math.sin(this.angle) * this.width - Math.cos(this.angle) * this.height; + } + // 3rd quadrant + else if ((-Math.PI*3/2 < this.angle && this.angle < Math.PI) || (Math.PI/2 < this.angle && this.angle < Math.PI)) { + tx = Math.sin(this.angle) * this.height - Math.cos(this.angle)*this.width; + ty = -Math.cos(this.angle) * this.height; + } + ctx.strokeStyle = this.fillStyle; + ctx.fillStyle = this.fillStyle; + // var fstyle = this.fontStyle+' '+this.fontVariant+' '+this.fontWeight+' '+this.fontSize+' '+this.fontFamily; + var fstyle = this.fontSize+' '+this.fontFamily; + ctx.font = fstyle; + ctx.translate(tx, ty); + ctx.rotate(this.angle); + ctx.fillText(str, x, y); + // ctx.strokeText(str, x, y); + + ctx.restore(); + }; + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.min.js new file mode 100644 index 0000000..6f8d676 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.canvasTextRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.CanvasTextRenderer=function(b){this.fontStyle="normal";this.fontVariant="normal";this.fontWeight="normal";this.fontSize="10px";this.fontFamily="sans-serif";this.fontStretch=1;this.fillStyle="#666666";this.angle=0;this.textAlign="start";this.textBaseline="alphabetic";this.text;this.width;this.height;this.pt2px=1.28;a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.init=function(b){a.extend(true,this,b);this.normalizedFontSize=this.normalizeFontSize(this.fontSize);this.setHeight()};a.jqplot.CanvasTextRenderer.prototype.normalizeFontSize=function(b){b=String(b);var c=parseFloat(b);if(b.indexOf("px")>-1){return c/this.pt2px}else{if(b.indexOf("pt")>-1){return c}else{if(b.indexOf("em")>-1){return c*12}else{if(b.indexOf("%")>-1){return c*12/100}else{return c/this.pt2px}}}}};a.jqplot.CanvasTextRenderer.prototype.fontWeight2Float=function(b){if(Number(b)){return b/400}else{switch(b){case"normal":return 1;break;case"bold":return 1.75;break;case"bolder":return 2.25;break;case"lighter":return 0.75;break;default:return 1;break}}};a.jqplot.CanvasTextRenderer.prototype.getText=function(){return this.text};a.jqplot.CanvasTextRenderer.prototype.setText=function(c,b){this.text=c;this.setWidth(b);return this};a.jqplot.CanvasTextRenderer.prototype.getWidth=function(b){return this.width};a.jqplot.CanvasTextRenderer.prototype.setWidth=function(c,b){if(!b){this.width=this.measure(c,this.text)}else{this.width=b}return this};a.jqplot.CanvasTextRenderer.prototype.getHeight=function(b){return this.height};a.jqplot.CanvasTextRenderer.prototype.setHeight=function(b){if(!b){this.height=this.normalizedFontSize*this.pt2px}else{this.height=b}return this};a.jqplot.CanvasTextRenderer.prototype.letter=function(b){return this.letters[b]};a.jqplot.CanvasTextRenderer.prototype.ascent=function(){return this.normalizedFontSize};a.jqplot.CanvasTextRenderer.prototype.descent=function(){return 7*this.normalizedFontSize/25};a.jqplot.CanvasTextRenderer.prototype.measure=function(d,g){var f=0;var b=g.length;for(var e=0;e<b;e++){var h=this.letter(g.charAt(e));if(h){f+=h.width*this.normalizedFontSize/25*this.fontStretch}}return f};a.jqplot.CanvasTextRenderer.prototype.draw=function(s,n){var r=0;var o=this.height*0.72;var p=0;var l=n.length;var k=this.normalizedFontSize/25;s.save();var h,f;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){h=0;f=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){h=Math.sin(this.angle)*this.height;f=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){h=-Math.cos(this.angle)*this.width;f=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){h=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;f=-Math.cos(this.angle)*this.height}}}}s.strokeStyle=this.fillStyle;s.fillStyle=this.fillStyle;s.translate(h,f);s.rotate(this.angle);s.lineCap="round";var t=(this.normalizedFontSize>30)?2:2+(30-this.normalizedFontSize)/20;s.lineWidth=t*k*this.fontWeight2Float(this.fontWeight);for(var g=0;g<l;g++){var m=this.letter(n.charAt(g));if(!m){continue}s.beginPath();var e=1;var b=0;for(var d=0;d<m.points.length;d++){var q=m.points[d];if(q[0]==-1&&q[1]==-1){e=1;continue}if(e){s.moveTo(r+q[0]*k*this.fontStretch,o-q[1]*k);e=false}else{s.lineTo(r+q[0]*k*this.fontStretch,o-q[1]*k)}}s.stroke();r+=m.width*k*this.fontStretch}s.restore();return p};a.jqplot.CanvasTextRenderer.prototype.letters={" ":{width:16,points:[]},"!":{width:10,points:[[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},'"':{width:16,points:[[4,21],[4,14],[-1,-1],[12,21],[12,14]]},"#":{width:21,points:[[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]]},"$":{width:20,points:[[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},"%":{width:24,points:[[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]]},"&":{width:26,points:[[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]]},"'":{width:10,points:[[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]]},"(":{width:14,points:[[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]]},")":{width:14,points:[[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]]},"*":{width:16,points:[[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]]},"+":{width:26,points:[[13,18],[13,0],[-1,-1],[4,9],[22,9]]},",":{width:10,points:[[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"-":{width:18,points:[[6,9],[12,9]]},".":{width:10,points:[[5,2],[4,1],[5,0],[6,1],[5,2]]},"/":{width:22,points:[[20,25],[2,-7]]},"0":{width:20,points:[[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]]},"1":{width:20,points:[[6,17],[8,18],[11,21],[11,0]]},"2":{width:20,points:[[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]]},"3":{width:20,points:[[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"4":{width:20,points:[[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]]},"5":{width:20,points:[[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]]},"6":{width:20,points:[[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]]},"7":{width:20,points:[[17,21],[7,0],[-1,-1],[3,21],[17,21]]},"8":{width:20,points:[[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]]},"9":{width:20,points:[[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]]},":":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]]},";":{width:10,points:[[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]]},"<":{width:24,points:[[20,18],[4,9],[20,0]]},"=":{width:26,points:[[4,12],[22,12],[-1,-1],[4,6],[22,6]]},">":{width:24,points:[[4,18],[20,9],[4,0]]},"?":{width:18,points:[[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]]},"@":{width:27,points:[[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]]},A:{width:18,points:[[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]]},B:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]]},C:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]]},D:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]]},E:{width:19,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]]},F:{width:18,points:[[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]]},G:{width:21,points:[[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]]},H:{width:22,points:[[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]]},I:{width:8,points:[[4,21],[4,0]]},J:{width:16,points:[[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]]},K:{width:21,points:[[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]]},L:{width:17,points:[[4,21],[4,0],[-1,-1],[4,0],[16,0]]},M:{width:24,points:[[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]]},N:{width:22,points:[[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]]},O:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]]},P:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]]},Q:{width:22,points:[[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]]},R:{width:21,points:[[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]]},S:{width:20,points:[[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]]},T:{width:16,points:[[8,21],[8,0],[-1,-1],[1,21],[15,21]]},U:{width:22,points:[[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]]},V:{width:18,points:[[1,21],[9,0],[-1,-1],[17,21],[9,0]]},W:{width:24,points:[[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]]},X:{width:20,points:[[3,21],[17,0],[-1,-1],[17,21],[3,0]]},Y:{width:18,points:[[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]]},Z:{width:20,points:[[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]]},"[":{width:14,points:[[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]]},"\\":{width:14,points:[[0,21],[14,-3]]},"]":{width:14,points:[[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]]},"^":{width:16,points:[[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]]},_:{width:16,points:[[0,-2],[16,-2]]},"`":{width:10,points:[[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]]},a:{width:19,points:[[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},b:{width:19,points:[[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},c:{width:18,points:[[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},d:{width:19,points:[[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},e:{width:18,points:[[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},f:{width:12,points:[[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]]},g:{width:19,points:[[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},h:{width:19,points:[[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},i:{width:8,points:[[3,21],[4,20],[5,21],[4,22],[3,21],[-1,-1],[4,14],[4,0]]},j:{width:10,points:[[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]]},k:{width:17,points:[[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]]},l:{width:8,points:[[4,21],[4,0]]},m:{width:30,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]]},n:{width:19,points:[[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]]},o:{width:19,points:[[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]]},p:{width:19,points:[[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]]},q:{width:19,points:[[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]]},r:{width:13,points:[[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]]},s:{width:17,points:[[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]]},t:{width:12,points:[[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]]},u:{width:19,points:[[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]]},v:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0]]},w:{width:22,points:[[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]]},x:{width:17,points:[[3,14],[14,0],[-1,-1],[14,14],[3,0]]},y:{width:16,points:[[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]]},z:{width:17,points:[[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]]},"{":{width:14,points:[[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]]},"|":{width:8,points:[[4,25],[4,-7]]},"}":{width:14,points:[[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]]},"~":{width:24,points:[[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]]}};a.jqplot.CanvasFontRenderer=function(b){b=b||{};if(!b.pt2px){b.pt2px=1.5}a.jqplot.CanvasTextRenderer.call(this,b)};a.jqplot.CanvasFontRenderer.prototype=new a.jqplot.CanvasTextRenderer({});a.jqplot.CanvasFontRenderer.prototype.constructor=a.jqplot.CanvasFontRenderer;a.jqplot.CanvasFontRenderer.prototype.measure=function(c,e){var d=this.fontSize+" "+this.fontFamily;c.save();c.font=d;var b=c.measureText(e).width;c.restore();return b};a.jqplot.CanvasFontRenderer.prototype.draw=function(e,g){var c=0;var h=this.height*0.72;e.save();var d,b;if((-Math.PI/2<=this.angle&&this.angle<=0)||(Math.PI*3/2<=this.angle&&this.angle<=Math.PI*2)){d=0;b=-Math.sin(this.angle)*this.width}else{if((0<this.angle&&this.angle<=Math.PI/2)||(-Math.PI*2<=this.angle&&this.angle<=-Math.PI*3/2)){d=Math.sin(this.angle)*this.height;b=0}else{if((-Math.PI<this.angle&&this.angle<-Math.PI/2)||(Math.PI<=this.angle&&this.angle<=Math.PI*3/2)){d=-Math.cos(this.angle)*this.width;b=-Math.sin(this.angle)*this.width-Math.cos(this.angle)*this.height}else{if((-Math.PI*3/2<this.angle&&this.angle<Math.PI)||(Math.PI/2<this.angle&&this.angle<Math.PI)){d=Math.sin(this.angle)*this.height-Math.cos(this.angle)*this.width;b=-Math.cos(this.angle)*this.height}}}}e.strokeStyle=this.fillStyle;e.fillStyle=this.fillStyle;var f=this.fontSize+" "+this.fontFamily;e.font=f;e.translate(d,b);e.rotate(this.angle);e.fillText(g,c,h);e.restore()}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js new file mode 100644 index 0000000..aa77120 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.js @@ -0,0 +1,679 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * class: $.jqplot.CategoryAxisRenderer + * A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series. + * + * To use this renderer, include the plugin in your source + * > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script> + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}} + **/ + $.jqplot.CategoryAxisRenderer = function(options) { + $.jqplot.LinearAxisRenderer.call(this); + // prop: sortMergedLabels + // True to sort tick labels when labels are created by merging + // x axis values from multiple series. That is, say you have + // two series like: + // > line1 = [[2006, 4], [2008, 9], [2009, 16]]; + // > line2 = [[2006, 3], [2007, 7], [2008, 6]]; + // If no label array is specified, tick labels will be collected + // from the x values of the series. With sortMergedLabels + // set to true, tick labels will be: + // > [2006, 2007, 2008, 2009] + // With sortMergedLabels set to false, tick labels will be: + // > [2006, 2008, 2009, 2007] + // + // Note, this property is specified on the renderOptions for the + // axes when creating a plot: + // > axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer, rendererOptions:{sortMergedLabels:true}}} + this.sortMergedLabels = false; + }; + + $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer; + + $.jqplot.CategoryAxisRenderer.prototype.init = function(options){ + this.groups = 1; + this.groupLabels = []; + this._groupLabels = []; + this._grouped = false; + this._barsPerGroup = null; + this.reverse = false; + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + $.extend(true, this, {tickOptions:{formatString:'%d'}}, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + if (s.groups) { + this.groups = s.groups; + } + var d = s.data; + + for (var j=0; j<d.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + if (d[j][0] < db.min || db.min == null) { + db.min = d[j][0]; + } + if (d[j][0] > db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + + if (this.groupLabels.length) { + this.groups = this.groupLabels.length; + } + }; + + + $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var tt, i; + + // if we already have ticks, use them. + if (userTicks.length) { + // adjust with blanks if we have groups + if (this.groups > 1 && !this._grouped) { + var l = userTicks.length; + var skip = parseInt(l/this.groups, 10); + var count = 0; + for (var i=skip; i<l; i+=skip) { + userTicks.splice(i+count, 0, ' '); + count++; + } + this._grouped = true; + } + this.min = 0.5; + this.max = userTicks.length + 0.5; + var range = this.max - this.min; + this.numberTicks = 2*userTicks.length + 1; + for (i=0; i<userTicks.length; i++){ + tt = this.min + 2 * i * range / (this.numberTicks-1); + // need a marker before and after the tick + var t = new this.tickRenderer(this.tickOptions); + t.showLabel = false; + // t.showMark = true; + t.setTick(tt, this.name); + this._ticks.push(t); + var t = new this.tickRenderer(this.tickOptions); + t.label = userTicks[i]; + // t.showLabel = true; + t.showMark = false; + t.showGridline = false; + t.setTick(tt+0.5, this.name); + this._ticks.push(t); + } + // now add the last tick at the end + var t = new this.tickRenderer(this.tickOptions); + t.showLabel = false; + // t.showMark = true; + t.setTick(tt+1, this.name); + this._ticks.push(t); + } + + // we don't have any ticks yet, let's make some! + else { + if (name == 'xaxis' || name == 'x2axis') { + dim = this._plotDimensions.width; + } + else { + dim = this._plotDimensions.height; + } + + // if min, max and number of ticks specified, user can't specify interval. + if (this.min != null && this.max != null && this.numberTicks != null) { + this.tickInterval = null; + } + + // if max, min, and interval specified and interval won't fit, ignore interval. + if (this.min != null && this.max != null && this.tickInterval != null) { + if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) { + this.tickInterval = null; + } + } + + // find out how many categories are in the lines and collect labels + var labels = []; + var numcats = 0; + var min = 0.5; + var max, val; + var isMerged = false; + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + for (var j=0; j<s.data.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + val = s.data[j][0]; + } + else { + val = s.data[j][1]; + } + if ($.inArray(val, labels) == -1) { + isMerged = true; + numcats += 1; + labels.push(val); + } + } + } + + if (isMerged && this.sortMergedLabels) { + if (typeof labels[0] == "string") { + labels.sort(); + } else { + labels.sort(function(a,b) { return a - b; }); + } + } + + // keep a reference to these tick labels to use for redrawing plot (see bug #57) + this.ticks = labels; + + // now bin the data values to the right lables. + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + for (var j=0; j<s.data.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + val = s.data[j][0]; + } + else { + val = s.data[j][1]; + } + // for category axis, force the values into category bins. + // we should have the value in the label array now. + var idx = $.inArray(val, labels)+1; + if (this.name == 'xaxis' || this.name == 'x2axis') { + s.data[j][0] = idx; + } + else { + s.data[j][1] = idx; + } + } + } + + // adjust with blanks if we have groups + if (this.groups > 1 && !this._grouped) { + var l = labels.length; + var skip = parseInt(l/this.groups, 10); + var count = 0; + for (var i=skip; i<l; i+=skip+1) { + labels[i] = ' '; + } + this._grouped = true; + } + + max = numcats + 0.5; + if (this.numberTicks == null) { + this.numberTicks = 2*numcats + 1; + } + + var range = max - min; + this.min = min; + this.max = max; + var track = 0; + + // todo: adjust this so more ticks displayed. + var maxVisibleTicks = parseInt(3+dim/10, 10); + var skip = parseInt(numcats/maxVisibleTicks, 10); + + if (this.tickInterval == null) { + + this.tickInterval = range / (this.numberTicks-1); + + } + // if tickInterval is specified, we will ignore any computed maximum. + for (var i=0; i<this.numberTicks; i++){ + tt = this.min + i * this.tickInterval; + var t = new this.tickRenderer(this.tickOptions); + // if even tick, it isn't a category, it's a divider + if (i/2 == parseInt(i/2, 10)) { + t.showLabel = false; + t.showMark = true; + } + else { + if (skip>0 && track<skip) { + t.showLabel = false; + track += 1; + } + else { + t.showLabel = true; + track = 0; + } + t.label = t.formatter(t.formatString, labels[(i-1)/2]); + t.showMark = false; + t.showGridline = false; + } + t.setTick(tt, this.name); + this._ticks.push(t); + } + } + + }; + + // called with scope of axis + $.jqplot.CategoryAxisRenderer.prototype.draw = function(ctx, plot) { + if (this.show) { + // populate the axis label and value properties. + // createTicks is a method on the renderer, but + // call it within the scope of the axis. + this.renderer.createTicks.call(this); + // fill a div with axes labels in the right direction. + // Need to pregenerate each axis to get its bounds and + // position it and the labels correctly on the plot. + var dim=0; + var temp; + // Added for theming. + if (this._elem) { + // this._elem.empty(); + // Memory Leaks patch + this._elem.emptyForce(); + } + + this._elem = this._elem || $('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>'); + + if (this.name == 'xaxis' || this.name == 'x2axis') { + this._elem.width(this._plotDimensions.width); + } + else { + this._elem.height(this._plotDimensions.height); + } + + // create a _label object. + this.labelOptions.axis = this.name; + this._label = new this.labelRenderer(this.labelOptions); + if (this._label.show) { + var elem = this._label.draw(ctx, plot); + elem.appendTo(this._elem); + } + + var t = this._ticks; + for (var i=0; i<t.length; i++) { + var tick = t[i]; + if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + var elem = tick.draw(ctx, plot); + elem.appendTo(this._elem); + } + } + + this._groupLabels = []; + // now make group labels + for (var i=0; i<this.groupLabels.length; i++) + { + var elem = $('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>'); + elem.html(this.groupLabels[i]); + this._groupLabels.push(elem); + elem.appendTo(this._elem); + } + } + return this._elem; + }; + + // called with scope of axis + $.jqplot.CategoryAxisRenderer.prototype.set = function() { + var dim = 0; + var temp; + var w = 0; + var h = 0; + var lshow = (this._label == null) ? false : this._label.show; + if (this.show) { + var t = this._ticks; + for (var i=0; i<t.length; i++) { + var tick = t[i]; + if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + temp = tick._elem.outerHeight(true); + } + else { + temp = tick._elem.outerWidth(true); + } + if (temp > dim) { + dim = temp; + } + } + } + + var dim2 = 0; + for (var i=0; i<this._groupLabels.length; i++) { + var l = this._groupLabels[i]; + if (this.name == 'xaxis' || this.name == 'x2axis') { + temp = l.outerHeight(true); + } + else { + temp = l.outerWidth(true); + } + if (temp > dim2) { + dim2 = temp; + } + } + + if (lshow) { + w = this._label._elem.outerWidth(true); + h = this._label._elem.outerHeight(true); + } + if (this.name == 'xaxis') { + dim += dim2 + h; + this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); + } + else if (this.name == 'x2axis') { + dim += dim2 + h; + this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); + } + else if (this.name == 'yaxis') { + dim += dim2 + w; + this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + else { + dim += dim2 + w; + this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + } + }; + + // called with scope of axis + $.jqplot.CategoryAxisRenderer.prototype.pack = function(pos, offsets) { + var ticks = this._ticks; + var max = this.max; + var min = this.min; + var offmax = offsets.max; + var offmin = offsets.min; + var lshow = (this._label == null) ? false : this._label.show; + var i; + + for (var p in pos) { + this._elem.css(p, pos[p]); + } + + this._offsets = offsets; + // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. + var pixellength = offmax - offmin; + var unitlength = max - min; + + if (!this.reverse) { + // point to unit and unit to point conversions references to Plot DOM element top left corner. + + this.u2p = function(u){ + return (u - min) * pixellength / unitlength + offmin; + }; + + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + if (this.name == 'xaxis' || this.name == 'x2axis'){ + this.series_u2p = function(u){ + return (u - min) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + else { + this.series_u2p = function(u){ + return (u - max) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + } + + else { + // point to unit and unit to point conversions references to Plot DOM element top left corner. + + this.u2p = function(u){ + return offmin + (max - u) * pixellength / unitlength; + }; + + this.p2u = function(p){ + return min + (p - offmin) * unitlength / pixellength; + }; + + if (this.name == 'xaxis' || this.name == 'x2axis'){ + this.series_u2p = function(u){ + return (max - u) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + + else { + this.series_u2p = function(u){ + return (min - u) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + } + + + if (this.show) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + for (i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'xaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + if (temp * t.angle < 0) { + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + } + // position at start + else { + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + } + break; + case 'end': + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + case 'start': + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + break; + case 'middle': + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + default: + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + } + } + else { + shim = -t.getWidth()/2; + } + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('left', val); + t.pack(); + } + } + + var labeledge=['bottom', 0]; + if (lshow) { + var w = this._label._elem.outerWidth(true); + this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); + if (this.name == 'xaxis') { + this._label._elem.css('bottom', '0px'); + labeledge = ['bottom', this._label._elem.outerHeight(true)]; + } + else { + this._label._elem.css('top', '0px'); + labeledge = ['top', this._label._elem.outerHeight(true)]; + } + this._label.pack(); + } + + // draw the group labels + var step = parseInt(this._ticks.length/this.groups, 10) + 1; + for (i=0; i<this._groupLabels.length; i++) { + var mid = 0; + var count = 0; + for (var j=i*step; j<(i+1)*step; j++) { + if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one. + if (this._ticks[j]._elem && this._ticks[j].label != " ") { + var t = this._ticks[j]._elem; + var p = t.position(); + mid += p.left + t.outerWidth(true)/2; + count++; + } + } + mid = mid/count; + this._groupLabels[i].css({'left':(mid - this._groupLabels[i].outerWidth(true)/2)}); + this._groupLabels[i].css(labeledge[0], labeledge[1]); + } + } + else { + for (i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'yaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + case 'end': + if (temp * t.angle < 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'start': + if (t.angle > 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'middle': + // if (t.angle > 0) { + // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + // } + // else { + // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + // } + shim = -t.getHeight()/2; + break; + default: + shim = -t.getHeight()/2; + break; + } + } + else { + shim = -t.getHeight()/2; + } + + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('top', val); + t.pack(); + } + } + + var labeledge=['left', 0]; + if (lshow) { + var h = this._label._elem.outerHeight(true); + this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); + if (this.name == 'yaxis') { + this._label._elem.css('left', '0px'); + labeledge = ['left', this._label._elem.outerWidth(true)]; + } + else { + this._label._elem.css('right', '0px'); + labeledge = ['right', this._label._elem.outerWidth(true)]; + } + this._label.pack(); + } + + // draw the group labels, position top here, do left after label position. + var step = parseInt(this._ticks.length/this.groups, 10) + 1; // step is one more than before as we don't want to have overlaps in loops + for (i=0; i<this._groupLabels.length; i++) { + var mid = 0; + var count = 0; + for (var j=i*step; j<(i+1)*step; j++) { // j must never reach (i+1)*step as we don't want to have overlap between loops + if (j >= this._ticks.length-1) continue; // the last tick does not exist as there is no other group in order to have an empty one. + if (this._ticks[j]._elem && this._ticks[j].label != " ") { + var t = this._ticks[j]._elem; + var p = t.position(); + mid += p.top + t.outerHeight()/2; + count++; + } + } + mid = mid/count; + this._groupLabels[i].css({'top':mid - this._groupLabels[i].outerHeight()/2}); + this._groupLabels[i].css(labeledge[0], labeledge[1]); + + } + } + } + }; + + +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.min.js new file mode 100644 index 0000000..d3a0bae --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.categoryAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.CategoryAxisRenderer=function(b){a.jqplot.LinearAxisRenderer.call(this);this.sortMergedLabels=false};a.jqplot.CategoryAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.CategoryAxisRenderer.prototype.constructor=a.jqplot.CategoryAxisRenderer;a.jqplot.CategoryAxisRenderer.prototype.init=function(e){this.groups=1;this.groupLabels=[];this._groupLabels=[];this._grouped=false;this._barsPerGroup=null;this.reverse=false;a.extend(true,this,{tickOptions:{formatString:"%d"}},e);var b=this._dataBounds;for(var f=0;f<this._series.length;f++){var g=this._series[f];if(g.groups){this.groups=g.groups}var h=g.data;for(var c=0;c<h.length;c++){if(this.name=="xaxis"||this.name=="x2axis"){if(h[c][0]<b.min||b.min==null){b.min=h[c][0]}if(h[c][0]>b.max||b.max==null){b.max=h[c][0]}}else{if(h[c][1]<b.min||b.min==null){b.min=h[c][1]}if(h[c][1]>b.max||b.max==null){b.max=h[c][1]}}}}if(this.groupLabels.length){this.groups=this.groupLabels.length}};a.jqplot.CategoryAxisRenderer.prototype.createTicks=function(){var D=this._ticks;var z=this.ticks;var F=this.name;var C=this._dataBounds;var v,A;var q,w;var d,c;var b,x;if(z.length){if(this.groups>1&&!this._grouped){var r=z.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p){z.splice(x+e,0," ");e++}this._grouped=true}this.min=0.5;this.max=z.length+0.5;var m=this.max-this.min;this.numberTicks=2*z.length+1;for(x=0;x<z.length;x++){b=this.min+2*x*m/(this.numberTicks-1);var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b,this.name);this._ticks.push(h);var h=new this.tickRenderer(this.tickOptions);h.label=z[x];h.showMark=false;h.showGridline=false;h.setTick(b+0.5,this.name);this._ticks.push(h)}var h=new this.tickRenderer(this.tickOptions);h.showLabel=false;h.setTick(b+1,this.name);this._ticks.push(h)}else{if(F=="xaxis"||F=="x2axis"){v=this._plotDimensions.width}else{v=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.min!=null&&this.max!=null&&this.tickInterval!=null){if(parseInt((this.max-this.min)/this.tickInterval,10)!=(this.max-this.min)/this.tickInterval){this.tickInterval=null}}var y=[];var B=0;var q=0.5;var w,E;var f=false;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}if(a.inArray(E,y)==-1){f=true;B+=1;y.push(E)}}}if(f&&this.sortMergedLabels){if(typeof y[0]=="string"){y.sort()}else{y.sort(function(j,i){return j-i})}}this.ticks=y;for(var x=0;x<this._series.length;x++){var k=this._series[x];for(var u=0;u<k.data.length;u++){if(this.name=="xaxis"||this.name=="x2axis"){E=k.data[u][0]}else{E=k.data[u][1]}var n=a.inArray(E,y)+1;if(this.name=="xaxis"||this.name=="x2axis"){k.data[u][0]=n}else{k.data[u][1]=n}}}if(this.groups>1&&!this._grouped){var r=y.length;var p=parseInt(r/this.groups,10);var e=0;for(var x=p;x<r;x+=p+1){y[x]=" "}this._grouped=true}w=B+0.5;if(this.numberTicks==null){this.numberTicks=2*B+1}var m=w-q;this.min=q;this.max=w;var o=0;var g=parseInt(3+v/10,10);var p=parseInt(B/g,10);if(this.tickInterval==null){this.tickInterval=m/(this.numberTicks-1)}for(var x=0;x<this.numberTicks;x++){b=this.min+x*this.tickInterval;var h=new this.tickRenderer(this.tickOptions);if(x/2==parseInt(x/2,10)){h.showLabel=false;h.showMark=true}else{if(p>0&&o<p){h.showLabel=false;o+=1}else{h.showLabel=true;o=0}h.label=h.formatter(h.formatString,y[(x-1)/2]);h.showMark=false;h.showGridline=false}h.setTick(b,this.name);this._ticks.push(h)}}};a.jqplot.CategoryAxisRenderer.prototype.draw=function(b,j){if(this.show){this.renderer.createTicks.call(this);var h=0;var c;if(this._elem){this._elem.emptyForce()}this._elem=this._elem||a('<div class="jqplot-axis jqplot-'+this.name+'" style="position:absolute;"></div>');if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var g=this._label.draw(b,j);g.appendTo(this._elem)}var f=this._ticks;for(var e=0;e<f.length;e++){var d=f[e];if(d.showLabel&&(!d.isMinorTick||this.showMinorTicks)){var g=d.draw(b,j);g.appendTo(this._elem)}}this._groupLabels=[];for(var e=0;e<this.groupLabels.length;e++){var g=a('<div style="position:absolute;" class="jqplot-'+this.name+'-groupLabel"></div>');g.html(this.groupLabels[e]);this._groupLabels.push(g);g.appendTo(this._elem)}}return this._elem};a.jqplot.CategoryAxisRenderer.prototype.set=function(){var e=0;var m;var k=0;var f=0;var d=(this._label==null)?false:this._label.show;if(this.show){var n=this._ticks;for(var c=0;c<n.length;c++){var g=n[c];if(g.showLabel&&(!g.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){m=g._elem.outerHeight(true)}else{m=g._elem.outerWidth(true)}if(m>e){e=m}}}var j=0;for(var c=0;c<this._groupLabels.length;c++){var b=this._groupLabels[c];if(this.name=="xaxis"||this.name=="x2axis"){m=b.outerHeight(true)}else{m=b.outerWidth(true)}if(m>j){j=m}}if(d){k=this._label._elem.outerWidth(true);f=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){e+=j+f;this._elem.css({height:e+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){e+=j+k;this._elem.css({width:e+"px",left:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}else{e+=j+k;this._elem.css({width:e+"px",right:"0px",top:"0px"});if(d&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",k+"px")}}}}}};a.jqplot.CategoryAxisRenderer.prototype.pack=function(e,c){var C=this._ticks;var v=this.max;var s=this.min;var n=c.max;var l=c.min;var q=(this._label==null)?false:this._label.show;var x;for(var r in e){this._elem.css(r,e[r])}this._offsets=c;var g=n-l;var k=v-s;if(!this.reverse){this.u2p=function(h){return(h-s)*g/k+l};this.p2u=function(h){return(h-l)*k/g+s};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(h-s)*g/k};this.series_p2u=function(h){return h*k/g+s}}else{this.series_u2p=function(h){return(h-v)*g/k};this.series_p2u=function(h){return h*k/g+v}}}else{this.u2p=function(h){return l+(v-h)*g/k};this.p2u=function(h){return s+(h-l)*k/g};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(v-h)*g/k};this.series_p2u=function(h){return h*k/g+v}}else{this.series_u2p=function(h){return(s-h)*g/k};this.series_p2u=function(h){return h*k/g+s}}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(x=0;x<C.length;x++){var o=C[x];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="xaxis")?1:-1;switch(o.labelPosition){case"auto":if(A*o.angle<0){b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2}else{b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2}break;case"end":b=-o.getWidth()+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;case"start":b=-o._textRenderer.height*Math.sin(o._textRenderer.angle)/2;break;case"middle":b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break;default:b=-o.getWidth()/2+o._textRenderer.height*Math.sin(-o._textRenderer.angle)/2;break}}else{b=-o.getWidth()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("left",D);o.pack()}}var z=["bottom",0];if(q){var m=this._label._elem.outerWidth(true);this._label._elem.css("left",l+g/2-m/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px");z=["bottom",this._label._elem.outerHeight(true)]}else{this._label._elem.css("top","0px");z=["top",this._label._elem.outerHeight(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<(x+1)*d;u++){if(u>=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.left+o.outerWidth(true)/2;f++}}B=B/f;this._groupLabels[x].css({left:(B-this._groupLabels[x].outerWidth(true)/2)});this._groupLabels[x].css(z[0],z[1])}}else{for(x=0;x<C.length;x++){var o=C[x];if(o.show&&o.showLabel){var b;if(o.constructor==a.jqplot.CanvasAxisTickRenderer&&o.angle){var A=(this.name=="yaxis")?1:-1;switch(o.labelPosition){case"auto":case"end":if(A*o.angle<0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"start":if(o.angle>0){b=-o._textRenderer.height*Math.cos(-o._textRenderer.angle)/2}else{b=-o.getHeight()+o._textRenderer.height*Math.cos(o._textRenderer.angle)/2}break;case"middle":b=-o.getHeight()/2;break;default:b=-o.getHeight()/2;break}}else{b=-o.getHeight()/2}var D=this.u2p(o.value)+b+"px";o._elem.css("top",D);o.pack()}}var z=["left",0];if(q){var y=this._label._elem.outerHeight(true);this._label._elem.css("top",n-g/2-y/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px");z=["left",this._label._elem.outerWidth(true)]}else{this._label._elem.css("right","0px");z=["right",this._label._elem.outerWidth(true)]}this._label.pack()}var d=parseInt(this._ticks.length/this.groups,10)+1;for(x=0;x<this._groupLabels.length;x++){var B=0;var f=0;for(var u=x*d;u<(x+1)*d;u++){if(u>=this._ticks.length-1){continue}if(this._ticks[u]._elem&&this._ticks[u].label!=" "){var o=this._ticks[u]._elem;var r=o.position();B+=r.top+o.outerHeight()/2;f++}}B=B/f;this._groupLabels[x].css({top:B-this._groupLabels[x].outerHeight()/2});this._groupLabels[x].css(z[0],z[1])}}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.js new file mode 100644 index 0000000..2f094fc --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.js @@ -0,0 +1,116 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.ciParser + * Data Renderer function which converts a custom JSON data object into jqPlot data format. + * Set this as a callable on the jqplot dataRenderer plot option: + * + * > plot = $.jqplot('mychart', [data], { dataRenderer: $.jqplot.ciParser, ... }); + * + * Where data is an object in JSON format or a JSON encoded string conforming to the + * City Index API spec. + * + * Note that calling the renderer function is handled internally by jqPlot. The + * user does not have to call the function. The parameters described below will + * automatically be passed to the ciParser function. + * + * Parameters: + * data - JSON encoded string or object. + * plot - reference to jqPlot Plot object. + * + * Returns: + * data array in jqPlot format. + * + */ + $.jqplot.ciParser = function (data, plot) { + var ret = [], + line, + temp, + i, j, k, kk; + + if (typeof(data) == "string") { + data = $.jqplot.JSON.parse(data, handleStrings); + } + + else if (typeof(data) == "object") { + for (k in data) { + for (i=0; i<data[k].length; i++) { + for (kk in data[k][i]) { + data[k][i][kk] = handleStrings(kk, data[k][i][kk]); + } + } + } + } + + else { + return null; + } + + // function handleStrings + // Checks any JSON encoded strings to see if they are + // encoded dates. If so, pull out the timestamp. + // Expects dates to be represented by js timestamps. + + function handleStrings(key, value) { + var a; + if (value != null) { + if (value.toString().indexOf('Date') >= 0) { + //here we will try to extract the ticks from the Date string in the "value" fields of JSON returned data + a = /^\/Date\((-?[0-9]+)\)\/$/.exec(value); + if (a) { + return parseInt(a[1], 10); + } + } + return value; + } + } + + for (var prop in data) { + line = []; + temp = data[prop]; + switch (prop) { + case "PriceTicks": + for (i=0; i<temp.length; i++) { + line.push([temp[i]['TickDate'], temp[i]['Price']]); + } + break; + case "PriceBars": + for (i=0; i<temp.length; i++) { + line.push([temp[i]['BarDate'], temp[i]['Open'], temp[i]['High'], temp[i]['Low'], temp[i]['Close']]); + } + break; + } + ret.push(line); + } + return ret; + }; +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.min.js new file mode 100644 index 0000000..e17e792 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ciParser.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.ciParser=function(g,l){var m=[],o,n,h,f,e,c;if(typeof(g)=="string"){g=a.jqplot.JSON.parse(g,d)}else{if(typeof(g)=="object"){for(e in g){for(h=0;h<g[e].length;h++){for(c in g[e][h]){g[e][h][c]=d(c,g[e][h][c])}}}}else{return null}}function d(j,k){var i;if(k!=null){if(k.toString().indexOf("Date")>=0){i=/^\/Date\((-?[0-9]+)\)\/$/.exec(k);if(i){return parseInt(i[1],10)}}return k}}for(var b in g){o=[];n=g[b];switch(b){case"PriceTicks":for(h=0;h<n.length;h++){o.push([n[h]["TickDate"],n[h]["Price"]])}break;case"PriceBars":for(h=0;h<n.length;h++){o.push([n[h]["BarDate"],n[h]["Open"],n[h]["High"],n[h]["Low"],n[h]["Close"]])}break}m.push(o)}return m}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.js new file mode 100644 index 0000000..bf1c36f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.js @@ -0,0 +1,1108 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + /** + * Class: $.jqplot.Cursor + * Plugin class representing the cursor as displayed on the plot. + */ + $.jqplot.Cursor = function(options) { + // Group: Properties + // + // prop: style + // CSS spec for cursor style + this.style = 'crosshair'; + this.previousCursor = 'auto'; + // prop: show + // whether to show the cursor or not. + this.show = $.jqplot.config.enablePlugins; + // prop: showTooltip + // show a cursor position tooltip. Location of the tooltip + // will be controlled by followMouse and tooltipLocation. + this.showTooltip = true; + // prop: followMouse + // Tooltip follows the mouse, it is not at a fixed location. + // Tooltip will show on the grid at the location given by + // tooltipLocation, offset from the grid edge by tooltipOffset. + this.followMouse = false; + // prop: tooltipLocation + // Where to position tooltip. If followMouse is true, this is + // relative to the cursor, otherwise, it is relative to the grid. + // One of 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + this.tooltipLocation = 'se'; + // prop: tooltipOffset + // Pixel offset of tooltip from the grid boudaries or cursor center. + this.tooltipOffset = 6; + // prop: showTooltipGridPosition + // show the grid pixel coordinates of the mouse. + this.showTooltipGridPosition = false; + // prop: showTooltipUnitPosition + // show the unit (data) coordinates of the mouse. + this.showTooltipUnitPosition = true; + // prop: showTooltipDataPosition + // Used with showVerticalLine to show intersecting data points in the tooltip. + this.showTooltipDataPosition = false; + // prop: tooltipFormatString + // sprintf format string for the tooltip. + // Uses Ash Searle's javascript sprintf implementation + // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ + // See http://perldoc.perl.org/functions/sprintf.html for reference + // Note, if showTooltipDataPosition is true, the default tooltipFormatString + // will be set to the cursorLegendFormatString, not the default given here. + this.tooltipFormatString = '%.4P, %.4P'; + // prop: useAxesFormatters + // Use the x and y axes formatters to format the text in the tooltip. + this.useAxesFormatters = true; + // prop: tooltipAxisGroups + // Show position for the specified axes. + // This is an array like [['xaxis', 'yaxis'], ['xaxis', 'y2axis']] + // Default is to compute automatically for all visible axes. + this.tooltipAxisGroups = []; + // prop: zoom + // Enable plot zooming. + this.zoom = false; + // zoomProxy and zoomTarget properties are not directly set by user. + // They Will be set through call to zoomProxy method. + this.zoomProxy = false; + this.zoomTarget = false; + // prop: looseZoom + // Will expand zoom range to provide more rounded tick values. + // Works only with linear, log and date axes. + this.looseZoom = true; + // prop: clickReset + // Will reset plot zoom if single click on plot without drag. + this.clickReset = false; + // prop: dblClickReset + // Will reset plot zoom if double click on plot without drag. + this.dblClickReset = true; + // prop: showVerticalLine + // draw a vertical line across the plot which follows the cursor. + // When the line is near a data point, a special legend and/or tooltip can + // be updated with the data values. + this.showVerticalLine = false; + // prop: showHorizontalLine + // draw a horizontal line across the plot which follows the cursor. + this.showHorizontalLine = false; + // prop: constrainZoomTo + // 'none', 'x' or 'y' + this.constrainZoomTo = 'none'; + // // prop: autoscaleConstraint + // // when a constrained axis is specified, true will + // // auatoscale the adjacent axis. + // this.autoscaleConstraint = true; + this.shapeRenderer = new $.jqplot.ShapeRenderer(); + this._zoom = {start:[], end:[], started: false, zooming:false, isZoomed:false, axes:{start:{}, end:{}}, gridpos:{}, datapos:{}}; + this._tooltipElem; + this.zoomCanvas; + this.cursorCanvas; + // prop: intersectionThreshold + // pixel distance from data point or marker to consider cursor lines intersecting with point. + // If data point markers are not shown, this should be >= 1 or will often miss point intersections. + this.intersectionThreshold = 2; + // prop: showCursorLegend + // Replace the plot legend with an enhanced legend displaying intersection information. + this.showCursorLegend = false; + // prop: cursorLegendFormatString + // Format string used in the cursor legend. If showTooltipDataPosition is true, + // this will also be the default format string used by tooltipFormatString. + this.cursorLegendFormatString = $.jqplot.Cursor.cursorLegendFormatString; + // whether the cursor is over the grid or not. + this._oldHandlers = {onselectstart: null, ondrag: null, onmousedown: null}; + // prop: constrainOutsideZoom + // True to limit actual zoom area to edges of grid, even when zooming + // outside of plot area. That is, can't zoom out by mousing outside plot. + this.constrainOutsideZoom = true; + // prop: showTooltipOutsideZoom + // True will keep updating the tooltip when zooming of the grid. + this.showTooltipOutsideZoom = false; + // true if mouse is over grid, false if not. + this.onGrid = false; + $.extend(true, this, options); + }; + + $.jqplot.Cursor.cursorLegendFormatString = '%s x:%s, y:%s'; + + // called with scope of plot + $.jqplot.Cursor.init = function (target, data, opts){ + // add a cursor attribute to the plot + var options = opts || {}; + this.plugins.cursor = new $.jqplot.Cursor(options.cursor); + var c = this.plugins.cursor; + + if (c.show) { + $.jqplot.eventListenerHooks.push(['jqplotMouseEnter', handleMouseEnter]); + $.jqplot.eventListenerHooks.push(['jqplotMouseLeave', handleMouseLeave]); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMouseMove]); + + if (c.showCursorLegend) { + opts.legend = opts.legend || {}; + opts.legend.renderer = $.jqplot.CursorLegendRenderer; + opts.legend.formatString = this.plugins.cursor.cursorLegendFormatString; + opts.legend.show = true; + } + + if (c.zoom) { + $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleMouseDown]); + + if (c.clickReset) { + $.jqplot.eventListenerHooks.push(['jqplotClick', handleClick]); + } + + if (c.dblClickReset) { + $.jqplot.eventListenerHooks.push(['jqplotDblClick', handleDblClick]); + } + } + + this.resetZoom = function() { + var axes = this.axes; + if (!c.zoomProxy) { + for (var ax in axes) { + axes[ax].reset(); + axes[ax]._ticks = []; + // fake out tick creation algorithm to make sure original auto + // computed format string is used if _overrideFormatString is true + if (c._zoom.axes[ax] !== undefined) { + axes[ax]._autoFormatString = c._zoom.axes[ax].tickFormatString; + } + } + this.redraw(); + } + else { + var ctx = this.plugins.cursor.zoomCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx = null; + } + this.plugins.cursor._zoom.isZoomed = false; + this.target.trigger('jqplotResetZoom', [this, this.plugins.cursor]); + }; + + + if (c.showTooltipDataPosition) { + c.showTooltipUnitPosition = false; + c.showTooltipGridPosition = false; + if (options.cursor.tooltipFormatString == undefined) { + c.tooltipFormatString = $.jqplot.Cursor.cursorLegendFormatString; + } + } + } + }; + + // called with context of plot + $.jqplot.Cursor.postDraw = function() { + var c = this.plugins.cursor; + + // Memory Leaks patch + if (c.zoomCanvas) { + c.zoomCanvas.resetCanvas(); + c.zoomCanvas = null; + } + + if (c.cursorCanvas) { + c.cursorCanvas.resetCanvas(); + c.cursorCanvas = null; + } + + if (c._tooltipElem) { + c._tooltipElem.emptyForce(); + c._tooltipElem = null; + } + + + if (c.zoom) { + c.zoomCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions, this)); + c.zoomCanvas.setContext(); + } + + var elem = document.createElement('div'); + c._tooltipElem = $(elem); + elem = null; + c._tooltipElem.addClass('jqplot-cursor-tooltip'); + c._tooltipElem.css({position:'absolute', display:'none'}); + + + if (c.zoomCanvas) { + c.zoomCanvas._elem.before(c._tooltipElem); + } + + else { + this.eventCanvas._elem.before(c._tooltipElem); + } + + if (c.showVerticalLine || c.showHorizontalLine) { + c.cursorCanvas = new $.jqplot.GenericCanvas(); + this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions, this)); + c.cursorCanvas.setContext(); + } + + // if we are showing the positions in unit coordinates, and no axes groups + // were specified, create a default set. + if (c.showTooltipUnitPosition){ + if (c.tooltipAxisGroups.length === 0) { + var series = this.series; + var s; + var temp = []; + for (var i=0; i<series.length; i++) { + s = series[i]; + var ax = s.xaxis+','+s.yaxis; + if ($.inArray(ax, temp) == -1) { + temp.push(ax); + } + } + for (var i=0; i<temp.length; i++) { + c.tooltipAxisGroups.push(temp[i].split(',')); + } + } + } + }; + + // Group: methods + // + // method: $.jqplot.Cursor.zoomProxy + // links targetPlot to controllerPlot so that plot zooming of + // targetPlot will be controlled by zooming on the controllerPlot. + // controllerPlot will not actually zoom, but acts as an + // overview plot. Note, the zoom options must be set to true for + // zoomProxy to work. + $.jqplot.Cursor.zoomProxy = function(targetPlot, controllerPlot) { + var tc = targetPlot.plugins.cursor; + var cc = controllerPlot.plugins.cursor; + tc.zoomTarget = true; + tc.zoom = true; + tc.style = 'auto'; + tc.dblClickReset = false; + cc.zoom = true; + cc.zoomProxy = true; + + controllerPlot.target.bind('jqplotZoom', plotZoom); + controllerPlot.target.bind('jqplotResetZoom', plotReset); + + function plotZoom(ev, gridpos, datapos, plot, cursor) { + tc.doZoom(gridpos, datapos, targetPlot, cursor); + } + + function plotReset(ev, plot, cursor) { + targetPlot.resetZoom(); + } + }; + + $.jqplot.Cursor.prototype.resetZoom = function(plot, cursor) { + var axes = plot.axes; + var cax = cursor._zoom.axes; + if (!plot.plugins.cursor.zoomProxy && cursor._zoom.isZoomed) { + for (var ax in axes) { + // axes[ax]._ticks = []; + // axes[ax].min = cax[ax].min; + // axes[ax].max = cax[ax].max; + // axes[ax].numberTicks = cax[ax].numberTicks; + // axes[ax].tickInterval = cax[ax].tickInterval; + // // for date axes + // axes[ax].daTickInterval = cax[ax].daTickInterval; + axes[ax].reset(); + axes[ax]._ticks = []; + // fake out tick creation algorithm to make sure original auto + // computed format string is used if _overrideFormatString is true + axes[ax]._autoFormatString = cax[ax].tickFormatString; + } + plot.redraw(); + cursor._zoom.isZoomed = false; + } + else { + var ctx = cursor.zoomCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx = null; + } + plot.target.trigger('jqplotResetZoom', [plot, cursor]); + }; + + $.jqplot.Cursor.resetZoom = function(plot) { + plot.resetZoom(); + }; + + $.jqplot.Cursor.prototype.doZoom = function (gridpos, datapos, plot, cursor) { + var c = cursor; + var axes = plot.axes; + var zaxes = c._zoom.axes; + var start = zaxes.start; + var end = zaxes.end; + var min, max, dp, span, + newmin, newmax, curax, _numberTicks, ret; + var ctx = plot.plugins.cursor.zoomCanvas._ctx; + // don't zoom if zoom area is too small (in pixels) + if ((c.constrainZoomTo == 'none' && Math.abs(gridpos.x - c._zoom.start[0]) > 6 && Math.abs(gridpos.y - c._zoom.start[1]) > 6) || (c.constrainZoomTo == 'x' && Math.abs(gridpos.x - c._zoom.start[0]) > 6) || (c.constrainZoomTo == 'y' && Math.abs(gridpos.y - c._zoom.start[1]) > 6)) { + if (!plot.plugins.cursor.zoomProxy) { + for (var ax in datapos) { + // make a copy of the original axes to revert back. + if (c._zoom.axes[ax] == undefined) { + c._zoom.axes[ax] = {}; + c._zoom.axes[ax].numberTicks = axes[ax].numberTicks; + c._zoom.axes[ax].tickInterval = axes[ax].tickInterval; + // for date axes... + c._zoom.axes[ax].daTickInterval = axes[ax].daTickInterval; + c._zoom.axes[ax].min = axes[ax].min; + c._zoom.axes[ax].max = axes[ax].max; + c._zoom.axes[ax].tickFormatString = (axes[ax].tickOptions != null) ? axes[ax].tickOptions.formatString : ''; + } + + + if ((c.constrainZoomTo == 'none') || (c.constrainZoomTo == 'x' && ax.charAt(0) == 'x') || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'y')) { + dp = datapos[ax]; + if (dp != null) { + if (dp > start[ax]) { + newmin = start[ax]; + newmax = dp; + } + else { + span = start[ax] - dp; + newmin = dp; + newmax = start[ax]; + } + + curax = axes[ax]; + + _numberTicks = null; + + // if aligning this axis, use number of ticks from previous axis. + // Do I need to reset somehow if alignTicks is changed and then graph is replotted?? + if (curax.alignTicks) { + if (curax.name === 'x2axis' && plot.axes.xaxis.show) { + _numberTicks = plot.axes.xaxis.numberTicks; + } + else if (curax.name.charAt(0) === 'y' && curax.name !== 'yaxis' && curax.name !== 'yMidAxis' && plot.axes.yaxis.show) { + _numberTicks = plot.axes.yaxis.numberTicks; + } + } + + if (this.looseZoom && (axes[ax].renderer.constructor === $.jqplot.LinearAxisRenderer || axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer )) { //} || axes[ax].renderer.constructor === $.jqplot.DateAxisRenderer)) { + + ret = $.jqplot.LinearTickGenerator(newmin, newmax, curax._scalefact, _numberTicks); + + // if new minimum is less than "true" minimum of axis display, adjust it + if (axes[ax].tickInset && ret[0] < axes[ax].min + axes[ax].tickInset * axes[ax].tickInterval) { + ret[0] += ret[4]; + ret[2] -= 1; + } + + // if new maximum is greater than "true" max of axis display, adjust it + if (axes[ax].tickInset && ret[1] > axes[ax].max - axes[ax].tickInset * axes[ax].tickInterval) { + ret[1] -= ret[4]; + ret[2] -= 1; + } + + // for log axes, don't fall below current minimum, this will look bad and can't have 0 in range anyway. + if (axes[ax].renderer.constructor === $.jqplot.LogAxisRenderer && ret[0] < axes[ax].min) { + // remove a tick and shift min up + ret[0] += ret[4]; + ret[2] -= 1; + } + + axes[ax].min = ret[0]; + axes[ax].max = ret[1]; + axes[ax]._autoFormatString = ret[3]; + axes[ax].numberTicks = ret[2]; + axes[ax].tickInterval = ret[4]; + // for date axes... + axes[ax].daTickInterval = [ret[4]/1000, 'seconds']; + } + else { + axes[ax].min = newmin; + axes[ax].max = newmax; + axes[ax].tickInterval = null; + axes[ax].numberTicks = null; + // for date axes... + axes[ax].daTickInterval = null; + } + + axes[ax]._ticks = []; + } + } + + // if ((c.constrainZoomTo == 'x' && ax.charAt(0) == 'y' && c.autoscaleConstraint) || (c.constrainZoomTo == 'y' && ax.charAt(0) == 'x' && c.autoscaleConstraint)) { + // dp = datapos[ax]; + // if (dp != null) { + // axes[ax].max == null; + // axes[ax].min = null; + // } + // } + } + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + plot.redraw(); + c._zoom.isZoomed = true; + ctx = null; + } + plot.target.trigger('jqplotZoom', [gridpos, datapos, plot, cursor]); + } + }; + + $.jqplot.preInitHooks.push($.jqplot.Cursor.init); + $.jqplot.postDrawHooks.push($.jqplot.Cursor.postDraw); + + function updateTooltip(gridpos, datapos, plot) { + var c = plot.plugins.cursor; + var s = ''; + var addbr = false; + if (c.showTooltipGridPosition) { + s = gridpos.x+', '+gridpos.y; + addbr = true; + } + if (c.showTooltipUnitPosition) { + var g; + for (var i=0; i<c.tooltipAxisGroups.length; i++) { + g = c.tooltipAxisGroups[i]; + if (addbr) { + s += '<br />'; + } + if (c.useAxesFormatters) { + for (var j=0; j<g.length; j++) { + if (j) { + s += ', '; + } + var af = plot.axes[g[j]]._ticks[0].formatter; + var afstr = plot.axes[g[j]]._ticks[0].formatString; + s += af(afstr, datapos[g[j]]); + } + } + else { + s += $.jqplot.sprintf(c.tooltipFormatString, datapos[g[0]], datapos[g[1]]); + } + addbr = true; + } + } + + if (c.showTooltipDataPosition) { + var series = plot.series; + var ret = getIntersectingPoints(plot, gridpos.x, gridpos.y); + var addbr = false; + + for (var i = 0; i< series.length; i++) { + if (series[i].show) { + var idx = series[i].index; + var label = series[i].label.toString(); + var cellid = $.inArray(idx, ret.indices); + var sx = undefined; + var sy = undefined; + if (cellid != -1) { + var data = ret.data[cellid].data; + if (c.useAxesFormatters) { + var xf = series[i]._xaxis._ticks[0].formatter; + var yf = series[i]._yaxis._ticks[0].formatter; + var xfstr = series[i]._xaxis._ticks[0].formatString; + var yfstr = series[i]._yaxis._ticks[0].formatString; + sx = xf(xfstr, data[0]); + sy = yf(yfstr, data[1]); + } + else { + sx = data[0]; + sy = data[1]; + } + if (addbr) { + s += '<br />'; + } + s += $.jqplot.sprintf(c.tooltipFormatString, label, sx, sy); + addbr = true; + } + } + } + + } + c._tooltipElem.html(s); + } + + function moveLine(gridpos, plot) { + var c = plot.plugins.cursor; + var ctx = c.cursorCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + if (c.showVerticalLine) { + c.shapeRenderer.draw(ctx, [[gridpos.x, 0], [gridpos.x, ctx.canvas.height]]); + } + if (c.showHorizontalLine) { + c.shapeRenderer.draw(ctx, [[0, gridpos.y], [ctx.canvas.width, gridpos.y]]); + } + var ret = getIntersectingPoints(plot, gridpos.x, gridpos.y); + if (c.showCursorLegend) { + var cells = $(plot.targetId + ' td.jqplot-cursor-legend-label'); + for (var i=0; i<cells.length; i++) { + var idx = $(cells[i]).data('seriesIndex'); + var series = plot.series[idx]; + var label = series.label.toString(); + var cellid = $.inArray(idx, ret.indices); + var sx = undefined; + var sy = undefined; + if (cellid != -1) { + var data = ret.data[cellid].data; + if (c.useAxesFormatters) { + var xf = series._xaxis._ticks[0].formatter; + var yf = series._yaxis._ticks[0].formatter; + var xfstr = series._xaxis._ticks[0].formatString; + var yfstr = series._yaxis._ticks[0].formatString; + sx = xf(xfstr, data[0]); + sy = yf(yfstr, data[1]); + } + else { + sx = data[0]; + sy = data[1]; + } + } + if (plot.legend.escapeHtml) { + $(cells[i]).text($.jqplot.sprintf(c.cursorLegendFormatString, label, sx, sy)); + } + else { + $(cells[i]).html($.jqplot.sprintf(c.cursorLegendFormatString, label, sx, sy)); + } + } + } + ctx = null; + } + + function getIntersectingPoints(plot, x, y) { + var ret = {indices:[], data:[]}; + var s, i, d0, d, j, r, p; + var threshold; + var c = plot.plugins.cursor; + for (var i=0; i<plot.series.length; i++) { + s = plot.series[i]; + r = s.renderer; + if (s.show) { + threshold = c.intersectionThreshold; + if (s.showMarker) { + threshold += s.markerRenderer.size/2; + } + for (var j=0; j<s.gridData.length; j++) { + p = s.gridData[j]; + // check vertical line + if (c.showVerticalLine) { + if (Math.abs(x-p[0]) <= threshold) { + ret.indices.push(i); + ret.data.push({seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]}); + } + } + } + } + } + return ret; + } + + function moveTooltip(gridpos, plot) { + var c = plot.plugins.cursor; + var elem = c._tooltipElem; + switch (c.tooltipLocation) { + case 'nw': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); + break; + case 'n': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; + var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); + break; + case 'ne': + var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top - c.tooltipOffset - elem.outerHeight(true); + break; + case 'e': + var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + case 'se': + var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; + break; + case 's': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; + var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; + break; + case 'sw': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; + break; + case 'w': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + default: + var x = gridpos.x + plot._gridPadding.left + c.tooltipOffset; + var y = gridpos.y + plot._gridPadding.top + c.tooltipOffset; + break; + } + + elem.css('left', x); + elem.css('top', y); + elem = null; + } + + function positionTooltip(plot) { + // fake a grid for positioning + var grid = plot._gridPadding; + var c = plot.plugins.cursor; + var elem = c._tooltipElem; + switch (c.tooltipLocation) { + case 'nw': + var a = grid.left + c.tooltipOffset; + var b = grid.top + c.tooltipOffset; + elem.css('left', a); + elem.css('top', b); + break; + case 'n': + var a = (grid.left + (plot._plotDimensions.width - grid.right))/2 - elem.outerWidth(true)/2; + var b = grid.top + c.tooltipOffset; + elem.css('left', a); + elem.css('top', b); + break; + case 'ne': + var a = grid.right + c.tooltipOffset; + var b = grid.top + c.tooltipOffset; + elem.css({right:a, top:b}); + break; + case 'e': + var a = grid.right + c.tooltipOffset; + var b = (grid.top + (plot._plotDimensions.height - grid.bottom))/2 - elem.outerHeight(true)/2; + elem.css({right:a, top:b}); + break; + case 'se': + var a = grid.right + c.tooltipOffset; + var b = grid.bottom + c.tooltipOffset; + elem.css({right:a, bottom:b}); + break; + case 's': + var a = (grid.left + (plot._plotDimensions.width - grid.right))/2 - elem.outerWidth(true)/2; + var b = grid.bottom + c.tooltipOffset; + elem.css({left:a, bottom:b}); + break; + case 'sw': + var a = grid.left + c.tooltipOffset; + var b = grid.bottom + c.tooltipOffset; + elem.css({left:a, bottom:b}); + break; + case 'w': + var a = grid.left + c.tooltipOffset; + var b = (grid.top + (plot._plotDimensions.height - grid.bottom))/2 - elem.outerHeight(true)/2; + elem.css({left:a, top:b}); + break; + default: // same as 'se' + var a = grid.right - c.tooltipOffset; + var b = grid.bottom + c.tooltipOffset; + elem.css({right:a, bottom:b}); + break; + } + elem = null; + } + + function handleClick (ev, gridpos, datapos, neighbor, plot) { + ev.preventDefault(); + ev.stopImmediatePropagation(); + var c = plot.plugins.cursor; + if (c.clickReset) { + c.resetZoom(plot, c); + } + var sel = window.getSelection; + if (document.selection && document.selection.empty) + { + document.selection.empty(); + } + else if (sel && !sel().isCollapsed) { + sel().collapse(); + } + return false; + } + + function handleDblClick (ev, gridpos, datapos, neighbor, plot) { + ev.preventDefault(); + ev.stopImmediatePropagation(); + var c = plot.plugins.cursor; + if (c.dblClickReset) { + c.resetZoom(plot, c); + } + var sel = window.getSelection; + if (document.selection && document.selection.empty) + { + document.selection.empty(); + } + else if (sel && !sel().isCollapsed) { + sel().collapse(); + } + return false; + } + + function handleMouseLeave(ev, gridpos, datapos, neighbor, plot) { + var c = plot.plugins.cursor; + c.onGrid = false; + if (c.show) { + $(ev.target).css('cursor', c.previousCursor); + if (c.showTooltip && !(c._zoom.zooming && c.showTooltipOutsideZoom && !c.constrainOutsideZoom)) { + c._tooltipElem.empty(); + c._tooltipElem.hide(); + } + if (c.zoom) { + c._zoom.gridpos = gridpos; + c._zoom.datapos = datapos; + } + if (c.showVerticalLine || c.showHorizontalLine) { + var ctx = c.cursorCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx = null; + } + if (c.showCursorLegend) { + var cells = $(plot.targetId + ' td.jqplot-cursor-legend-label'); + for (var i=0; i<cells.length; i++) { + var idx = $(cells[i]).data('seriesIndex'); + var series = plot.series[idx]; + var label = series.label.toString(); + if (plot.legend.escapeHtml) { + $(cells[i]).text($.jqplot.sprintf(c.cursorLegendFormatString, label, undefined, undefined)); + } + else { + $(cells[i]).html($.jqplot.sprintf(c.cursorLegendFormatString, label, undefined, undefined)); + } + + } + } + } + } + + function handleMouseEnter(ev, gridpos, datapos, neighbor, plot) { + var c = plot.plugins.cursor; + c.onGrid = true; + if (c.show) { + c.previousCursor = ev.target.style.cursor; + ev.target.style.cursor = c.style; + if (c.showTooltip) { + updateTooltip(gridpos, datapos, plot); + if (c.followMouse) { + moveTooltip(gridpos, plot); + } + else { + positionTooltip(plot); + } + c._tooltipElem.show(); + } + if (c.showVerticalLine || c.showHorizontalLine) { + moveLine(gridpos, plot); + } + } + + } + + function handleMouseMove(ev, gridpos, datapos, neighbor, plot) { + var c = plot.plugins.cursor; + if (c.show) { + if (c.showTooltip) { + updateTooltip(gridpos, datapos, plot); + if (c.followMouse) { + moveTooltip(gridpos, plot); + } + } + if (c.showVerticalLine || c.showHorizontalLine) { + moveLine(gridpos, plot); + } + } + } + + function getEventPosition(ev) { + var plot = ev.data.plot; + var go = plot.eventCanvas._elem.offset(); + var gridPos = {x:ev.pageX - go.left, y:ev.pageY - go.top}; + ////// + // TO DO: handle yMidAxis + ////// + var dataPos = {xaxis:null, yaxis:null, x2axis:null, y2axis:null, y3axis:null, y4axis:null, y5axis:null, y6axis:null, y7axis:null, y8axis:null, y9axis:null, yMidAxis:null}; + var an = ['xaxis', 'yaxis', 'x2axis', 'y2axis', 'y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis', 'yMidAxis']; + var ax = plot.axes; + var n, axis; + for (n=11; n>0; n--) { + axis = an[n-1]; + if (ax[axis].show) { + dataPos[axis] = ax[axis].series_p2u(gridPos[axis.charAt(0)]); + } + } + + return {offsets:go, gridPos:gridPos, dataPos:dataPos}; + } + + function handleZoomMove(ev) { + var plot = ev.data.plot; + var c = plot.plugins.cursor; + // don't do anything if not on grid. + if (c.show && c.zoom && c._zoom.started && !c.zoomTarget) { + ev.preventDefault(); + var ctx = c.zoomCanvas._ctx; + var positions = getEventPosition(ev); + var gridpos = positions.gridPos; + var datapos = positions.dataPos; + c._zoom.gridpos = gridpos; + c._zoom.datapos = datapos; + c._zoom.zooming = true; + var xpos = gridpos.x; + var ypos = gridpos.y; + var height = ctx.canvas.height; + var width = ctx.canvas.width; + if (c.showTooltip && !c.onGrid && c.showTooltipOutsideZoom) { + updateTooltip(gridpos, datapos, plot); + if (c.followMouse) { + moveTooltip(gridpos, plot); + } + } + if (c.constrainZoomTo == 'x') { + c._zoom.end = [xpos, height]; + } + else if (c.constrainZoomTo == 'y') { + c._zoom.end = [width, ypos]; + } + else { + c._zoom.end = [xpos, ypos]; + } + var sel = window.getSelection; + if (document.selection && document.selection.empty) + { + document.selection.empty(); + } + else if (sel && !sel().isCollapsed) { + sel().collapse(); + } + drawZoomBox.call(c); + ctx = null; + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + var c = plot.plugins.cursor; + if(plot.plugins.mobile){ + $(document).one('vmouseup.jqplot_cursor', {plot:plot}, handleMouseUp); + } else { + $(document).one('mouseup.jqplot_cursor', {plot:plot}, handleMouseUp); + } + var axes = plot.axes; + if (document.onselectstart != undefined) { + c._oldHandlers.onselectstart = document.onselectstart; + document.onselectstart = function () { return false; }; + } + if (document.ondrag != undefined) { + c._oldHandlers.ondrag = document.ondrag; + document.ondrag = function () { return false; }; + } + if (document.onmousedown != undefined) { + c._oldHandlers.onmousedown = document.onmousedown; + document.onmousedown = function () { return false; }; + } + if (c.zoom) { + if (!c.zoomProxy) { + var ctx = c.zoomCanvas._ctx; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx = null; + } + if (c.constrainZoomTo == 'x') { + c._zoom.start = [gridpos.x, 0]; + } + else if (c.constrainZoomTo == 'y') { + c._zoom.start = [0, gridpos.y]; + } + else { + c._zoom.start = [gridpos.x, gridpos.y]; + } + c._zoom.started = true; + for (var ax in datapos) { + // get zoom starting position. + c._zoom.axes.start[ax] = datapos[ax]; + } + if(plot.plugins.mobile){ + $(document).bind('vmousemove.jqplotCursor', {plot:plot}, handleZoomMove); + } else { + $(document).bind('mousemove.jqplotCursor', {plot:plot}, handleZoomMove); + } + + } + } + + function handleMouseUp(ev) { + var plot = ev.data.plot; + var c = plot.plugins.cursor; + if (c.zoom && c._zoom.zooming && !c.zoomTarget) { + var xpos = c._zoom.gridpos.x; + var ypos = c._zoom.gridpos.y; + var datapos = c._zoom.datapos; + var height = c.zoomCanvas._ctx.canvas.height; + var width = c.zoomCanvas._ctx.canvas.width; + var axes = plot.axes; + + if (c.constrainOutsideZoom && !c.onGrid) { + if (xpos < 0) { xpos = 0; } + else if (xpos > width) { xpos = width; } + if (ypos < 0) { ypos = 0; } + else if (ypos > height) { ypos = height; } + + for (var axis in datapos) { + if (datapos[axis]) { + if (axis.charAt(0) == 'x') { + datapos[axis] = axes[axis].series_p2u(xpos); + } + else { + datapos[axis] = axes[axis].series_p2u(ypos); + } + } + } + } + + if (c.constrainZoomTo == 'x') { + ypos = height; + } + else if (c.constrainZoomTo == 'y') { + xpos = width; + } + c._zoom.end = [xpos, ypos]; + c._zoom.gridpos = {x:xpos, y:ypos}; + + c.doZoom(c._zoom.gridpos, datapos, plot, c); + } + c._zoom.started = false; + c._zoom.zooming = false; + + $(document).unbind('mousemove.jqplotCursor', handleZoomMove); + + if (document.onselectstart != undefined && c._oldHandlers.onselectstart != null){ + document.onselectstart = c._oldHandlers.onselectstart; + c._oldHandlers.onselectstart = null; + } + if (document.ondrag != undefined && c._oldHandlers.ondrag != null){ + document.ondrag = c._oldHandlers.ondrag; + c._oldHandlers.ondrag = null; + } + if (document.onmousedown != undefined && c._oldHandlers.onmousedown != null){ + document.onmousedown = c._oldHandlers.onmousedown; + c._oldHandlers.onmousedown = null; + } + + } + + function drawZoomBox() { + var start = this._zoom.start; + var end = this._zoom.end; + var ctx = this.zoomCanvas._ctx; + var l, t, h, w; + if (end[0] > start[0]) { + l = start[0]; + w = end[0] - start[0]; + } + else { + l = end[0]; + w = start[0] - end[0]; + } + if (end[1] > start[1]) { + t = start[1]; + h = end[1] - start[1]; + } + else { + t = end[1]; + h = start[1] - end[1]; + } + ctx.fillStyle = 'rgba(0,0,0,0.2)'; + ctx.strokeStyle = '#999999'; + ctx.lineWidth = 1.0; + ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height); + ctx.clearRect(l, t, w, h); + // IE won't show transparent fill rect, so stroke a rect also. + ctx.strokeRect(l,t,w,h); + ctx = null; + } + + $.jqplot.CursorLegendRenderer = function(options) { + $.jqplot.TableLegendRenderer.call(this, options); + this.formatString = '%s'; + }; + + $.jqplot.CursorLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.CursorLegendRenderer.prototype.constructor = $.jqplot.CursorLegendRenderer; + + // called in context of a Legend + $.jqplot.CursorLegendRenderer.prototype.draw = function() { + if (this._elem) { + this._elem.emptyForce(); + this._elem = null; + } + if (this.show) { + var series = this._series, s; + // make a table. one line label per row. + var elem = document.createElement('table'); + this._elem = $(elem); + elem = null; + this._elem.addClass('jqplot-legend jqplot-cursor-legend'); + this._elem.css('position', 'absolute'); + + var pad = false; + for (var i = 0; i< series.length; i++) { + s = series[i]; + if (s.show && s.showLabel) { + var lt = $.jqplot.sprintf(this.formatString, s.label.toString()); + if (lt) { + var color = s.color; + if (s._stack && !s.fill) { + color = ''; + } + addrow.call(this, lt, color, pad, i); + pad = true; + } + // let plugins add more rows to legend. Used by trend line plugin. + for (var j=0; j<$.jqplot.addLegendRowHooks.length; j++) { + var item = $.jqplot.addLegendRowHooks[j].call(this, s); + if (item) { + addrow.call(this, item.label, item.color, pad); + pad = true; + } + } + } + } + series = s = null; + delete series; + delete s; + } + + function addrow(label, color, pad, idx) { + var rs = (pad) ? this.rowSpacing : '0'; + var tr = $('<tr class="jqplot-legend jqplot-cursor-legend"></tr>').appendTo(this._elem); + tr.data('seriesIndex', idx); + $('<td class="jqplot-legend jqplot-cursor-legend-swatch" style="padding-top:'+rs+';">'+ + '<div style="border:1px solid #cccccc;padding:0.2em;">'+ + '<div class="jqplot-cursor-legend-swatch" style="background-color:'+color+';"></div>'+ + '</div></td>').appendTo(tr); + var td = $('<td class="jqplot-legend jqplot-cursor-legend-label" style="vertical-align:middle;padding-top:'+rs+';"></td>'); + td.appendTo(tr); + td.data('seriesIndex', idx); + if (this.escapeHtml) { + td.text(label); + } + else { + td.html(label); + } + tr = null; + td = null; + } + return this._elem; + }; + +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.min.js new file mode 100644 index 0000000..4471309 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.cursor.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(j){j.jqplot.Cursor=function(q){this.style="crosshair";this.previousCursor="auto";this.show=j.jqplot.config.enablePlugins;this.showTooltip=true;this.followMouse=false;this.tooltipLocation="se";this.tooltipOffset=6;this.showTooltipGridPosition=false;this.showTooltipUnitPosition=true;this.showTooltipDataPosition=false;this.tooltipFormatString="%.4P, %.4P";this.useAxesFormatters=true;this.tooltipAxisGroups=[];this.zoom=false;this.zoomProxy=false;this.zoomTarget=false;this.looseZoom=true;this.clickReset=false;this.dblClickReset=true;this.showVerticalLine=false;this.showHorizontalLine=false;this.constrainZoomTo="none";this.shapeRenderer=new j.jqplot.ShapeRenderer();this._zoom={start:[],end:[],started:false,zooming:false,isZoomed:false,axes:{start:{},end:{}},gridpos:{},datapos:{}};this._tooltipElem;this.zoomCanvas;this.cursorCanvas;this.intersectionThreshold=2;this.showCursorLegend=false;this.cursorLegendFormatString=j.jqplot.Cursor.cursorLegendFormatString;this._oldHandlers={onselectstart:null,ondrag:null,onmousedown:null};this.constrainOutsideZoom=true;this.showTooltipOutsideZoom=false;this.onGrid=false;j.extend(true,this,q)};j.jqplot.Cursor.cursorLegendFormatString="%s x:%s, y:%s";j.jqplot.Cursor.init=function(t,s,r){var q=r||{};this.plugins.cursor=new j.jqplot.Cursor(q.cursor);var u=this.plugins.cursor;if(u.show){j.jqplot.eventListenerHooks.push(["jqplotMouseEnter",b]);j.jqplot.eventListenerHooks.push(["jqplotMouseLeave",f]);j.jqplot.eventListenerHooks.push(["jqplotMouseMove",i]);if(u.showCursorLegend){r.legend=r.legend||{};r.legend.renderer=j.jqplot.CursorLegendRenderer;r.legend.formatString=this.plugins.cursor.cursorLegendFormatString;r.legend.show=true}if(u.zoom){j.jqplot.eventListenerHooks.push(["jqplotMouseDown",a]);if(u.clickReset){j.jqplot.eventListenerHooks.push(["jqplotClick",k])}if(u.dblClickReset){j.jqplot.eventListenerHooks.push(["jqplotDblClick",c])}}this.resetZoom=function(){var x=this.axes;if(!u.zoomProxy){for(var w in x){x[w].reset();x[w]._ticks=[];if(u._zoom.axes[w]!==undefined){x[w]._autoFormatString=u._zoom.axes[w].tickFormatString}}this.redraw()}else{var v=this.plugins.cursor.zoomCanvas._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);v=null}this.plugins.cursor._zoom.isZoomed=false;this.target.trigger("jqplotResetZoom",[this,this.plugins.cursor])};if(u.showTooltipDataPosition){u.showTooltipUnitPosition=false;u.showTooltipGridPosition=false;if(q.cursor.tooltipFormatString==undefined){u.tooltipFormatString=j.jqplot.Cursor.cursorLegendFormatString}}}};j.jqplot.Cursor.postDraw=function(){var x=this.plugins.cursor;if(x.zoomCanvas){x.zoomCanvas.resetCanvas();x.zoomCanvas=null}if(x.cursorCanvas){x.cursorCanvas.resetCanvas();x.cursorCanvas=null}if(x._tooltipElem){x._tooltipElem.emptyForce();x._tooltipElem=null}if(x.zoom){x.zoomCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.zoomCanvas.createElement(this._gridPadding,"jqplot-zoom-canvas",this._plotDimensions,this));x.zoomCanvas.setContext()}var v=document.createElement("div");x._tooltipElem=j(v);v=null;x._tooltipElem.addClass("jqplot-cursor-tooltip");x._tooltipElem.css({position:"absolute",display:"none"});if(x.zoomCanvas){x.zoomCanvas._elem.before(x._tooltipElem)}else{this.eventCanvas._elem.before(x._tooltipElem)}if(x.showVerticalLine||x.showHorizontalLine){x.cursorCanvas=new j.jqplot.GenericCanvas();this.eventCanvas._elem.before(x.cursorCanvas.createElement(this._gridPadding,"jqplot-cursor-canvas",this._plotDimensions,this));x.cursorCanvas.setContext()}if(x.showTooltipUnitPosition){if(x.tooltipAxisGroups.length===0){var t=this.series;var u;var q=[];for(var r=0;r<t.length;r++){u=t[r];var w=u.xaxis+","+u.yaxis;if(j.inArray(w,q)==-1){q.push(w)}}for(var r=0;r<q.length;r++){x.tooltipAxisGroups.push(q[r].split(","))}}}};j.jqplot.Cursor.zoomProxy=function(v,r){var q=v.plugins.cursor;var u=r.plugins.cursor;q.zoomTarget=true;q.zoom=true;q.style="auto";q.dblClickReset=false;u.zoom=true;u.zoomProxy=true;r.target.bind("jqplotZoom",t);r.target.bind("jqplotResetZoom",s);function t(x,w,z,y,A){q.doZoom(w,z,v,A)}function s(w,x,y){v.resetZoom()}};j.jqplot.Cursor.prototype.resetZoom=function(u,v){var t=u.axes;var s=v._zoom.axes;if(!u.plugins.cursor.zoomProxy&&v._zoom.isZoomed){for(var r in t){t[r].reset();t[r]._ticks=[];t[r]._autoFormatString=s[r].tickFormatString}u.redraw();v._zoom.isZoomed=false}else{var q=v.zoomCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);q=null}u.target.trigger("jqplotResetZoom",[u,v])};j.jqplot.Cursor.resetZoom=function(q){q.resetZoom()};j.jqplot.Cursor.prototype.doZoom=function(G,t,C,u){var I=u;var F=C.axes;var r=I._zoom.axes;var w=r.start;var s=r.end;var B,E,z,D,v,x,q,H,J;var A=C.plugins.cursor.zoomCanvas._ctx;if((I.constrainZoomTo=="none"&&Math.abs(G.x-I._zoom.start[0])>6&&Math.abs(G.y-I._zoom.start[1])>6)||(I.constrainZoomTo=="x"&&Math.abs(G.x-I._zoom.start[0])>6)||(I.constrainZoomTo=="y"&&Math.abs(G.y-I._zoom.start[1])>6)){if(!C.plugins.cursor.zoomProxy){for(var y in t){if(I._zoom.axes[y]==undefined){I._zoom.axes[y]={};I._zoom.axes[y].numberTicks=F[y].numberTicks;I._zoom.axes[y].tickInterval=F[y].tickInterval;I._zoom.axes[y].daTickInterval=F[y].daTickInterval;I._zoom.axes[y].min=F[y].min;I._zoom.axes[y].max=F[y].max;I._zoom.axes[y].tickFormatString=(F[y].tickOptions!=null)?F[y].tickOptions.formatString:""}if((I.constrainZoomTo=="none")||(I.constrainZoomTo=="x"&&y.charAt(0)=="x")||(I.constrainZoomTo=="y"&&y.charAt(0)=="y")){z=t[y];if(z!=null){if(z>w[y]){v=w[y];x=z}else{D=w[y]-z;v=z;x=w[y]}q=F[y];H=null;if(q.alignTicks){if(q.name==="x2axis"&&C.axes.xaxis.show){H=C.axes.xaxis.numberTicks}else{if(q.name.charAt(0)==="y"&&q.name!=="yaxis"&&q.name!=="yMidAxis"&&C.axes.yaxis.show){H=C.axes.yaxis.numberTicks}}}if(this.looseZoom&&(F[y].renderer.constructor===j.jqplot.LinearAxisRenderer||F[y].renderer.constructor===j.jqplot.LogAxisRenderer)){J=j.jqplot.LinearTickGenerator(v,x,q._scalefact,H);if(F[y].tickInset&&J[0]<F[y].min+F[y].tickInset*F[y].tickInterval){J[0]+=J[4];J[2]-=1}if(F[y].tickInset&&J[1]>F[y].max-F[y].tickInset*F[y].tickInterval){J[1]-=J[4];J[2]-=1}if(F[y].renderer.constructor===j.jqplot.LogAxisRenderer&&J[0]<F[y].min){J[0]+=J[4];J[2]-=1}F[y].min=J[0];F[y].max=J[1];F[y]._autoFormatString=J[3];F[y].numberTicks=J[2];F[y].tickInterval=J[4];F[y].daTickInterval=[J[4]/1000,"seconds"]}else{F[y].min=v;F[y].max=x;F[y].tickInterval=null;F[y].numberTicks=null;F[y].daTickInterval=null}F[y]._ticks=[]}}}A.clearRect(0,0,A.canvas.width,A.canvas.height);C.redraw();I._zoom.isZoomed=true;A=null}C.target.trigger("jqplotZoom",[G,t,C,u])}};j.jqplot.preInitHooks.push(j.jqplot.Cursor.init);j.jqplot.postDrawHooks.push(j.jqplot.Cursor.postDraw);function e(G,r,C){var J=C.plugins.cursor;var w="";var N=false;if(J.showTooltipGridPosition){w=G.x+", "+G.y;N=true}if(J.showTooltipUnitPosition){var F;for(var E=0;E<J.tooltipAxisGroups.length;E++){F=J.tooltipAxisGroups[E];if(N){w+="<br />"}if(J.useAxesFormatters){for(var D=0;D<F.length;D++){if(D){w+=", "}var H=C.axes[F[D]]._ticks[0].formatter;var B=C.axes[F[D]]._ticks[0].formatString;w+=H(B,r[F[D]])}}else{w+=j.jqplot.sprintf(J.tooltipFormatString,r[F[0]],r[F[1]])}N=true}}if(J.showTooltipDataPosition){var u=C.series;var M=d(C,G.x,G.y);var N=false;for(var E=0;E<u.length;E++){if(u[E].show){var y=u[E].index;var t=u[E].label.toString();var I=j.inArray(y,M.indices);var z=undefined;var x=undefined;if(I!=-1){var L=M.data[I].data;if(J.useAxesFormatters){var A=u[E]._xaxis._ticks[0].formatter;var q=u[E]._yaxis._ticks[0].formatter;var K=u[E]._xaxis._ticks[0].formatString;var v=u[E]._yaxis._ticks[0].formatString;z=A(K,L[0]);x=q(v,L[1])}else{z=L[0];x=L[1]}if(N){w+="<br />"}w+=j.jqplot.sprintf(J.tooltipFormatString,t,z,x);N=true}}}}J._tooltipElem.html(w)}function g(C,A){var E=A.plugins.cursor;var z=E.cursorCanvas._ctx;z.clearRect(0,0,z.canvas.width,z.canvas.height);if(E.showVerticalLine){E.shapeRenderer.draw(z,[[C.x,0],[C.x,z.canvas.height]])}if(E.showHorizontalLine){E.shapeRenderer.draw(z,[[0,C.y],[z.canvas.width,C.y]])}var G=d(A,C.x,C.y);if(E.showCursorLegend){var r=j(A.targetId+" td.jqplot-cursor-legend-label");for(var B=0;B<r.length;B++){var v=j(r[B]).data("seriesIndex");var t=A.series[v];var s=t.label.toString();var D=j.inArray(v,G.indices);var x=undefined;var w=undefined;if(D!=-1){var H=G.data[D].data;if(E.useAxesFormatters){var y=t._xaxis._ticks[0].formatter;var q=t._yaxis._ticks[0].formatter;var F=t._xaxis._ticks[0].formatString;var u=t._yaxis._ticks[0].formatString;x=y(F,H[0]);w=q(u,H[1])}else{x=H[0];w=H[1]}}if(A.legend.escapeHtml){j(r[B]).text(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}else{j(r[B]).html(j.jqplot.sprintf(E.cursorLegendFormatString,s,x,w))}}}z=null}function d(A,F,E){var B={indices:[],data:[]};var G,w,u,C,v,q,t;var z;var D=A.plugins.cursor;for(var w=0;w<A.series.length;w++){G=A.series[w];q=G.renderer;if(G.show){z=D.intersectionThreshold;if(G.showMarker){z+=G.markerRenderer.size/2}for(var v=0;v<G.gridData.length;v++){t=G.gridData[v];if(D.showVerticalLine){if(Math.abs(F-t[0])<=z){B.indices.push(w);B.data.push({seriesIndex:w,pointIndex:v,gridData:t,data:G.data[v]})}}}}}return B}function n(r,t){var v=t.plugins.cursor;var s=v._tooltipElem;switch(v.tooltipLocation){case"nw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"n":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"ne":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-v.tooltipOffset-s.outerHeight(true);break;case"e":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;case"se":var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"s":var q=r.x+t._gridPadding.left-s.outerWidth(true)/2;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"sw":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break;case"w":var q=r.x+t._gridPadding.left-s.outerWidth(true)-v.tooltipOffset;var u=r.y+t._gridPadding.top-s.outerHeight(true)/2;break;default:var q=r.x+t._gridPadding.left+v.tooltipOffset;var u=r.y+t._gridPadding.top+v.tooltipOffset;break}s.css("left",q);s.css("top",u);s=null}function m(u){var s=u._gridPadding;var v=u.plugins.cursor;var t=v._tooltipElem;switch(v.tooltipLocation){case"nw":var r=s.left+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"n":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.top+v.tooltipOffset;t.css("left",r);t.css("top",q);break;case"ne":var r=s.right+v.tooltipOffset;var q=s.top+v.tooltipOffset;t.css({right:r,top:q});break;case"e":var r=s.right+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({right:r,top:q});break;case"se":var r=s.right+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break;case"s":var r=(s.left+(u._plotDimensions.width-s.right))/2-t.outerWidth(true)/2;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"sw":var r=s.left+v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({left:r,bottom:q});break;case"w":var r=s.left+v.tooltipOffset;var q=(s.top+(u._plotDimensions.height-s.bottom))/2-t.outerHeight(true)/2;t.css({left:r,top:q});break;default:var r=s.right-v.tooltipOffset;var q=s.bottom+v.tooltipOffset;t.css({right:r,bottom:q});break}t=null}function k(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.clickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function c(r,q,v,u,t){r.preventDefault();r.stopImmediatePropagation();var w=t.plugins.cursor;if(w.dblClickReset){w.resetZoom(t,w)}var s=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(s&&!s().isCollapsed){s().collapse()}}return false}function f(w,t,q,z,u){var v=u.plugins.cursor;v.onGrid=false;if(v.show){j(w.target).css("cursor",v.previousCursor);if(v.showTooltip&&!(v._zoom.zooming&&v.showTooltipOutsideZoom&&!v.constrainOutsideZoom)){v._tooltipElem.empty();v._tooltipElem.hide()}if(v.zoom){v._zoom.gridpos=t;v._zoom.datapos=q}if(v.showVerticalLine||v.showHorizontalLine){var B=v.cursorCanvas._ctx;B.clearRect(0,0,B.canvas.width,B.canvas.height);B=null}if(v.showCursorLegend){var A=j(u.targetId+" td.jqplot-cursor-legend-label");for(var s=0;s<A.length;s++){var y=j(A[s]).data("seriesIndex");var r=u.series[y];var x=r.label.toString();if(u.legend.escapeHtml){j(A[s]).text(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}else{j(A[s]).html(j.jqplot.sprintf(v.cursorLegendFormatString,x,undefined,undefined))}}}}}function b(r,q,u,t,s){var v=s.plugins.cursor;v.onGrid=true;if(v.show){v.previousCursor=r.target.style.cursor;r.target.style.cursor=v.style;if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}else{m(s)}v._tooltipElem.show()}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function i(r,q,u,t,s){var v=s.plugins.cursor;if(v.show){if(v.showTooltip){e(q,u,s);if(v.followMouse){n(q,s)}}if(v.showVerticalLine||v.showHorizontalLine){g(q,s)}}}function o(y){var x=y.data.plot;var t=x.eventCanvas._elem.offset();var w={x:y.pageX-t.left,y:y.pageY-t.top};var u={xaxis:null,yaxis:null,x2axis:null,y2axis:null,y3axis:null,y4axis:null,y5axis:null,y6axis:null,y7axis:null,y8axis:null,y9axis:null,yMidAxis:null};var v=["xaxis","yaxis","x2axis","y2axis","y3axis","y4axis","y5axis","y6axis","y7axis","y8axis","y9axis","yMidAxis"];var q=x.axes;var r,s;for(r=11;r>0;r--){s=v[r-1];if(q[s].show){u[s]=q[s].series_p2u(w[s.charAt(0)])}}return{offsets:t,gridPos:w,dataPos:u}}function h(z){var x=z.data.plot;var y=x.plugins.cursor;if(y.show&&y.zoom&&y._zoom.started&&!y.zoomTarget){z.preventDefault();var B=y.zoomCanvas._ctx;var v=o(z);var w=v.gridPos;var t=v.dataPos;y._zoom.gridpos=w;y._zoom.datapos=t;y._zoom.zooming=true;var u=w.x;var s=w.y;var A=B.canvas.height;var q=B.canvas.width;if(y.showTooltip&&!y.onGrid&&y.showTooltipOutsideZoom){e(w,t,x);if(y.followMouse){n(w,x)}}if(y.constrainZoomTo=="x"){y._zoom.end=[u,A]}else{if(y.constrainZoomTo=="y"){y._zoom.end=[q,s]}else{y._zoom.end=[u,s]}}var r=window.getSelection;if(document.selection&&document.selection.empty){document.selection.empty()}else{if(r&&!r().isCollapsed){r().collapse()}}l.call(y);B=null}}function a(w,s,r,x,t){var v=t.plugins.cursor;if(t.plugins.mobile){j(document).one("vmouseup.jqplot_cursor",{plot:t},p)}else{j(document).one("mouseup.jqplot_cursor",{plot:t},p)}var u=t.axes;if(document.onselectstart!=undefined){v._oldHandlers.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!=undefined){v._oldHandlers.ondrag=document.ondrag;document.ondrag=function(){return false}}if(document.onmousedown!=undefined){v._oldHandlers.onmousedown=document.onmousedown;document.onmousedown=function(){return false}}if(v.zoom){if(!v.zoomProxy){var y=v.zoomCanvas._ctx;y.clearRect(0,0,y.canvas.width,y.canvas.height);y=null}if(v.constrainZoomTo=="x"){v._zoom.start=[s.x,0]}else{if(v.constrainZoomTo=="y"){v._zoom.start=[0,s.y]}else{v._zoom.start=[s.x,s.y]}}v._zoom.started=true;for(var q in r){v._zoom.axes.start[q]=r[q]}if(t.plugins.mobile){j(document).bind("vmousemove.jqplotCursor",{plot:t},h)}else{j(document).bind("mousemove.jqplotCursor",{plot:t},h)}}}function p(y){var v=y.data.plot;var x=v.plugins.cursor;if(x.zoom&&x._zoom.zooming&&!x.zoomTarget){var u=x._zoom.gridpos.x;var r=x._zoom.gridpos.y;var t=x._zoom.datapos;var z=x.zoomCanvas._ctx.canvas.height;var q=x.zoomCanvas._ctx.canvas.width;var w=v.axes;if(x.constrainOutsideZoom&&!x.onGrid){if(u<0){u=0}else{if(u>q){u=q}}if(r<0){r=0}else{if(r>z){r=z}}for(var s in t){if(t[s]){if(s.charAt(0)=="x"){t[s]=w[s].series_p2u(u)}else{t[s]=w[s].series_p2u(r)}}}}if(x.constrainZoomTo=="x"){r=z}else{if(x.constrainZoomTo=="y"){u=q}}x._zoom.end=[u,r];x._zoom.gridpos={x:u,y:r};x.doZoom(x._zoom.gridpos,t,v,x)}x._zoom.started=false;x._zoom.zooming=false;j(document).unbind("mousemove.jqplotCursor",h);if(document.onselectstart!=undefined&&x._oldHandlers.onselectstart!=null){document.onselectstart=x._oldHandlers.onselectstart;x._oldHandlers.onselectstart=null}if(document.ondrag!=undefined&&x._oldHandlers.ondrag!=null){document.ondrag=x._oldHandlers.ondrag;x._oldHandlers.ondrag=null}if(document.onmousedown!=undefined&&x._oldHandlers.onmousedown!=null){document.onmousedown=x._oldHandlers.onmousedown;x._oldHandlers.onmousedown=null}}function l(){var y=this._zoom.start;var u=this._zoom.end;var s=this.zoomCanvas._ctx;var r,v,x,q;if(u[0]>y[0]){r=y[0];q=u[0]-y[0]}else{r=u[0];q=y[0]-u[0]}if(u[1]>y[1]){v=y[1];x=u[1]-y[1]}else{v=u[1];x=y[1]-u[1]}s.fillStyle="rgba(0,0,0,0.2)";s.strokeStyle="#999999";s.lineWidth=1;s.clearRect(0,0,s.canvas.width,s.canvas.height);s.fillRect(0,0,s.canvas.width,s.canvas.height);s.clearRect(r,v,q,x);s.strokeRect(r,v,q,x);s=null}j.jqplot.CursorLegendRenderer=function(q){j.jqplot.TableLegendRenderer.call(this,q);this.formatString="%s"};j.jqplot.CursorLegendRenderer.prototype=new j.jqplot.TableLegendRenderer();j.jqplot.CursorLegendRenderer.prototype.constructor=j.jqplot.CursorLegendRenderer;j.jqplot.CursorLegendRenderer.prototype.draw=function(){if(this._elem){this._elem.emptyForce();this._elem=null}if(this.show){var w=this._series,A;var r=document.createElement("table");this._elem=j(r);r=null;this._elem.addClass("jqplot-legend jqplot-cursor-legend");this._elem.css("position","absolute");var q=false;for(var x=0;x<w.length;x++){A=w[x];if(A.show&&A.showLabel){var v=j.jqplot.sprintf(this.formatString,A.label.toString());if(v){var t=A.color;if(A._stack&&!A.fill){t=""}z.call(this,v,t,q,x);q=true}for(var u=0;u<j.jqplot.addLegendRowHooks.length;u++){var y=j.jqplot.addLegendRowHooks[u].call(this,A);if(y){z.call(this,y.label,y.color,q);q=true}}}}w=A=null;delete w;delete A}function z(D,C,F,s){var B=(F)?this.rowSpacing:"0";var E=j('<tr class="jqplot-legend jqplot-cursor-legend"></tr>').appendTo(this._elem);E.data("seriesIndex",s);j('<td class="jqplot-legend jqplot-cursor-legend-swatch" style="padding-top:'+B+';"><div style="border:1px solid #cccccc;padding:0.2em;"><div class="jqplot-cursor-legend-swatch" style="background-color:'+C+';"></div></div></td>').appendTo(E);var G=j('<td class="jqplot-legend jqplot-cursor-legend-label" style="vertical-align:middle;padding-top:'+B+';"></td>');G.appendTo(E);G.data("seriesIndex",s);if(this.escapeHtml){G.text(D)}else{G.html(D)}E=null;G=null}return this._elem}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.js new file mode 100644 index 0000000..e371a28 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.js @@ -0,0 +1,741 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.DateAxisRenderer + * A plugin for a jqPlot to render an axis as a series of date values. + * This renderer has no options beyond those supplied by the <Axis> class. + * It supplies its own tick formatter, so the tickOptions.formatter option + * should not be overridden. + * + * Thanks to Ken Synder for his enhanced Date instance methods which are + * included with this code <http://kendsnyder.com/sandbox/date/>. + * + * To use this renderer, include the plugin in your source + * > <script type="text/javascript" language="javascript" src="plugins/jqplot.dateAxisRenderer.js"></script> + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.DateAxisRenderer}}} + * + * Dates can be passed into the axis in almost any recognizable value and + * will be parsed. They will be rendered on the axis in the format + * specified by tickOptions.formatString. e.g. tickOptions.formatString = '%Y-%m-%d'. + * + * Accecptable format codes + * are: + * + * > Code Result Description + * > == Years == + * > %Y 2008 Four-digit year + * > %y 08 Two-digit year + * > == Months == + * > %m 09 Two-digit month + * > %#m 9 One or two-digit month + * > %B September Full month name + * > %b Sep Abbreviated month name + * > == Days == + * > %d 05 Two-digit day of month + * > %#d 5 One or two-digit day of month + * > %e 5 One or two-digit day of month + * > %A Sunday Full name of the day of the week + * > %a Sun Abbreviated name of the day of the week + * > %w 0 Number of the day of the week (0 = Sunday, 6 = Saturday) + * > %o th The ordinal suffix string following the day of the month + * > == Hours == + * > %H 23 Hours in 24-hour format (two digits) + * > %#H 3 Hours in 24-hour integer format (one or two digits) + * > %I 11 Hours in 12-hour format (two digits) + * > %#I 3 Hours in 12-hour integer format (one or two digits) + * > %p PM AM or PM + * > == Minutes == + * > %M 09 Minutes (two digits) + * > %#M 9 Minutes (one or two digits) + * > == Seconds == + * > %S 02 Seconds (two digits) + * > %#S 2 Seconds (one or two digits) + * > %s 1206567625723 Unix timestamp (Seconds past 1970-01-01 00:00:00) + * > == Milliseconds == + * > %N 008 Milliseconds (three digits) + * > %#N 8 Milliseconds (one to three digits) + * > == Timezone == + * > %O 360 difference in minutes between local time and GMT + * > %Z Mountain Standard Time Name of timezone as reported by browser + * > %G -06:00 Hours and minutes between GMT + * > == Shortcuts == + * > %F 2008-03-26 %Y-%m-%d + * > %T 05:06:30 %H:%M:%S + * > %X 05:06:30 %H:%M:%S + * > %x 03/26/08 %m/%d/%y + * > %D 03/26/08 %m/%d/%y + * > %#c Wed Mar 26 15:31:00 2008 %a %b %e %H:%M:%S %Y + * > %v 3-Sep-2008 %e-%b-%Y + * > %R 15:31 %H:%M + * > %r 3:31:00 PM %I:%M:%S %p + * > == Characters == + * > %n \n Newline + * > %t \t Tab + * > %% % Percent Symbol + */ + $.jqplot.DateAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + this.date = new $.jsDate(); + }; + + var second = 1000; + var minute = 60 * second; + var hour = 60 * minute; + var day = 24 * hour; + var week = 7 * day; + + // these are less definitive + var month = 30.4368499 * day; + var year = 365.242199 * day; + + var daysInMonths = [31,28,31,30,31,30,31,30,31,30,31,30]; + // array of consistent nice intervals. Longer intervals + // will depend on days in month, days in year, etc. + var niceFormatStrings = ['%M:%S.%#N', '%M:%S.%#N', '%M:%S.%#N', '%M:%S', '%M:%S', '%M:%S', '%M:%S', '%H:%M:%S', '%H:%M:%S', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%H:%M', '%a %H:%M', '%a %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%b %e %H:%M', '%v', '%v', '%v', '%v', '%v', '%v', '%v']; + var niceIntervals = [0.1*second, 0.2*second, 0.5*second, second, 2*second, 5*second, 10*second, 15*second, 30*second, minute, 2*minute, 5*minute, 10*minute, 15*minute, 30*minute, hour, 2*hour, 4*hour, 6*hour, 8*hour, 12*hour, day, 2*day, 3*day, 4*day, 5*day, week, 2*week]; + + var niceMonthlyIntervals = []; + + function bestDateInterval(min, max, titarget) { + // iterate through niceIntervals to find one closest to titarget + var badness = Number.MAX_VALUE; + var temp, bestTi, bestfmt; + for (var i=0, l=niceIntervals.length; i < l; i++) { + temp = Math.abs(titarget - niceIntervals[i]); + if (temp < badness) { + badness = temp; + bestTi = niceIntervals[i]; + bestfmt = niceFormatStrings[i]; + } + } + + return [bestTi, bestfmt]; + } + + $.jqplot.DateAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.DateAxisRenderer.prototype.constructor = $.jqplot.DateAxisRenderer; + + $.jqplot.DateTickFormatter = function(format, val) { + if (!format) { + format = '%Y/%m/%d'; + } + return $.jsDate.strftime(val, format); + }; + + $.jqplot.DateAxisRenderer.prototype.init = function(options){ + // prop: tickRenderer + // A class of a rendering engine for creating the ticks labels displayed on the plot, + // See <$.jqplot.AxisTickRenderer>. + // this.tickRenderer = $.jqplot.AxisTickRenderer; + // this.labelRenderer = $.jqplot.AxisLabelRenderer; + this.tickOptions.formatter = $.jqplot.DateTickFormatter; + // prop: tickInset + // Controls the amount to inset the first and last ticks from + // the edges of the grid, in multiples of the tick interval. + // 0 is no inset, 0.5 is one half a tick interval, 1 is a full + // tick interval, etc. + this.tickInset = 0; + // prop: drawBaseline + // True to draw the axis baseline. + this.drawBaseline = true; + // prop: baselineWidth + // width of the baseline in pixels. + this.baselineWidth = null; + // prop: baselineColor + // CSS color spec for the baseline. + this.baselineColor = null; + this.daTickInterval = null; + this._daTickInterval = null; + + $.extend(true, this, options); + + var db = this._dataBounds, + stats, + sum, + s, + d, + pd, + sd, + intv; + + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i<this._series.length; i++) { + stats = {intervals:[], frequencies:{}, sortedIntervals:[], min:null, max:null, mean:null}; + sum = 0; + s = this._series[i]; + d = s.data; + pd = s._plotData; + sd = s._stackData; + intv = 0; + + for (var j=0; j<d.length; j++) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + d[j][0] = new $.jsDate(d[j][0]).getTime(); + pd[j][0] = new $.jsDate(d[j][0]).getTime(); + sd[j][0] = new $.jsDate(d[j][0]).getTime(); + if ((d[j][0] != null && d[j][0] < db.min) || db.min == null) { + db.min = d[j][0]; + } + if ((d[j][0] != null && d[j][0] > db.max) || db.max == null) { + db.max = d[j][0]; + } + if (j>0) { + intv = Math.abs(d[j][0] - d[j-1][0]); + stats.intervals.push(intv); + if (stats.frequencies.hasOwnProperty(intv)) { + stats.frequencies[intv] += 1; + } + else { + stats.frequencies[intv] = 1; + } + } + sum += intv; + + } + else { + d[j][1] = new $.jsDate(d[j][1]).getTime(); + pd[j][1] = new $.jsDate(d[j][1]).getTime(); + sd[j][1] = new $.jsDate(d[j][1]).getTime(); + if ((d[j][1] != null && d[j][1] < db.min) || db.min == null) { + db.min = d[j][1]; + } + if ((d[j][1] != null && d[j][1] > db.max) || db.max == null) { + db.max = d[j][1]; + } + if (j>0) { + intv = Math.abs(d[j][1] - d[j-1][1]); + stats.intervals.push(intv); + if (stats.frequencies.hasOwnProperty(intv)) { + stats.frequencies[intv] += 1; + } + else { + stats.frequencies[intv] = 1; + } + } + } + sum += intv; + } + + if (s.renderer.bands) { + if (s.renderer.bands.hiData.length) { + var bd = s.renderer.bands.hiData; + for (var j=0, l=bd.length; j < l; j++) { + if (this.name === 'xaxis' || this.name === 'x2axis') { + bd[j][0] = new $.jsDate(bd[j][0]).getTime(); + if ((bd[j][0] != null && bd[j][0] > db.max) || db.max == null) { + db.max = bd[j][0]; + } + } + else { + bd[j][1] = new $.jsDate(bd[j][1]).getTime(); + if ((bd[j][1] != null && bd[j][1] > db.max) || db.max == null) { + db.max = bd[j][1]; + } + } + } + } + if (s.renderer.bands.lowData.length) { + var bd = s.renderer.bands.lowData; + for (var j=0, l=bd.length; j < l; j++) { + if (this.name === 'xaxis' || this.name === 'x2axis') { + bd[j][0] = new $.jsDate(bd[j][0]).getTime(); + if ((bd[j][0] != null && bd[j][0] < db.min) || db.min == null) { + db.min = bd[j][0]; + } + } + else { + bd[j][1] = new $.jsDate(bd[j][1]).getTime(); + if ((bd[j][1] != null && bd[j][1] < db.min) || db.min == null) { + db.min = bd[j][1]; + } + } + } + } + } + + var tempf = 0, + tempn=0; + for (var n in stats.frequencies) { + stats.sortedIntervals.push({interval:n, frequency:stats.frequencies[n]}); + } + stats.sortedIntervals.sort(function(a, b){ + return b.frequency - a.frequency; + }); + + stats.min = $.jqplot.arrayMin(stats.intervals); + stats.max = $.jqplot.arrayMax(stats.intervals); + stats.mean = sum/d.length; + this._intervalStats.push(stats); + stats = sum = s = d = pd = sd = null; + } + db = null; + + }; + + // called with scope of an axis + $.jqplot.DateAxisRenderer.prototype.reset = function() { + this.min = this._options.min; + this.max = this._options.max; + this.tickInterval = this._options.tickInterval; + this.numberTicks = this._options.numberTicks; + this._autoFormatString = ''; + if (this._overrideFormatString && this.tickOptions && this.tickOptions.formatString) { + this.tickOptions.formatString = ''; + } + this.daTickInterval = this._daTickInterval; + // this._ticks = this.__ticks; + }; + + $.jqplot.DateAxisRenderer.prototype.createTicks = function(plot) { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var iv = this._intervalStats; + var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; + var interval; + var min, max; + var pos1, pos2; + var tt, i; + var threshold = 30; + var insetMult = 1; + var daTickInterval = null; + + // if user specified a tick interval, convert to usable. + if (this.tickInterval != null) + { + // if interval is a number or can be converted to one, use it. + // Assume it is in SECONDS!!! + if (Number(this.tickInterval)) { + daTickInterval = [Number(this.tickInterval), 'seconds']; + } + // else, parse out something we can build from. + else if (typeof this.tickInterval == "string") { + var parts = this.tickInterval.split(' '); + if (parts.length == 1) { + daTickInterval = [1, parts[0]]; + } + else if (parts.length == 2) { + daTickInterval = [parts[0], parts[1]]; + } + } + } + + var tickInterval = this.tickInterval; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + min = new $.jsDate((this.min != null) ? this.min : db.min).getTime(); + max = new $.jsDate((this.max != null) ? this.max : db.max).getTime(); + + // see if we're zooming. if we are, don't use the min and max we're given, + // but compute some nice ones. They will be reset later. + + var cursor = plot.plugins.cursor; + + if (cursor && cursor._zoom && cursor._zoom.zooming) { + this.min = null; + this.max = null; + } + + var range = max - min; + + if (this.tickOptions == null || !this.tickOptions.formatString) { + this._overrideFormatString = true; + } + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i<userTicks.length; i++){ + var ut = userTicks[i]; + var t = new this.tickRenderer(this.tickOptions); + if (ut.constructor == Array) { + t.value = new $.jsDate(ut[0]).getTime(); + t.label = ut[1]; + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(t.value, this.name); + this._ticks.push(t); + } + + else { + t.value = new $.jsDate(ut).getTime(); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(t.value, this.name); + this._ticks.push(t); + } + } + this.numberTicks = userTicks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this.numberTicks-1].value; + this.daTickInterval = [(this.max - this.min) / (this.numberTicks - 1)/1000, 'seconds']; + } + + //////// + // We don't have any ticks yet, let's make some! + //////// + + // special case when there is only one point, make three tick marks to center the point + else if (this.min == null && this.max == null && db.min == db.max) + { + var onePointOpts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null}); + var delta = 300000; + this.min = db.min - delta; + this.max = db.max + delta; + this.numberTicks = 3; + + for(var i=this.min;i<=this.max;i+= delta) + { + onePointOpts.value = i; + + var t = new this.tickRenderer(onePointOpts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + + t.showLabel = false; + t.showMark = false; + + this._ticks.push(t); + } + + if(this.showTicks) { + this._ticks[1].showLabel = true; + } + if(this.showTickMarks) { + this._ticks[1].showTickMarks = true; + } + } + // if user specified min and max are null, we set those to make best ticks. + else if (this.min == null && this.max == null) { + + var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null}); + + // want to find a nice interval + var nttarget, + titarget; + + // if no tickInterval or numberTicks options specified, make a good guess. + if (!this.tickInterval && !this.numberTicks) { + var tdim = Math.max(dim, threshold+1); + // how many ticks to put on the axis? + // date labels tend to be long. If ticks not rotated, + // don't use too many and have a high spacing factor. + // If we are rotating ticks, use a lower factor. + var spacingFactor = 115; + if (this.tickRenderer === $.jqplot.CanvasAxisTickRenderer && this.tickOptions.angle) { + spacingFactor = 115 - 40 * Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI)); + } + + nttarget = Math.ceil((tdim-threshold)/spacingFactor + 1); + titarget = (max - min) / (nttarget - 1); + } + + // If tickInterval is specified, we'll try to honor it. + // Not guaranteed to get this interval, but we'll get as close as + // we can. + // tickInterval will be used before numberTicks, that is if + // both are specified, numberTicks will be ignored. + else if (this.tickInterval) { + titarget = new $.jsDate(0).add(daTickInterval[0], daTickInterval[1]).getTime(); + } + + // if numberTicks specified, try to honor it. + // Not guaranteed, but will try to get close. + else if (this.numberTicks) { + nttarget = this.numberTicks; + titarget = (max - min) / (nttarget - 1); + } + + // If we can use an interval of 2 weeks or less, pick best one + if (titarget <= 19*day) { + var ret = bestDateInterval(min, max, titarget); + var tempti = ret[0]; + this._autoFormatString = ret[1]; + + min = new $.jsDate(min); + min = Math.floor((min.getTime() - min.getUtcOffset())/tempti) * tempti + min.getUtcOffset(); + + nttarget = Math.ceil((max - min) / tempti) + 1; + this.min = min; + this.max = min + (nttarget - 1) * tempti; + + // if max is less than max, add an interval + if (this.max < max) { + this.max += tempti; + nttarget += 1; + } + this.tickInterval = tempti; + this.numberTicks = nttarget; + + for (var i=0; i<nttarget; i++) { + opts.value = this.min + i * tempti; + t = new this.tickRenderer(opts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + this._ticks.push(t); + } + + insetMult = this.tickInterval; + } + + // should we use a monthly interval? + else if (titarget <= 9 * month) { + + this._autoFormatString = '%v'; + + // how many months in an interval? + var intv = Math.round(titarget/month); + if (intv < 1) { + intv = 1; + } + else if (intv > 6) { + intv = 6; + } + + // figure out the starting month and ending month. + var mstart = new $.jsDate(min).setDate(1).setHours(0,0,0,0); + + // See if max ends exactly on a month + var tempmend = new $.jsDate(max); + var mend = new $.jsDate(max).setDate(1).setHours(0,0,0,0); + + if (tempmend.getTime() !== mend.getTime()) { + mend = mend.add(1, 'month'); + } + + var nmonths = mend.diff(mstart, 'month'); + + nttarget = Math.ceil(nmonths/intv) + 1; + + this.min = mstart.getTime(); + this.max = mstart.clone().add((nttarget - 1) * intv, 'month').getTime(); + this.numberTicks = nttarget; + + for (var i=0; i<nttarget; i++) { + if (i === 0) { + opts.value = mstart.getTime(); + } + else { + opts.value = mstart.add(intv, 'month').getTime(); + } + t = new this.tickRenderer(opts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + this._ticks.push(t); + } + + insetMult = intv * month; + } + + // use yearly intervals + else { + + this._autoFormatString = '%v'; + + // how many years in an interval? + var intv = Math.round(titarget/year); + if (intv < 1) { + intv = 1; + } + + // figure out the starting and ending years. + var mstart = new $.jsDate(min).setMonth(0, 1).setHours(0,0,0,0); + var mend = new $.jsDate(max).add(1, 'year').setMonth(0, 1).setHours(0,0,0,0); + + var nyears = mend.diff(mstart, 'year'); + + nttarget = Math.ceil(nyears/intv) + 1; + + this.min = mstart.getTime(); + this.max = mstart.clone().add((nttarget - 1) * intv, 'year').getTime(); + this.numberTicks = nttarget; + + for (var i=0; i<nttarget; i++) { + if (i === 0) { + opts.value = mstart.getTime(); + } + else { + opts.value = mstart.add(intv, 'year').getTime(); + } + t = new this.tickRenderer(opts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + this._ticks.push(t); + } + + insetMult = intv * year; + } + } + + //////// + // Some option(s) specified, work around that. + //////// + + else { + if (name == 'xaxis' || name == 'x2axis') { + dim = this._plotDimensions.width; + } + else { + dim = this._plotDimensions.height; + } + + // if min, max and number of ticks specified, user can't specify interval. + if (this.min != null && this.max != null && this.numberTicks != null) { + this.tickInterval = null; + } + + if (this.tickInterval != null && daTickInterval != null) { + this.daTickInterval = daTickInterval; + } + + // if min and max are same, space them out a bit + if (min == max) { + var adj = 24*60*60*500; // 1/2 day + min -= adj; + max += adj; + } + + range = max - min; + + var optNumTicks = 2 + parseInt(Math.max(0, dim-100)/100, 10); + + + var rmin, rmax; + + rmin = (this.min != null) ? new $.jsDate(this.min).getTime() : min - range/2*(this.padMin - 1); + rmax = (this.max != null) ? new $.jsDate(this.max).getTime() : max + range/2*(this.padMax - 1); + this.min = rmin; + this.max = rmax; + range = this.max - this.min; + + if (this.numberTicks == null){ + // if tickInterval is specified by user, we will ignore computed maximum. + // max will be equal or greater to fit even # of ticks. + if (this.daTickInterval != null) { + var nc = new $.jsDate(this.max).diff(this.min, this.daTickInterval[1], true); + this.numberTicks = Math.ceil(nc/this.daTickInterval[0]) +1; + // this.max = new $.jsDate(this.min).add(this.numberTicks-1, this.daTickInterval[1]).getTime(); + this.max = new $.jsDate(this.min).add((this.numberTicks-1) * this.daTickInterval[0], this.daTickInterval[1]).getTime(); + } + else if (dim > 200) { + this.numberTicks = parseInt(3+(dim-200)/100, 10); + } + else { + this.numberTicks = 2; + } + } + + insetMult = range / (this.numberTicks-1)/1000; + + if (this.daTickInterval == null) { + this.daTickInterval = [insetMult, 'seconds']; + } + + + for (var i=0; i<this.numberTicks; i++){ + var min = new $.jsDate(this.min); + tt = min.add(i*this.daTickInterval[0], this.daTickInterval[1]).getTime(); + var t = new this.tickRenderer(this.tickOptions); + // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(tt, this.name); + this._ticks.push(t); + } + } + + if (this.tickInset) { + this.min = this.min - this.tickInset * insetMult; + this.max = this.max + this.tickInset * insetMult; + } + + if (this._daTickInterval == null) { + this._daTickInterval = this.daTickInterval; + } + + ticks = null; + }; + +})(jQuery); + diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.min.js new file mode 100644 index 0000000..a295489 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dateAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(h){h.jqplot.DateAxisRenderer=function(){h.jqplot.LinearAxisRenderer.call(this);this.date=new h.jsDate()};var c=1000;var e=60*c;var f=60*e;var l=24*f;var b=7*l;var j=30.4368499*l;var k=365.242199*l;var g=[31,28,31,30,31,30,31,30,31,30,31,30];var i=["%M:%S.%#N","%M:%S.%#N","%M:%S.%#N","%M:%S","%M:%S","%M:%S","%M:%S","%H:%M:%S","%H:%M:%S","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%H:%M","%a %H:%M","%a %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%b %e %H:%M","%v","%v","%v","%v","%v","%v","%v"];var m=[0.1*c,0.2*c,0.5*c,c,2*c,5*c,10*c,15*c,30*c,e,2*e,5*e,10*e,15*e,30*e,f,2*f,4*f,6*f,8*f,12*f,l,2*l,3*l,4*l,5*l,b,2*b];var d=[];function a(p,s,t){var o=Number.MAX_VALUE;var u,r,v;for(var q=0,n=m.length;q<n;q++){u=Math.abs(t-m[q]);if(u<o){o=u;r=m[q];v=i[q]}}return[r,v]}h.jqplot.DateAxisRenderer.prototype=new h.jqplot.LinearAxisRenderer();h.jqplot.DateAxisRenderer.prototype.constructor=h.jqplot.DateAxisRenderer;h.jqplot.DateTickFormatter=function(n,o){if(!n){n="%Y/%m/%d"}return h.jsDate.strftime(o,n)};h.jqplot.DateAxisRenderer.prototype.init=function(E){this.tickOptions.formatter=h.jqplot.DateTickFormatter;this.tickInset=0;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.daTickInterval=null;this._daTickInterval=null;h.extend(true,this,E);var C=this._dataBounds,u,x,D,y,A,z,o;for(var t=0;t<this._series.length;t++){u={intervals:[],frequencies:{},sortedIntervals:[],min:null,max:null,mean:null};x=0;D=this._series[t];y=D.data;A=D._plotData;z=D._stackData;o=0;for(var r=0;r<y.length;r++){if(this.name=="xaxis"||this.name=="x2axis"){y[r][0]=new h.jsDate(y[r][0]).getTime();A[r][0]=new h.jsDate(y[r][0]).getTime();z[r][0]=new h.jsDate(y[r][0]).getTime();if((y[r][0]!=null&&y[r][0]<C.min)||C.min==null){C.min=y[r][0]}if((y[r][0]!=null&&y[r][0]>C.max)||C.max==null){C.max=y[r][0]}if(r>0){o=Math.abs(y[r][0]-y[r-1][0]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}x+=o}else{y[r][1]=new h.jsDate(y[r][1]).getTime();A[r][1]=new h.jsDate(y[r][1]).getTime();z[r][1]=new h.jsDate(y[r][1]).getTime();if((y[r][1]!=null&&y[r][1]<C.min)||C.min==null){C.min=y[r][1]}if((y[r][1]!=null&&y[r][1]>C.max)||C.max==null){C.max=y[r][1]}if(r>0){o=Math.abs(y[r][1]-y[r-1][1]);u.intervals.push(o);if(u.frequencies.hasOwnProperty(o)){u.frequencies[o]+=1}else{u.frequencies[o]=1}}}x+=o}if(D.renderer.bands){if(D.renderer.bands.hiData.length){var w=D.renderer.bands.hiData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]>C.max)||C.max==null){C.max=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]>C.max)||C.max==null){C.max=w[r][1]}}}}if(D.renderer.bands.lowData.length){var w=D.renderer.bands.lowData;for(var r=0,q=w.length;r<q;r++){if(this.name==="xaxis"||this.name==="x2axis"){w[r][0]=new h.jsDate(w[r][0]).getTime();if((w[r][0]!=null&&w[r][0]<C.min)||C.min==null){C.min=w[r][0]}}else{w[r][1]=new h.jsDate(w[r][1]).getTime();if((w[r][1]!=null&&w[r][1]<C.min)||C.min==null){C.min=w[r][1]}}}}}var B=0,v=0;for(var p in u.frequencies){u.sortedIntervals.push({interval:p,frequency:u.frequencies[p]})}u.sortedIntervals.sort(function(s,n){return n.frequency-s.frequency});u.min=h.jqplot.arrayMin(u.intervals);u.max=h.jqplot.arrayMax(u.intervals);u.mean=x/y.length;this._intervalStats.push(u);u=x=D=y=A=z=null}C=null};h.jqplot.DateAxisRenderer.prototype.reset=function(){this.min=this._options.min;this.max=this._options.max;this.tickInterval=this._options.tickInterval;this.numberTicks=this._options.numberTicks;this._autoFormatString="";if(this._overrideFormatString&&this.tickOptions&&this.tickOptions.formatString){this.tickOptions.formatString=""}this.daTickInterval=this._daTickInterval};h.jqplot.DateAxisRenderer.prototype.createTicks=function(p){var X=this._ticks;var L=this.ticks;var F=this.name;var H=this._dataBounds;var M=this._intervalStats;var n=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var w;var ae,J;var y,x;var ad,aa;var s=30;var O=1;var U=null;if(this.tickInterval!=null){if(Number(this.tickInterval)){U=[Number(this.tickInterval),"seconds"]}else{if(typeof this.tickInterval=="string"){var ac=this.tickInterval.split(" ");if(ac.length==1){U=[1,ac[0]]}else{if(ac.length==2){U=[ac[0],ac[1]]}}}}}var v=this.tickInterval;ae=new h.jsDate((this.min!=null)?this.min:H.min).getTime();J=new h.jsDate((this.max!=null)?this.max:H.max).getTime();var A=p.plugins.cursor;if(A&&A._zoom&&A._zoom.zooming){this.min=null;this.max=null}var B=J-ae;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}if(L.length){for(aa=0;aa<L.length;aa++){var P=L[aa];var Y=new this.tickRenderer(this.tickOptions);if(P.constructor==Array){Y.value=new h.jsDate(P[0]).getTime();Y.label=P[1];if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}else{Y.value=new h.jsDate(P).getTime();if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(Y.value,this.name);this._ticks.push(Y)}}this.numberTicks=L.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.daTickInterval=[(this.max-this.min)/(this.numberTicks-1)/1000,"seconds"]}else{if(this.min==null&&this.max==null&&H.min==H.max){var E=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var T=300000;this.min=H.min-T;this.max=H.max+T;this.numberTicks=3;for(var aa=this.min;aa<=this.max;aa+=T){E.value=aa;var Y=new this.tickRenderer(E);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}Y.showLabel=false;Y.showMark=false;this._ticks.push(Y)}if(this.showTicks){this._ticks[1].showLabel=true}if(this.showTickMarks){this._ticks[1].showTickMarks=true}}else{if(this.min==null&&this.max==null){var N=h.extend(true,{},this.tickOptions,{name:this.name,value:null});var ab,I;if(!this.tickInterval&&!this.numberTicks){var R=Math.max(n,s+1);var Z=115;if(this.tickRenderer===h.jqplot.CanvasAxisTickRenderer&&this.tickOptions.angle){Z=115-40*Math.abs(Math.sin(this.tickOptions.angle/180*Math.PI))}ab=Math.ceil((R-s)/Z+1);I=(J-ae)/(ab-1)}else{if(this.tickInterval){I=new h.jsDate(0).add(U[0],U[1]).getTime()}else{if(this.numberTicks){ab=this.numberTicks;I=(J-ae)/(ab-1)}}}if(I<=19*l){var Q=a(ae,J,I);var r=Q[0];this._autoFormatString=Q[1];ae=new h.jsDate(ae);ae=Math.floor((ae.getTime()-ae.getUtcOffset())/r)*r+ae.getUtcOffset();ab=Math.ceil((J-ae)/r)+1;this.min=ae;this.max=ae+(ab-1)*r;if(this.max<J){this.max+=r;ab+=1}this.tickInterval=r;this.numberTicks=ab;for(var aa=0;aa<ab;aa++){N.value=this.min+aa*r;Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=this.tickInterval}else{if(I<=9*j){this._autoFormatString="%v";var D=Math.round(I/j);if(D<1){D=1}else{if(D>6){D=6}}var V=new h.jsDate(ae).setDate(1).setHours(0,0,0,0);var q=new h.jsDate(J);var z=new h.jsDate(J).setDate(1).setHours(0,0,0,0);if(q.getTime()!==z.getTime()){z=z.add(1,"month")}var S=z.diff(V,"month");ab=Math.ceil(S/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"month").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"month").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*j}else{this._autoFormatString="%v";var D=Math.round(I/k);if(D<1){D=1}var V=new h.jsDate(ae).setMonth(0,1).setHours(0,0,0,0);var z=new h.jsDate(J).add(1,"year").setMonth(0,1).setHours(0,0,0,0);var K=z.diff(V,"year");ab=Math.ceil(K/D)+1;this.min=V.getTime();this.max=V.clone().add((ab-1)*D,"year").getTime();this.numberTicks=ab;for(var aa=0;aa<ab;aa++){if(aa===0){N.value=V.getTime()}else{N.value=V.add(D,"year").getTime()}Y=new this.tickRenderer(N);if(this._overrideFormatString&&this._autoFormatString!=""){Y.formatString=this._autoFormatString}if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}this._ticks.push(Y)}O=D*k}}}else{if(F=="xaxis"||F=="x2axis"){n=this._plotDimensions.width}else{n=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}if(this.tickInterval!=null&&U!=null){this.daTickInterval=U}if(ae==J){var o=24*60*60*500;ae-=o;J+=o}B=J-ae;var G=2+parseInt(Math.max(0,n-100)/100,10);var W,C;W=(this.min!=null)?new h.jsDate(this.min).getTime():ae-B/2*(this.padMin-1);C=(this.max!=null)?new h.jsDate(this.max).getTime():J+B/2*(this.padMax-1);this.min=W;this.max=C;B=this.max-this.min;if(this.numberTicks==null){if(this.daTickInterval!=null){var u=new h.jsDate(this.max).diff(this.min,this.daTickInterval[1],true);this.numberTicks=Math.ceil(u/this.daTickInterval[0])+1;this.max=new h.jsDate(this.min).add((this.numberTicks-1)*this.daTickInterval[0],this.daTickInterval[1]).getTime()}else{if(n>200){this.numberTicks=parseInt(3+(n-200)/100,10)}else{this.numberTicks=2}}}O=B/(this.numberTicks-1)/1000;if(this.daTickInterval==null){this.daTickInterval=[O,"seconds"]}for(var aa=0;aa<this.numberTicks;aa++){var ae=new h.jsDate(this.min);ad=ae.add(aa*this.daTickInterval[0],this.daTickInterval[1]).getTime();var Y=new this.tickRenderer(this.tickOptions);if(!this.showTicks){Y.showLabel=false;Y.showMark=false}else{if(!this.showTickMarks){Y.showMark=false}}Y.setTick(ad,this.name);this._ticks.push(Y)}}}}if(this.tickInset){this.min=this.min-this.tickInset*O;this.max=this.max+this.tickInset*O}if(this._daTickInterval==null){this._daTickInterval=this.daTickInterval}X=null}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.js new file mode 100644 index 0000000..9684812 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.js @@ -0,0 +1,805 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.DonutRenderer + * Plugin renderer to draw a donut chart. + * x values, if present, will be used as slice labels. + * y values give slice size. + * + * To use this renderer, you need to include the + * donut renderer plugin, for example: + * + * > <script type="text/javascript" src="plugins/jqplot.donutRenderer.js"></script> + * + * Properties described here are passed into the $.jqplot function + * as options on the series renderer. For example: + * + * > plot2 = $.jqplot('chart2', [s1, s2], { + * > seriesDefaults: { + * > renderer:$.jqplot.DonutRenderer, + * > rendererOptions:{ + * > sliceMargin: 2, + * > innerDiameter: 110, + * > startAngle: -90 + * > } + * > } + * > }); + * + * A donut plot will trigger events on the plot target + * according to user interaction. All events return the event object, + * the series index, the point (slice) index, and the point data for + * the appropriate slice. + * + * 'jqplotDataMouseOver' - triggered when user mouseing over a slice. + * 'jqplotDataHighlight' - triggered the first time user mouses over a slice, + * if highlighting is enabled. + * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of + * a highlighted slice. + * 'jqplotDataClick' - triggered when the user clicks on a slice. + * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if + * the "captureRightClick" option is set to true on the plot. + */ + $.jqplot.DonutRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.DonutRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.DonutRenderer.prototype.constructor = $.jqplot.DonutRenderer; + + // called with scope of a series + $.jqplot.DonutRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + // prop: diameter + // Outer diameter of the donut, auto computed by default + this.diameter = null; + // prop: innerDiameter + // Inner diameter of the donut, auto calculated by default. + // If specified will override thickness value. + this.innerDiameter = null; + // prop: thickness + // thickness of the donut, auto computed by default + // Overridden by if innerDiameter is specified. + this.thickness = null; + // prop: padding + // padding between the donut and plot edges, legend, etc. + this.padding = 20; + // prop: sliceMargin + // angular spacing between donut slices in degrees. + this.sliceMargin = 0; + // prop: ringMargin + // pixel distance between rings, or multiple series in a donut plot. + // null will compute ringMargin based on sliceMargin. + this.ringMargin = null; + // prop: fill + // true or false, whether to fil the slices. + this.fill = true; + // prop: shadowOffset + // offset of the shadow from the slice and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.07; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: highlightMouseOver + // True to highlight slice when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a slice. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a slice. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // an array of colors to use when highlighting a slice. + this.highlightColors = []; + // prop: dataLabels + // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. + // Defaults to percentage of each pie slice. + this.dataLabels = 'percent'; + // prop: showDataLabels + // true to show data labels on slices. + this.showDataLabels = false; + // prop: dataLabelFormatString + // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. + this.dataLabelFormatString = null; + // prop: dataLabelThreshold + // Threshhold in percentage (0 - 100) of pie area, below which no label will be displayed. + // This applies to all label types, not just to percentage labels. + this.dataLabelThreshold = 3; + // prop: dataLabelPositionFactor + // A Multiplier (0-1) of the pie radius which controls position of label on slice. + // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie. + this.dataLabelPositionFactor = 0.4; + // prop: dataLabelNudge + // Number of pixels to slide the label away from (+) or toward (-) the center of the pie. + this.dataLabelNudge = 0; + // prop: startAngle + // Angle to start drawing donut in degrees. + // According to orientation of canvas coordinate system: + // 0 = on the positive x axis + // -90 = on the positive y axis. + // 90 = on the negaive y axis. + // 180 or - 180 = on the negative x axis. + this.startAngle = 0; + this.tickRenderer = $.jqplot.DonutTickRenderer; + // Used as check for conditions where donut shouldn't be drawn. + this._drawData = true; + this._type = 'donut'; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + $.extend(true, this, options); + if (this.diameter != null) { + this.diameter = this.diameter - this.sliceMargin; + } + this._diameter = null; + this._innerDiameter = null; + this._radius = null; + this._innerRadius = null; + this._thickness = null; + // references to the previous series in the plot to properly calculate diameters + // and thicknesses of nested rings. + this._previousSeries = []; + this._numberSeries = 1; + // array of [start,end] angles arrays, one for each slice. In radians. + this._sliceAngles = []; + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + + // set highlight colors if none provided + if (this.highlightColors.length == 0) { + for (var i=0; i<this.seriesColors.length; i++){ + var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); + } + } + + plot.postParseOptionsHooks.addOnce(postParseOptions); + plot.postInitHooks.addOnce(postInit); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + plot.postDrawHooks.addOnce(postPlotDraw); + + + }; + + $.jqplot.DonutRenderer.prototype.setGridData = function(plot) { + // set gridData property. This will hold angle in radians of each data point. + var stack = []; + var td = []; + var sa = this.startAngle/180*Math.PI; + var tot = 0; + // don't know if we have any valid data yet, so set plot to not draw. + this._drawData = false; + for (var i=0; i<this.data.length; i++){ + if (this.data[i][1] != 0) { + // we have data, O.K. to draw. + this._drawData = true; + } + stack.push(this.data[i][1]); + td.push([this.data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + tot += this.data[i][1]; + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + td[i][2] = this.data[i][1]/tot; + } + this.gridData = td; + }; + + $.jqplot.DonutRenderer.prototype.makeGridData = function(data, plot) { + var stack = []; + var td = []; + var tot = 0; + var sa = this.startAngle/180*Math.PI; + // don't know if we have any valid data yet, so set plot to not draw. + this._drawData = false; + for (var i=0; i<data.length; i++){ + if (this.data[i][1] != 0) { + // we have data, O.K. to draw. + this._drawData = true; + } + stack.push(data[i][1]); + td.push([data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + tot += data[i][1]; + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + td[i][2] = data[i][1]/tot; + } + return td; + }; + + $.jqplot.DonutRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) { + var r = this._diameter / 2; + var ri = r - this._thickness; + var fill = this.fill; + // var lineWidth = this.lineWidth; + ctx.save(); + ctx.translate(this._center[0], this._center[1]); + // ctx.translate(this.sliceMargin*Math.cos((ang1+ang2)/2), this.sliceMargin*Math.sin((ang1+ang2)/2)); + + if (isShadow) { + for (var i=0; i<this.shadowDepth; i++) { + ctx.save(); + ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); + doDraw(); + } + } + + else { + doDraw(); + } + + function doDraw () { + // Fix for IE and Chrome that can't seem to draw circles correctly. + // ang2 should always be <= 2 pi since that is the way the data is converted. + if (ang2 > 6.282 + this.startAngle) { + ang2 = 6.282 + this.startAngle; + if (ang1 > ang2) { + ang1 = 6.281 + this.startAngle; + } + } + // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids + // ugly line on unfilled donuts. + if (ang1 >= ang2) { + return; + } + ctx.beginPath(); + ctx.fillStyle = color; + ctx.strokeStyle = color; + // ctx.lineWidth = lineWidth; + ctx.arc(0, 0, r, ang1, ang2, false); + ctx.lineTo(ri*Math.cos(ang2), ri*Math.sin(ang2)); + ctx.arc(0,0, ri, ang2, ang1, true); + ctx.closePath(); + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + } + + if (isShadow) { + for (var i=0; i<this.shadowDepth; i++) { + ctx.restore(); + } + } + + ctx.restore(); + }; + + // called with scope of series + $.jqplot.DonutRenderer.prototype.draw = function (ctx, gd, options, plot) { + var i; + var opts = (options != undefined) ? options : {}; + // offset and direction of offset due to legend placement + var offx = 0; + var offy = 0; + var trans = 1; + // var colorGenerator = new this.colorGenerator(this.seriesColors); + if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { + var li = options.legendInfo; + switch (li.location) { + case 'nw': + offx = li.width + li.xoffset; + break; + case 'w': + offx = li.width + li.xoffset; + break; + case 'sw': + offx = li.width + li.xoffset; + break; + case 'ne': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'e': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'se': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'n': + offy = li.height + li.yoffset; + break; + case 's': + offy = li.height + li.yoffset; + trans = -1; + break; + default: + break; + } + } + + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var cw = ctx.canvas.width; + var ch = ctx.canvas.height; + var w = cw - offx - 2 * this.padding; + var h = ch - offy - 2 * this.padding; + var mindim = Math.min(w,h); + var d = mindim; + var ringmargin = (this.ringMargin == null) ? this.sliceMargin * 2.0 : this.ringMargin; + + for (var i=0; i<this._previousSeries.length; i++) { + d -= 2.0 * this._previousSeries[i]._thickness + 2.0 * ringmargin; + } + this._diameter = this.diameter || d; + if (this.innerDiameter != null) { + var od = (this._numberSeries > 1 && this.index > 0) ? this._previousSeries[0]._diameter : this._diameter; + this._thickness = this.thickness || (od - this.innerDiameter - 2.0*ringmargin*this._numberSeries) / this._numberSeries/2.0; + } + else { + this._thickness = this.thickness || mindim / 2 / (this._numberSeries + 1) * 0.85; + } + + var r = this._radius = this._diameter/2; + this._innerRadius = this._radius - this._thickness; + var sa = this.startAngle / 180 * Math.PI; + this._center = [(cw - trans * offx)/2 + trans * offx, (ch - trans*offy)/2 + trans * offy]; + + if (this.shadow) { + var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; + for (var i=0; i<gd.length; i++) { + var ang1 = (i == 0) ? sa : gd[i-1][1] + sa; + // Adjust ang1 and ang2 for sliceMargin + ang1 += this.sliceMargin/180*Math.PI; + this.renderer.drawSlice.call (this, ctx, ang1, gd[i][1]+sa, shadowColor, true); + } + + } + for (var i=0; i<gd.length; i++) { + var ang1 = (i == 0) ? sa : gd[i-1][1] + sa; + // Adjust ang1 and ang2 for sliceMargin + ang1 += this.sliceMargin/180*Math.PI; + var ang2 = gd[i][1] + sa; + this._sliceAngles.push([ang1, ang2]); + this.renderer.drawSlice.call (this, ctx, ang1, ang2, this.seriesColors[i], false); + + if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) { + var fstr, avgang = (ang1+ang2)/2, label; + + if (this.dataLabels == 'label') { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, gd[i][0]); + } + else if (this.dataLabels == 'value') { + fstr = this.dataLabelFormatString || '%d'; + label = $.jqplot.sprintf(fstr, this.data[i][1]); + } + else if (this.dataLabels == 'percent') { + fstr = this.dataLabelFormatString || '%d%%'; + label = $.jqplot.sprintf(fstr, gd[i][2]*100); + } + else if (this.dataLabels.constructor == Array) { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, this.dataLabels[i]); + } + + var fact = this._innerRadius + this._thickness * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; + + var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left; + var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top; + + var labelelem = $('<span class="jqplot-donut-series jqplot-data-label" style="position:absolute;">' + label + '</span>').insertBefore(plot.eventCanvas._elem); + x -= labelelem.width()/2; + y -= labelelem.height()/2; + x = Math.round(x); + y = Math.round(y); + labelelem.css({left: x, top: y}); + } + } + + }; + + $.jqplot.DonutAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.DonutAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.DonutAxisRenderer.prototype.constructor = $.jqplot.DonutAxisRenderer; + + + // There are no traditional axes on a donut chart. We just need to provide + // dummy objects with properties so the plot will render. + // called with scope of axis object. + $.jqplot.DonutAxisRenderer.prototype.init = function(options){ + // + this.tickRenderer = $.jqplot.DonutTickRenderer; + $.extend(true, this, options); + // I don't think I'm going to need _dataBounds here. + // have to go Axis scaling in a way to fit chart onto plot area + // and provide u2p and p2u functionality for mouse cursor, etc. + // for convienence set _dataBounds to 0 and 100 and + // set min/max to 0 and 100. + this._dataBounds = {min:0, max:100}; + this.min = 0; + this.max = 100; + this.showTicks = false; + this.ticks = []; + this.showMark = false; + this.show = false; + }; + + + + + $.jqplot.DonutLegendRenderer = function(){ + $.jqplot.TableLegendRenderer.call(this); + }; + + $.jqplot.DonutLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.DonutLegendRenderer.prototype.constructor = $.jqplot.DonutLegendRenderer; + + /** + * Class: $.jqplot.DonutLegendRenderer + * Legend Renderer specific to donut plots. Set by default + * when user creates a donut plot. + */ + $.jqplot.DonutLegendRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: numberRows + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // prop: numberColumns + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + $.extend(true, this, options); + }; + + // called with context of legend + $.jqplot.DonutLegendRenderer.prototype.draw = function() { + var legend = this; + if (this.show) { + var series = this._series; + var ss = 'position:absolute;'; + ss += (this.background) ? 'background:'+this.background+';' : ''; + ss += (this.border) ? 'border:'+this.border+';' : ''; + ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; + ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; + ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; + ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; + ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; + ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; + this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); + // Donut charts legends don't go by number of series, but by number of data points + // in the series. Refactor things here for that. + + var pad = false, + reverse = false, + nr, nc; + var s = series[0]; + var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); + + if (s.show) { + var pd = s.data; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(pd.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(pd.length/this.numberColumns); + } + else { + nr = pd.length; + nc = 1; + } + + var i, j, tr, td1, td2, lt, rs, color; + var idx = 0; + + for (i=0; i<nr; i++) { + if (reverse){ + tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); + } + else{ + tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); + } + for (j=0; j<nc; j++) { + if (idx < pd.length){ + lt = this.labels[idx] || pd[idx][0].toString(); + color = colorGenerator.next(); + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+ + '</div></td>'); + td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + td2.prependTo(tr); + td1.prependTo(tr); + } + else { + td1.appendTo(tr); + td2.appendTo(tr); + } + pad = true; + } + idx++; + } + } + } + } + return this._elem; + }; + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + // only set these if there is a donut series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.DonutRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.DonutRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.DonutAxisRenderer; + options.legend.renderer = $.jqplot.DonutLegendRenderer; + options.legend.preDraw = true; + options.seriesDefaults.pointLabels = {show: false}; + } + } + + // called with scope of plot. + function postInit(target, data, options) { + // if multiple series, add a reference to the previous one so that + // donut rings can nest. + for (var i=1; i<this.series.length; i++) { + if (!this.series[i]._previousSeries.length){ + for (var j=0; j<i; j++) { + if (this.series[i].renderer.constructor == $.jqplot.DonutRenderer && this.series[j].renderer.constructor == $.jqplot.DonutRenderer) { + this.series[i]._previousSeries.push(this.series[j]); + } + } + } + } + for (i=0; i<this.series.length; i++) { + if (this.series[i].renderer.constructor == $.jqplot.DonutRenderer) { + this.series[i]._numberSeries = this.series.length; + // don't allow mouseover and mousedown at same time. + if (this.series[i].highlightMouseOver) { + this.series[i].highlightMouseDown = false; + } + } + } + } + + var postParseOptionsRun = false; + // called with scope of plot + function postParseOptions(options) { + for (var i=0; i<this.series.length; i++) { + this.series[i].seriesColors = this.seriesColors; + this.series[i].colorGenerator = $.jqplot.colorGenerator; + } + } + + function highlight (plot, sidx, pidx) { + var s = plot.series[sidx]; + var canvas = plot.plugins.donutRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.donutRenderer.highlightedSeriesIndex = sidx; + s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColors[pidx], false); + } + + function unhighlight (plot) { + var canvas = plot.plugins.donutRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.donutRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.donutRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.donutRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.donutRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var idx = plot.plugins.donutRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.donutRenderer && this.plugins.donutRenderer.highlightCanvas) { + this.plugins.donutRenderer.highlightCanvas.resetCanvas(); + this.plugins.donutRenderer.highlightCanvas = null; + } + + this.plugins.donutRenderer = {highlightedSeriesIndex:null}; + this.plugins.donutRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + // do we have any data labels? if so, put highlight canvas before those + // Fix for broken jquery :first selector with canvas (VML) elements. + var labels = $(this.targetId+' .jqplot-data-label'); + if (labels.length) { + $(labels[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this)); + } + // else put highlight canvas before event canvas. + else { + this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this)); + } + var hctx = this.plugins.donutRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + $.jqplot.preInitHooks.push(preInit); + + $.jqplot.DonutTickRenderer = function() { + $.jqplot.AxisTickRenderer.call(this); + }; + + $.jqplot.DonutTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); + $.jqplot.DonutTickRenderer.prototype.constructor = $.jqplot.DonutTickRenderer; + +})(jQuery); + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.min.js new file mode 100644 index 0000000..a0cb217 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.donutRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.DonutRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.DonutRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.DonutRenderer.prototype.constructor=e.jqplot.DonutRenderer;e.jqplot.DonutRenderer.prototype.init=function(p,t){this.diameter=null;this.innerDiameter=null;this.thickness=null;this.padding=20;this.sliceMargin=0;this.ringMargin=null;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.4;this.dataLabelNudge=0;this.startAngle=0;this.tickRenderer=e.jqplot.DonutTickRenderer;this._drawData=true;this._type="donut";if(p.highlightMouseDown&&p.highlightMouseOver==null){p.highlightMouseOver=false}e.extend(true,this,p);if(this.diameter!=null){this.diameter=this.diameter-this.sliceMargin}this._diameter=null;this._innerDiameter=null;this._radius=null;this._innerRadius=null;this._thickness=null;this._previousSeries=[];this._numberSeries=1;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var q=e.jqplot.getColorComponents(this.seriesColors[r]);var n=[q[0],q[1],q[2]];var s=n[0]+n[1]+n[2];for(var o=0;o<3;o++){n[o]=(s>570)?n[o]*0.8:n[o]+0.3*(255-n[o]);n[o]=parseInt(n[o],10)}this.highlightColors.push("rgb("+n[0]+","+n[1]+","+n[2]+")")}}t.postParseOptionsHooks.addOnce(l);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",b);t.eventListenerHooks.addOnce("jqplotMouseDown",a);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",m);t.postDrawHooks.addOnce(h)};e.jqplot.DonutRenderer.prototype.setGridData=function(s){var o=[];var t=[];var n=this.startAngle/180*Math.PI;var r=0;this._drawData=false;for(var q=0;q<this.data.length;q++){if(this.data[q][1]!=0){this._drawData=true}o.push(this.data[q][1]);t.push([this.data[q][0]]);if(q>0){o[q]+=o[q-1]}r+=this.data[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q<o.length;q++){t[q][1]=o[q]*p;t[q][2]=this.data[q][1]/r}this.gridData=t};e.jqplot.DonutRenderer.prototype.makeGridData=function(s,t){var o=[];var u=[];var r=0;var n=this.startAngle/180*Math.PI;this._drawData=false;for(var q=0;q<s.length;q++){if(this.data[q][1]!=0){this._drawData=true}o.push(s[q][1]);u.push([s[q][0]]);if(q>0){o[q]+=o[q-1]}r+=s[q][1]}var p=Math.PI*2/o[o.length-1];for(var q=0;q<o.length;q++){u[q][1]=o[q]*p;u[q][2]=s[q][1]/r}return u};e.jqplot.DonutRenderer.prototype.drawSlice=function(x,u,t,p,s){var n=this._diameter/2;var v=n-this._thickness;var w=this.fill;x.save();x.translate(this._center[0],this._center[1]);if(s){for(var q=0;q<this.shadowDepth;q++){x.save();x.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));o()}}else{o()}function o(){if(t>6.282+this.startAngle){t=6.282+this.startAngle;if(u>t){u=6.281+this.startAngle}}if(u>=t){return}x.beginPath();x.fillStyle=p;x.strokeStyle=p;x.arc(0,0,n,u,t,false);x.lineTo(v*Math.cos(t),v*Math.sin(t));x.arc(0,0,v,t,u,true);x.closePath();if(w){x.fill()}else{x.stroke()}}if(s){for(var q=0;q<this.shadowDepth;q++){x.restore()}}x.restore()};e.jqplot.DonutRenderer.prototype.draw=function(N,V,t,P){var Q;var J=(t!=undefined)?t:{};var q=0;var p=0;var u=1;if(t.legendInfo&&t.legendInfo.placement=="insideGrid"){var I=t.legendInfo;switch(I.location){case"nw":q=I.width+I.xoffset;break;case"w":q=I.width+I.xoffset;break;case"sw":q=I.width+I.xoffset;break;case"ne":q=I.width+I.xoffset;u=-1;break;case"e":q=I.width+I.xoffset;u=-1;break;case"se":q=I.width+I.xoffset;u=-1;break;case"n":p=I.height+I.yoffset;break;case"s":p=I.height+I.yoffset;u=-1;break;default:break}}var B=(J.shadow!=undefined)?J.shadow:this.shadow;var W=(J.showLine!=undefined)?J.showLine:this.showLine;var O=(J.fill!=undefined)?J.fill:this.fill;var s=N.canvas.width;var H=N.canvas.height;var G=s-q-2*this.padding;var R=H-p-2*this.padding;var v=Math.min(G,R);var T=v;var X=(this.ringMargin==null)?this.sliceMargin*2:this.ringMargin;for(var Q=0;Q<this._previousSeries.length;Q++){T-=2*this._previousSeries[Q]._thickness+2*X}this._diameter=this.diameter||T;if(this.innerDiameter!=null){var M=(this._numberSeries>1&&this.index>0)?this._previousSeries[0]._diameter:this._diameter;this._thickness=this.thickness||(M-this.innerDiameter-2*X*this._numberSeries)/this._numberSeries/2}else{this._thickness=this.thickness||v/2/(this._numberSeries+1)*0.85}var K=this._radius=this._diameter/2;this._innerRadius=this._radius-this._thickness;var o=this.startAngle/180*Math.PI;this._center=[(s-u*q)/2+u*q,(H-u*p)/2+u*p];if(this.shadow){var L="rgba(0,0,0,"+this.shadowAlpha+")";for(var Q=0;Q<V.length;Q++){var A=(Q==0)?o:V[Q-1][1]+o;A+=this.sliceMargin/180*Math.PI;this.renderer.drawSlice.call(this,N,A,V[Q][1]+o,L,true)}}for(var Q=0;Q<V.length;Q++){var A=(Q==0)?o:V[Q-1][1]+o;A+=this.sliceMargin/180*Math.PI;var z=V[Q][1]+o;this._sliceAngles.push([A,z]);this.renderer.drawSlice.call(this,N,A,z,this.seriesColors[Q],false);if(this.showDataLabels&&V[Q][2]*100>=this.dataLabelThreshold){var S,U=(A+z)/2,C;if(this.dataLabels=="label"){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,V[Q][0])}else{if(this.dataLabels=="value"){S=this.dataLabelFormatString||"%d";C=e.jqplot.sprintf(S,this.data[Q][1])}else{if(this.dataLabels=="percent"){S=this.dataLabelFormatString||"%d%%";C=e.jqplot.sprintf(S,V[Q][2]*100)}else{if(this.dataLabels.constructor==Array){S=this.dataLabelFormatString||"%s";C=e.jqplot.sprintf(S,this.dataLabels[Q])}}}}var n=this._innerRadius+this._thickness*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var F=this._center[0]+Math.cos(U)*n+this.canvas._offsets.left;var E=this._center[1]+Math.sin(U)*n+this.canvas._offsets.top;var D=e('<span class="jqplot-donut-series jqplot-data-label" style="position:absolute;">'+C+"</span>").insertBefore(P.eventCanvas._elem);F-=D.width()/2;E-=D.height()/2;F=Math.round(F);E=Math.round(E);D.css({left:F,top:E})}}};e.jqplot.DonutAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.DonutAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.DonutAxisRenderer.prototype.constructor=e.jqplot.DonutAxisRenderer;e.jqplot.DonutAxisRenderer.prototype.init=function(n){this.tickRenderer=e.jqplot.DonutTickRenderer;e.extend(true,this,n);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.DonutLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.DonutLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.DonutLegendRenderer.prototype.constructor=e.jqplot.DonutLegendRenderer;e.jqplot.DonutLegendRenderer.prototype.init=function(n){this.numberRows=null;this.numberColumns=null;e.extend(true,this,n)};e.jqplot.DonutLegendRenderer.prototype.draw=function(){var q=this;if(this.show){var y=this._series;var B="position:absolute;";B+=(this.background)?"background:"+this.background+";":"";B+=(this.border)?"border:"+this.border+";":"";B+=(this.fontSize)?"font-size:"+this.fontSize+";":"";B+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";B+=(this.textColor)?"color:"+this.textColor+";":"";B+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";B+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";B+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";B+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('<table class="jqplot-table-legend" style="'+B+'"></table>');var F=false,x=false,n,v;var z=y[0];var o=new e.jqplot.ColorGenerator(z.seriesColors);if(z.show){var G=z.data;if(this.numberRows){n=this.numberRows;if(!this.numberColumns){v=Math.ceil(G.length/n)}else{v=this.numberColumns}}else{if(this.numberColumns){v=this.numberColumns;n=Math.ceil(G.length/this.numberColumns)}else{n=G.length;v=1}}var E,D,p,t,r,u,w,C;var A=0;for(E=0;E<n;E++){if(x){p=e('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{p=e('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(D=0;D<v;D++){if(A<G.length){u=this.labels[A]||G[A][0].toString();C=o.next();if(!x){if(E>0){F=true}else{F=false}}else{if(E==n-1){F=false}else{F=true}}w=(F)?this.rowSpacing:"0";t=e('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+w+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+C+';"></div></div></td>');r=e('<td class="jqplot-table-legend" style="padding-top:'+w+';"></td>');if(this.escapeHtml){r.text(u)}else{r.html(u)}if(x){r.prependTo(p);t.prependTo(p)}else{t.appendTo(p);r.appendTo(p)}F=true}A++}}}}return this._elem};function c(r,q,o){o=o||{};o.axesDefaults=o.axesDefaults||{};o.legend=o.legend||{};o.seriesDefaults=o.seriesDefaults||{};var n=false;if(o.seriesDefaults.renderer==e.jqplot.DonutRenderer){n=true}else{if(o.series){for(var p=0;p<o.series.length;p++){if(o.series[p].renderer==e.jqplot.DonutRenderer){n=true}}}}if(n){o.axesDefaults.renderer=e.jqplot.DonutAxisRenderer;o.legend.renderer=e.jqplot.DonutLegendRenderer;o.legend.preDraw=true;o.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=1;p<this.series.length;p++){if(!this.series[p]._previousSeries.length){for(var n=0;n<p;n++){if(this.series[p].renderer.constructor==e.jqplot.DonutRenderer&&this.series[n].renderer.constructor==e.jqplot.DonutRenderer){this.series[p]._previousSeries.push(this.series[n])}}}}for(p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.DonutRenderer){this.series[p]._numberSeries=this.series.length;if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}var k=false;function l(n){for(var o=0;o<this.series.length;o++){this.series[o].seriesColors=this.seriesColors;this.series[o].colorGenerator=e.jqplot.colorGenerator}}function d(r,q,p){var o=r.series[q];var n=r.plugins.donutRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);o._highlightedPoint=p;r.plugins.donutRenderer.highlightedSeriesIndex=q;o.renderer.drawSlice.call(o,n._ctx,o._sliceAngles[p][0],o._sliceAngles[p][1],o.highlightColors[p],false)}function i(p){var n=p.plugins.donutRenderer.highlightCanvas;n._ctx.clearRect(0,0,n._ctx.canvas.width,n._ctx.canvas.height);for(var o=0;o<p.series.length;o++){p.series[o]._highlightedPoint=null}p.plugins.donutRenderer.highlightedSeriesIndex=null;p.target.trigger("jqplotDataUnhighlight")}function b(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataMouseOver");o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);if(s.series[p[0]].highlightMouseOver&&!(p[0]==s.plugins.donutRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=r.which;n.pageX=r.pageX;n.pageY=r.pageY;s.target.trigger(n,p);d(s,p[0],p[1])}}else{if(t==null){i(s)}}}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];if(r.series[o[0]].highlightMouseDown&&!(o[0]==r.plugins.donutRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var n=jQuery.Event("jqplotDataHighlight");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);d(r,o[0],o[1])}}else{if(s==null){i(r)}}}function j(p,o,s,r,q){var n=q.plugins.donutRenderer.highlightedSeriesIndex;if(n!=null&&q.series[n].highlightMouseDown){i(q)}}function f(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function m(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var n=s.plugins.donutRenderer.highlightedSeriesIndex;if(n!=null&&s.series[n].highlightMouseDown){i(s)}var o=jQuery.Event("jqplotDataRightClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function h(){if(this.plugins.donutRenderer&&this.plugins.donutRenderer.highlightCanvas){this.plugins.donutRenderer.highlightCanvas.resetCanvas();this.plugins.donutRenderer.highlightCanvas=null}this.plugins.donutRenderer={highlightedSeriesIndex:null};this.plugins.donutRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var o=e(this.targetId+" .jqplot-data-label");if(o.length){e(o[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-donutRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-donutRenderer-highlight-canvas",this._plotDimensions,this))}var n=this.plugins.donutRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(p){i(p.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.DonutTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.DonutTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.DonutTickRenderer.prototype.constructor=e.jqplot.DonutTickRenderer})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.js new file mode 100644 index 0000000..a9639bf --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.js @@ -0,0 +1,225 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + /** + * Class: $.jqplot.Dragable + * Plugin to make plotted points dragable by the user. + */ + $.jqplot.Dragable = function(options) { + // Group: Properties + this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false}); + this.shapeRenderer = new $.jqplot.ShapeRenderer(); + this.isDragging = false; + this.isOver = false; + this._ctx; + this._elem; + this._point; + this._gridData; + // prop: color + // CSS color spec for the dragged point (and adjacent line segment or bar). + this.color; + // prop: constrainTo + // Constrain dragging motion to an axis or to none. + // Allowable values are 'none', 'x', 'y' + this.constrainTo = 'none'; // 'x', 'y', or 'none'; + $.extend(true, this, options); + }; + + function DragCanvas() { + $.jqplot.GenericCanvas.call(this); + this.isDragging = false; + this.isOver = false; + this._neighbor; + this._cursors = []; + } + + DragCanvas.prototype = new $.jqplot.GenericCanvas(); + DragCanvas.prototype.constructor = DragCanvas; + + + // called within scope of series + $.jqplot.Dragable.parseOptions = function (defaults, opts) { + var options = opts || {}; + this.plugins.dragable = new $.jqplot.Dragable(options.dragable); + // since this function is called before series options are parsed, + // we can set this here and it will be overridden if needed. + this.isDragable = $.jqplot.config.enablePlugins; + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + // add a new DragCanvas object to the plot plugins to handle drawing on this new canvas. + $.jqplot.Dragable.postPlotDraw = function() { + // Memory Leaks patch + if (this.plugins.dragable && this.plugins.dragable.highlightCanvas) { + this.plugins.dragable.highlightCanvas.resetCanvas(); + this.plugins.dragable.highlightCanvas = null; + } + + this.plugins.dragable = {previousCursor:'auto', isOver:false}; + this.plugins.dragable.dragCanvas = new DragCanvas(); + + this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions, this)); + var dctx = this.plugins.dragable.dragCanvas.setContext(); + }; + + //$.jqplot.preInitHooks.push($.jqplot.Dragable.init); + $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Dragable.parseOptions); + $.jqplot.postDrawHooks.push($.jqplot.Dragable.postPlotDraw); + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + $.jqplot.eventListenerHooks.push(['jqplotMouseDown', handleDown]); + $.jqplot.eventListenerHooks.push(['jqplotMouseUp', handleUp]); + + + function initDragPoint(plot, neighbor) { + var s = plot.series[neighbor.seriesIndex]; + var drag = s.plugins.dragable; + + // first, init the mark renderer for the dragged point + var smr = s.markerRenderer; + var mr = drag.markerRenderer; + mr.style = smr.style; + mr.lineWidth = smr.lineWidth + 2.5; + mr.size = smr.size + 5; + if (!drag.color) { + var rgba = $.jqplot.getColorComponents(smr.color); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + drag.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + } + mr.color = drag.color; + mr.init(); + + var start = (neighbor.pointIndex > 0) ? neighbor.pointIndex - 1 : 0; + var end = neighbor.pointIndex+2; + drag._gridData = s.gridData.slice(start, end); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + var gd = s.gridData; + + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.gridData[0] : gridpos.x; + var y = (drag.constrainTo == 'x') ? dp.gridData[1] : gridpos.y; + + // compute data values for any listeners. + var xu = s._xaxis.series_p2u(x); + var yu = s._yaxis.series_p2u(y); + + // clear the canvas then redraw effect at new position. + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + + // adjust our gridData for the new mouse position + if (dp.pointIndex > 0) { + drag._gridData[1] = [x, y]; + } + else { + drag._gridData[0] = [x, y]; + } + plot.series[dp.seriesIndex].draw(dc._ctx, {gridData:drag._gridData, shadow:false, preventJqPlotSeriesDrawTrigger:true, color:drag.color, markerOptions:{color:drag.color, shadow:false}, trendline:{show:false}}); + plot.target.trigger('jqplotSeriesPointChange', [dp.seriesIndex, dp.pointIndex, [xu,yu], [x,y]]); + } + else if (neighbor != null) { + var series = plot.series[neighbor.seriesIndex]; + if (series.isDragable) { + var dc = plot.plugins.dragable.dragCanvas; + if (!dc.isOver) { + dc._cursors.push(ev.target.style.cursor); + ev.target.style.cursor = "pointer"; + } + dc.isOver = true; + } + } + else if (neighbor == null) { + var dc = plot.plugins.dragable.dragCanvas; + if (dc.isOver) { + ev.target.style.cursor = dc._cursors.pop(); + dc.isOver = false; + } + } + } + + function handleDown(ev, gridpos, datapos, neighbor, plot) { + var dc = plot.plugins.dragable.dragCanvas; + dc._cursors.push(ev.target.style.cursor); + if (neighbor != null) { + var s = plot.series[neighbor.seriesIndex]; + var drag = s.plugins.dragable; + if (s.isDragable && !dc.isDragging) { + dc._neighbor = neighbor; + dc.isDragging = true; + initDragPoint(plot, neighbor); + drag.markerRenderer.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], dc._ctx); + ev.target.style.cursor = "move"; + plot.target.trigger('jqplotDragStart', [neighbor.seriesIndex, neighbor.pointIndex, gridpos, datapos]); + } + } + // Just in case of a hickup, we'll clear the drag canvas and reset. + else { + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + } + } + + function handleUp(ev, gridpos, datapos, neighbor, plot) { + if (plot.plugins.dragable.dragCanvas.isDragging) { + var dc = plot.plugins.dragable.dragCanvas; + // clear the canvas + var ctx = dc._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + dc.isDragging = false; + // redraw the series canvas at the new point. + var dp = dc._neighbor; + var s = plot.series[dp.seriesIndex]; + var drag = s.plugins.dragable; + // compute the new grid position with any constraints. + var x = (drag.constrainTo == 'y') ? dp.data[0] : datapos[s.xaxis]; + var y = (drag.constrainTo == 'x') ? dp.data[1] : datapos[s.yaxis]; + // var x = datapos[s.xaxis]; + // var y = datapos[s.yaxis]; + s.data[dp.pointIndex][0] = x; + s.data[dp.pointIndex][1] = y; + plot.drawSeries({preventJqPlotSeriesDrawTrigger:true}, dp.seriesIndex); + dc._neighbor = null; + ev.target.style.cursor = dc._cursors.pop(); + plot.target.trigger('jqplotDragStop', [gridpos, datapos]); + } + } +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.min.js new file mode 100644 index 0000000..3f1b80a --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.dragable.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(d){d.jqplot.Dragable=function(g){this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.shapeRenderer=new d.jqplot.ShapeRenderer();this.isDragging=false;this.isOver=false;this._ctx;this._elem;this._point;this._gridData;this.color;this.constrainTo="none";d.extend(true,this,g)};function b(){d.jqplot.GenericCanvas.call(this);this.isDragging=false;this.isOver=false;this._neighbor;this._cursors=[]}b.prototype=new d.jqplot.GenericCanvas();b.prototype.constructor=b;d.jqplot.Dragable.parseOptions=function(i,h){var g=h||{};this.plugins.dragable=new d.jqplot.Dragable(g.dragable);this.isDragable=d.jqplot.config.enablePlugins};d.jqplot.Dragable.postPlotDraw=function(){if(this.plugins.dragable&&this.plugins.dragable.highlightCanvas){this.plugins.dragable.highlightCanvas.resetCanvas();this.plugins.dragable.highlightCanvas=null}this.plugins.dragable={previousCursor:"auto",isOver:false};this.plugins.dragable.dragCanvas=new b();this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding,"jqplot-dragable-canvas",this._plotDimensions,this));var g=this.plugins.dragable.dragCanvas.setContext()};d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Dragable.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Dragable.postPlotDraw);d.jqplot.eventListenerHooks.push(["jqplotMouseMove",e]);d.jqplot.eventListenerHooks.push(["jqplotMouseDown",c]);d.jqplot.eventListenerHooks.push(["jqplotMouseUp",a]);function f(n,p){var q=n.series[p.seriesIndex];var m=q.plugins.dragable;var h=q.markerRenderer;var i=m.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+2.5;i.size=h.size+5;if(!m.color){var l=d.jqplot.getColorComponents(h.color);var o=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);m.color="rgba("+o[0]+","+o[1]+","+o[2]+","+k+")"}i.color=m.color;i.init();var g=(p.pointIndex>0)?p.pointIndex-1:0;var j=p.pointIndex+2;m._gridData=q.gridData.slice(g,j)}function e(o,l,h,t,m){if(m.plugins.dragable.dragCanvas.isDragging){var u=m.plugins.dragable.dragCanvas;var i=u._neighbor;var w=m.series[i.seriesIndex];var k=w.plugins.dragable;var r=w.gridData;var p=(k.constrainTo=="y")?i.gridData[0]:l.x;var n=(k.constrainTo=="x")?i.gridData[1]:l.y;var g=w._xaxis.series_p2u(p);var q=w._yaxis.series_p2u(n);var v=u._ctx;v.clearRect(0,0,v.canvas.width,v.canvas.height);if(i.pointIndex>0){k._gridData[1]=[p,n]}else{k._gridData[0]=[p,n]}m.series[i.seriesIndex].draw(u._ctx,{gridData:k._gridData,shadow:false,preventJqPlotSeriesDrawTrigger:true,color:k.color,markerOptions:{color:k.color,shadow:false},trendline:{show:false}});m.target.trigger("jqplotSeriesPointChange",[i.seriesIndex,i.pointIndex,[g,q],[p,n]])}else{if(t!=null){var j=m.series[t.seriesIndex];if(j.isDragable){var u=m.plugins.dragable.dragCanvas;if(!u.isOver){u._cursors.push(o.target.style.cursor);o.target.style.cursor="pointer"}u.isOver=true}}else{if(t==null){var u=m.plugins.dragable.dragCanvas;if(u.isOver){o.target.style.cursor=u._cursors.pop();u.isOver=false}}}}}function c(k,i,g,l,j){var m=j.plugins.dragable.dragCanvas;m._cursors.push(k.target.style.cursor);if(l!=null){var o=j.series[l.seriesIndex];var h=o.plugins.dragable;if(o.isDragable&&!m.isDragging){m._neighbor=l;m.isDragging=true;f(j,l);h.markerRenderer.draw(o.gridData[l.pointIndex][0],o.gridData[l.pointIndex][1],m._ctx);k.target.style.cursor="move";j.target.trigger("jqplotDragStart",[l.seriesIndex,l.pointIndex,i,g])}}else{var n=m._ctx;n.clearRect(0,0,n.canvas.width,n.canvas.height);m.isDragging=false}}function a(m,j,g,o,k){if(k.plugins.dragable.dragCanvas.isDragging){var p=k.plugins.dragable.dragCanvas;var q=p._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);p.isDragging=false;var h=p._neighbor;var r=k.series[h.seriesIndex];var i=r.plugins.dragable;var n=(i.constrainTo=="y")?h.data[0]:g[r.xaxis];var l=(i.constrainTo=="x")?h.data[1]:g[r.yaxis];r.data[h.pointIndex][0]=n;r.data[h.pointIndex][1]=l;k.drawSeries({preventJqPlotSeriesDrawTrigger:true},h.seriesIndex);p._neighbor=null;m.target.style.cursor=p._cursors.pop();k.target.trigger("jqplotDragStop",[j,g])}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.js new file mode 100644 index 0000000..5a2cbc6 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.js @@ -0,0 +1,305 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + // class $.jqplot.EnhancedLegendRenderer + // Legend renderer which can specify the number of rows and/or columns in the legend. + $.jqplot.EnhancedLegendRenderer = function(){ + $.jqplot.TableLegendRenderer.call(this); + }; + + $.jqplot.EnhancedLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.EnhancedLegendRenderer.prototype.constructor = $.jqplot.EnhancedLegendRenderer; + + // called with scope of legend. + $.jqplot.EnhancedLegendRenderer.prototype.init = function(options) { + // prop: numberRows + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // prop: numberColumns + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + // prop: seriesToggle + // false to not enable series on/off toggling on the legend. + // true or a fadein/fadeout speed (number of milliseconds or 'fast', 'normal', 'slow') + // to enable show/hide of series on click of legend item. + this.seriesToggle = 'normal'; + // prop: seriesToggleReplot + // True to replot the chart after toggling series on/off. + // This will set the series show property to false. + // This allows for rescaling or other maniplation of chart. + // Set to an options object (e.g. {resetAxes: true}) for replot options. + this.seriesToggleReplot = false; + // prop: disableIEFading + // true to toggle series with a show/hide method only and not allow fading in/out. + // This is to overcome poor performance of fade in some versions of IE. + this.disableIEFading = true; + $.extend(true, this, options); + + if (this.seriesToggle) { + $.jqplot.postDrawHooks.push(postDraw); + } + }; + + // called with scope of legend + $.jqplot.EnhancedLegendRenderer.prototype.draw = function(offsets, plot) { + var legend = this; + if (this.show) { + var series = this._series; + var s; + var ss = 'position:absolute;'; + ss += (this.background) ? 'background:'+this.background+';' : ''; + ss += (this.border) ? 'border:'+this.border+';' : ''; + ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; + ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; + ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; + ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; + ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; + ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; + this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); + if (this.seriesToggle) { + this._elem.css('z-index', '3'); + } + + var pad = false, + reverse = false, + nr, nc; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(series.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(series.length/this.numberColumns); + } + else { + nr = series.length; + nc = 1; + } + + var i, j, tr, td1, td2, lt, rs, div, div0, div1; + var idx = 0; + // check to see if we need to reverse + for (i=series.length-1; i>=0; i--) { + if (nc == 1 && series[i]._stack || series[i].renderer.constructor == $.jqplot.BezierCurveRenderer){ + reverse = true; + } + } + + for (i=0; i<nr; i++) { + tr = $(document.createElement('tr')); + tr.addClass('jqplot-table-legend'); + if (reverse){ + tr.prependTo(this._elem); + } + else{ + tr.appendTo(this._elem); + } + for (j=0; j<nc; j++) { + if (idx < series.length && (series[idx].show || series[idx].showLabel)){ + s = series[idx]; + lt = this.labels[idx] || s.label.toString(); + if (lt) { + var color = s.color; + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + td1 = $(document.createElement('td')); + td1.addClass('jqplot-table-legend jqplot-table-legend-swatch'); + td1.css({textAlign: 'center', paddingTop: rs}); + + div0 = $(document.createElement('div')); + div0.addClass('jqplot-table-legend-swatch-outline'); + div1 = $(document.createElement('div')); + div1.addClass('jqplot-table-legend-swatch'); + div1.css({backgroundColor: color, borderColor: color}); + + td1.append(div0.append(div1)); + + td2 = $(document.createElement('td')); + td2.addClass('jqplot-table-legend jqplot-table-legend-label'); + td2.css('paddingTop', rs); + + // td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + // '<div><div class="jqplot-table-legend-swatch" style="background-color:'+color+';border-color:'+color+';"></div>'+ + // '</div></td>'); + // td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + if (this.showLabels) {td2.prependTo(tr);} + if (this.showSwatches) {td1.prependTo(tr);} + } + else { + if (this.showSwatches) {td1.appendTo(tr);} + if (this.showLabels) {td2.appendTo(tr);} + } + + if (this.seriesToggle) { + + // add an overlay for clicking series on/off + // div0 = $(document.createElement('div')); + // div0.addClass('jqplot-table-legend-overlay'); + // div0.css({position:'relative', left:0, top:0, height:'100%', width:'100%'}); + // tr.append(div0); + + var speed; + if (typeof(this.seriesToggle) === 'string' || typeof(this.seriesToggle) === 'number') { + if (!$.jqplot.use_excanvas || !this.disableIEFading) { + speed = this.seriesToggle; + } + } + if (this.showSwatches) { + td1.bind('click', {series:s, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle); + td1.addClass('jqplot-seriesToggle'); + } + if (this.showLabels) { + td2.bind('click', {series:s, speed:speed, plot: plot, replot:this.seriesToggleReplot}, handleToggle); + td2.addClass('jqplot-seriesToggle'); + } + + // for series that are already hidden, add the hidden class + if (!s.show && s.showLabel) { + td1.addClass('jqplot-series-hidden'); + td2.addClass('jqplot-series-hidden'); + } + } + + pad = true; + } + } + idx++; + } + + td1 = td2 = div0 = div1 = null; + } + } + return this._elem; + }; + + var handleToggle = function (ev) { + var d = ev.data, + s = d.series, + replot = d.replot, + plot = d.plot, + speed = d.speed, + sidx = s.index, + showing = false; + + if (s.canvas._elem.is(':hidden') || !s.show) { + showing = true; + } + + var doLegendToggle = function() { + + if (replot) { + var opts = {}; + + if ($.isPlainObject(replot)) { + $.extend(true, opts, replot); + } + + plot.replot(opts); + // if showing, there was no canvas element to fade in, so hide here + // and then do a fade in. + if (showing && speed) { + var s = plot.series[sidx]; + + if (s.shadowCanvas._elem) { + s.shadowCanvas._elem.hide().fadeIn(speed); + } + s.canvas._elem.hide().fadeIn(speed); + s.canvas._elem.nextAll('.jqplot-point-label.jqplot-series-'+s.index).hide().fadeIn(speed); + } + + } + + else { + var s = plot.series[sidx]; + + if (s.canvas._elem.is(':hidden') || !s.show) { + // Not sure if there is a better way to check for showSwatches and showLabels === true. + // Test for "undefined" since default values for both showSwatches and showLables is true. + if (typeof plot.options.legend.showSwatches === 'undefined' || plot.options.legend.showSwatches === true) { + plot.legend._elem.find('td').eq(sidx * 2).addClass('jqplot-series-hidden'); + } + if (typeof plot.options.legend.showLabels === 'undefined' || plot.options.legend.showLabels === true) { + plot.legend._elem.find('td').eq((sidx * 2) + 1).addClass('jqplot-series-hidden'); + } + } + else { + if (typeof plot.options.legend.showSwatches === 'undefined' || plot.options.legend.showSwatches === true) { + plot.legend._elem.find('td').eq(sidx * 2).removeClass('jqplot-series-hidden'); + } + if (typeof plot.options.legend.showLabels === 'undefined' || plot.options.legend.showLabels === true) { + plot.legend._elem.find('td').eq((sidx * 2) + 1).removeClass('jqplot-series-hidden'); + } + } + + } + + }; + + s.toggleDisplay(ev, doLegendToggle); + }; + + // called with scope of plot. + var postDraw = function () { + if (this.legend.renderer.constructor == $.jqplot.EnhancedLegendRenderer && this.legend.seriesToggle){ + var e = this.legend._elem.detach(); + this.eventCanvas._elem.after(e); + } + }; +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js new file mode 100644 index 0000000..dc40b3c --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){c.jqplot.EnhancedLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.EnhancedLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.EnhancedLegendRenderer.prototype.constructor=c.jqplot.EnhancedLegendRenderer;c.jqplot.EnhancedLegendRenderer.prototype.init=function(d){this.numberRows=null;this.numberColumns=null;this.seriesToggle="normal";this.seriesToggleReplot=false;this.disableIEFading=true;c.extend(true,this,d);if(this.seriesToggle){c.jqplot.postDrawHooks.push(b)}};c.jqplot.EnhancedLegendRenderer.prototype.draw=function(m,y){var f=this;if(this.show){var r=this._series;var u;var w="position:absolute;";w+=(this.background)?"background:"+this.background+";":"";w+=(this.border)?"border:"+this.border+";":"";w+=(this.fontSize)?"font-size:"+this.fontSize+";":"";w+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";w+=(this.textColor)?"color:"+this.textColor+";":"";w+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";w+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";w+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";w+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('<table class="jqplot-table-legend" style="'+w+'"></table>');if(this.seriesToggle){this._elem.css("z-index","3")}var C=false,q=false,d,o;if(this.numberRows){d=this.numberRows;if(!this.numberColumns){o=Math.ceil(r.length/d)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;d=Math.ceil(r.length/this.numberColumns)}else{d=r.length;o=1}}var B,z,e,l,k,n,p,t,h,g;var v=0;for(B=r.length-1;B>=0;B--){if(o==1&&r[B]._stack||r[B].renderer.constructor==c.jqplot.BezierCurveRenderer){q=true}}for(B=0;B<d;B++){e=c(document.createElement("tr"));e.addClass("jqplot-table-legend");if(q){e.prependTo(this._elem)}else{e.appendTo(this._elem)}for(z=0;z<o;z++){if(v<r.length&&(r[v].show||r[v].showLabel)){u=r[v];n=this.labels[v]||u.label.toString();if(n){var x=u.color;if(!q){if(B>0){C=true}else{C=false}}else{if(B==d-1){C=false}else{C=true}}p=(C)?this.rowSpacing:"0";l=c(document.createElement("td"));l.addClass("jqplot-table-legend jqplot-table-legend-swatch");l.css({textAlign:"center",paddingTop:p});h=c(document.createElement("div"));h.addClass("jqplot-table-legend-swatch-outline");g=c(document.createElement("div"));g.addClass("jqplot-table-legend-swatch");g.css({backgroundColor:x,borderColor:x});l.append(h.append(g));k=c(document.createElement("td"));k.addClass("jqplot-table-legend jqplot-table-legend-label");k.css("paddingTop",p);if(this.escapeHtml){k.text(n)}else{k.html(n)}if(q){if(this.showLabels){k.prependTo(e)}if(this.showSwatches){l.prependTo(e)}}else{if(this.showSwatches){l.appendTo(e)}if(this.showLabels){k.appendTo(e)}}if(this.seriesToggle){var A;if(typeof(this.seriesToggle)==="string"||typeof(this.seriesToggle)==="number"){if(!c.jqplot.use_excanvas||!this.disableIEFading){A=this.seriesToggle}}if(this.showSwatches){l.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);l.addClass("jqplot-seriesToggle")}if(this.showLabels){k.bind("click",{series:u,speed:A,plot:y,replot:this.seriesToggleReplot},a);k.addClass("jqplot-seriesToggle")}if(!u.show&&u.showLabel){l.addClass("jqplot-series-hidden");k.addClass("jqplot-series-hidden")}}C=true}}v++}l=k=h=g=null}}return this._elem};var a=function(j){var i=j.data,m=i.series,k=i.replot,h=i.plot,f=i.speed,l=m.index,g=false;if(m.canvas._elem.is(":hidden")||!m.show){g=true}var e=function(){if(k){var n={};if(c.isPlainObject(k)){c.extend(true,n,k)}h.replot(n);if(g&&f){var d=h.series[l];if(d.shadowCanvas._elem){d.shadowCanvas._elem.hide().fadeIn(f)}d.canvas._elem.hide().fadeIn(f);d.canvas._elem.nextAll(".jqplot-point-label.jqplot-series-"+d.index).hide().fadeIn(f)}}else{var d=h.series[l];if(d.canvas._elem.is(":hidden")||!d.show){if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).addClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).addClass("jqplot-series-hidden")}}else{if(typeof h.options.legend.showSwatches==="undefined"||h.options.legend.showSwatches===true){h.legend._elem.find("td").eq(l*2).removeClass("jqplot-series-hidden")}if(typeof h.options.legend.showLabels==="undefined"||h.options.legend.showLabels===true){h.legend._elem.find("td").eq((l*2)+1).removeClass("jqplot-series-hidden")}}}};m.toggleDisplay(j,e)};var b=function(){if(this.legend.renderer.constructor==c.jqplot.EnhancedLegendRenderer&&this.legend.seriesToggle){var d=this.legend._elem.detach();this.eventCanvas._elem.after(d)}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.js new file mode 100644 index 0000000..2cbc9c2 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.js @@ -0,0 +1,943 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.FunnelRenderer + * Plugin renderer to draw a funnel chart. + * x values, if present, will be used as labels. + * y values give area size. + * + * Funnel charts will draw a single series + * only. + * + * To use this renderer, you need to include the + * funnel renderer plugin, for example: + * + * > <script type="text/javascript" src="plugins/jqplot.funnelRenderer.js"></script> + * + * Properties described here are passed into the $.jqplot function + * as options on the series renderer. For example: + * + * > plot2 = $.jqplot('chart2', [s1, s2], { + * > seriesDefaults: { + * > renderer:$.jqplot.FunnelRenderer, + * > rendererOptions:{ + * > sectionMargin: 12, + * > widthRatio: 0.3 + * > } + * > } + * > }); + * + * IMPORTANT + * + * *The funnel renderer will reorder data in descending order* so the largest value in + * the data set is first and displayed on top of the funnel. Data will then + * be displayed in descending order down the funnel. The area of each funnel + * section will correspond to the value of each data point relative to the sum + * of all values. That is section area is proportional to section value divided by + * sum of all section values. + * + * If your data is not in descending order when passed into the plot, *it will be + * reordered* when stored in the series.data property. A copy of the unordered + * data is kept in the series._unorderedData property. + * + * A funnel plot will trigger events on the plot target + * according to user interaction. All events return the event object, + * the series index, the point (section) index, and the point data for + * the appropriate section. *Note* the point index will referr to the ordered + * data, not the original unordered data. + * + * 'jqplotDataMouseOver' - triggered when mousing over a section. + * 'jqplotDataHighlight' - triggered the first time user mouses over a section, + * if highlighting is enabled. + * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of + * a highlighted section. + * 'jqplotDataClick' - triggered when the user clicks on a section. + * 'jqplotDataRightClick' - tiggered when the user right clicks on a section if + * the "captureRightClick" option is set to true on the plot. + */ + $.jqplot.FunnelRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.FunnelRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.FunnelRenderer.prototype.constructor = $.jqplot.FunnelRenderer; + + // called with scope of a series + $.jqplot.FunnelRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + // prop: padding + // padding between the funnel and plot edges, legend, etc. + this.padding = {top: 20, right: 20, bottom: 20, left: 20}; + // prop: sectionMargin + // spacing between funnel sections in pixels. + this.sectionMargin = 6; + // prop: fill + // true or false, whether to fill the areas. + this.fill = true; + // prop: shadowOffset + // offset of the shadow from the area and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.07; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: highlightMouseOver + // True to highlight area when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a area. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a area. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // array of colors to use when highlighting an area. + this.highlightColors = []; + // prop: widthRatio + // The ratio of the width of the top of the funnel to the bottom. + // a ratio of 0 will make an upside down pyramid. + this.widthRatio = 0.2; + // prop: lineWidth + // width of line if areas are stroked and not filled. + this.lineWidth = 2; + // prop: dataLabels + // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. + // Defaults to percentage of each pie slice. + this.dataLabels = 'percent'; + // prop: showDataLabels + // true to show data labels on slices. + this.showDataLabels = false; + // prop: dataLabelFormatString + // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. + this.dataLabelFormatString = null; + // prop: dataLabelThreshold + // Threshhold in percentage (0 - 100) of pie area, below which no label will be displayed. + // This applies to all label types, not just to percentage labels. + this.dataLabelThreshold = 3; + this._type = 'funnel'; + + this.tickRenderer = $.jqplot.FunnelTickRenderer; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + $.extend(true, this, options); + + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + + // lengths of bases, or horizontal sides of areas of trapezoid. + this._bases = []; + // total area + this._atot; + // areas of segments. + this._areas = []; + // vertical lengths of segments. + this._lengths = []; + // angle of the funnel to vertical. + this._angle; + this._dataIndices = []; + + // sort data + this._unorderedData = $.extend(true, [], this.data); + var idxs = $.extend(true, [], this.data); + for (var i=0; i<idxs.length; i++) { + idxs[i].push(i); + } + this.data.sort( function (a, b) { return b[1] - a[1]; } ); + idxs.sort( function (a, b) { return b[1] - a[1]; }); + for (var i=0; i<idxs.length; i++) { + this._dataIndices.push(idxs[i][2]); + } + + // set highlight colors if none provided + if (this.highlightColors.length == 0) { + for (var i=0; i<this.seriesColors.length; i++){ + var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.4 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); + } + } + + plot.postParseOptionsHooks.addOnce(postParseOptions); + plot.postInitHooks.addOnce(postInit); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + plot.postDrawHooks.addOnce(postPlotDraw); + + }; + + // gridData will be of form [label, percentage of total] + $.jqplot.FunnelRenderer.prototype.setGridData = function(plot) { + // set gridData property. This will hold angle in radians of each data point. + var sum = 0; + var td = []; + for (var i=0; i<this.data.length; i++){ + sum += this.data[i][1]; + td.push([this.data[i][0], this.data[i][1]]); + } + + // normalize y values, so areas are proportional. + for (var i=0; i<td.length; i++) { + td[i][1] = td[i][1]/sum; + } + + this._bases = new Array(td.length + 1); + this._lengths = new Array(td.length); + + this.gridData = td; + }; + + $.jqplot.FunnelRenderer.prototype.makeGridData = function(data, plot) { + // set gridData property. This will hold angle in radians of each data point. + var sum = 0; + var td = []; + for (var i=0; i<this.data.length; i++){ + sum += this.data[i][1]; + td.push([this.data[i][0], this.data[i][1]]); + } + + // normalize y values, so areas are proportional. + for (var i=0; i<td.length; i++) { + td[i][1] = td[i][1]/sum; + } + + this._bases = new Array(td.length + 1); + this._lengths = new Array(td.length); + + return td; + }; + + $.jqplot.FunnelRenderer.prototype.drawSection = function (ctx, vertices, color, isShadow) { + var fill = this.fill; + var lineWidth = this.lineWidth; + ctx.save(); + + if (isShadow) { + for (var i=0; i<this.shadowDepth; i++) { + ctx.save(); + ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); + doDraw(); + } + } + + else { + doDraw(); + } + + function doDraw () { + ctx.beginPath(); + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = lineWidth; + ctx.moveTo(vertices[0][0], vertices[0][1]); + for (var i=1; i<4; i++) { + ctx.lineTo(vertices[i][0], vertices[i][1]); + } + ctx.closePath(); + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + } + + if (isShadow) { + for (var i=0; i<this.shadowDepth; i++) { + ctx.restore(); + } + } + + ctx.restore(); + }; + + // called with scope of series + $.jqplot.FunnelRenderer.prototype.draw = function (ctx, gd, options, plot) { + var i; + var opts = (options != undefined) ? options : {}; + // offset and direction of offset due to legend placement + var offx = 0; + var offy = 0; + var trans = 1; + this._areas = []; + // var colorGenerator = new this.colorGenerator(this.seriesColors); + if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { + var li = options.legendInfo; + switch (li.location) { + case 'nw': + offx = li.width + li.xoffset; + break; + case 'w': + offx = li.width + li.xoffset; + break; + case 'sw': + offx = li.width + li.xoffset; + break; + case 'ne': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'e': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'se': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'n': + offy = li.height + li.yoffset; + break; + case 's': + offy = li.height + li.yoffset; + trans = -1; + break; + default: + break; + } + } + + var loff = (trans==1) ? this.padding.left + offx : this.padding.left; + var toff = (trans==1) ? this.padding.top + offy : this.padding.top; + var roff = (trans==-1) ? this.padding.right + offx : this.padding.right; + var boff = (trans==-1) ? this.padding.bottom + offy : this.padding.bottom; + + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var cw = ctx.canvas.width; + var ch = ctx.canvas.height; + this._bases[0] = cw - loff - roff; + var ltot = this._length = ch - toff - boff; + + var hend = this._bases[0]*this.widthRatio; + this._atot = ltot/2 * (this._bases[0] + this._bases[0]*this.widthRatio); + + this._angle = Math.atan((this._bases[0] - hend)/2/ltot); + + for (i=0; i<gd.length; i++) { + this._areas.push(gd[i][1] * this._atot); + } + + + var guess, err, count, lsum=0; + var tolerance = 0.0001; + + for (i=0; i<this._areas.length; i++) { + guess = this._areas[i]/this._bases[i]; + err = 999999; + this._lengths[i] = guess; + count = 0; + while (err > this._lengths[i]*tolerance && count < 100) { + this._lengths[i] = this._areas[i]/(this._bases[i] - this._lengths[i] * Math.tan(this._angle)); + err = Math.abs(this._lengths[i] - guess); + this._bases[i+1] = this._bases[i] - (2*this._lengths[i]*Math.tan(this._angle)); + guess = this._lengths[i]; + count++; + } + lsum += this._lengths[i]; + } + + // figure out vertices of each section + this._vertices = new Array(gd.length); + + // these are 4 coners of entire trapezoid + var p0 = [loff, toff], + p1 = [loff+this._bases[0], toff], + p2 = [loff + (this._bases[0] - this._bases[this._bases.length-1])/2, toff + this._length], + p3 = [p2[0] + this._bases[this._bases.length-1], p2[1]]; + + // equations of right and left sides, returns x, y values given height of section (y value) + function findleft (l) { + var m = (p0[1] - p2[1])/(p0[0] - p2[0]); + var b = p0[1] - m*p0[0]; + var y = l + p0[1]; + + return [(y - b)/m, y]; + } + + function findright (l) { + var m = (p1[1] - p3[1])/(p1[0] - p3[0]); + var b = p1[1] - m*p1[0]; + var y = l + p1[1]; + + return [(y - b)/m, y]; + } + + var x = offx, y = offy; + var h=0, adj=0; + + for (i=0; i<gd.length; i++) { + this._vertices[i] = new Array(); + var v = this._vertices[i]; + var sm = this.sectionMargin; + if (i == 0) { + adj = 0; + } + if (i == 1) { + adj = sm/3; + } + else if (i > 0 && i < gd.length-1) { + adj = sm/2; + } + else if (i == gd.length -1) { + adj = 2*sm/3; + } + v.push(findleft(h+adj)); + v.push(findright(h+adj)); + h += this._lengths[i]; + if (i == 0) { + adj = -2*sm/3; + } + else if (i > 0 && i < gd.length-1) { + adj = -sm/2; + } + else if (i == gd.length - 1) { + adj = 0; + } + v.push(findright(h+adj)); + v.push(findleft(h+adj)); + + } + + if (this.shadow) { + var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; + for (var i=0; i<gd.length; i++) { + this.renderer.drawSection.call (this, ctx, this._vertices[i], shadowColor, true); + } + + } + for (var i=0; i<gd.length; i++) { + var v = this._vertices[i]; + this.renderer.drawSection.call (this, ctx, v, this.seriesColors[i]); + + if (this.showDataLabels && gd[i][1]*100 >= this.dataLabelThreshold) { + var fstr, label; + + if (this.dataLabels == 'label') { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, gd[i][0]); + } + else if (this.dataLabels == 'value') { + fstr = this.dataLabelFormatString || '%d'; + label = $.jqplot.sprintf(fstr, this.data[i][1]); + } + else if (this.dataLabels == 'percent') { + fstr = this.dataLabelFormatString || '%d%%'; + label = $.jqplot.sprintf(fstr, gd[i][1]*100); + } + else if (this.dataLabels.constructor == Array) { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, this.dataLabels[this._dataIndices[i]]); + } + + var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; + + var x = (v[0][0] + v[1][0])/2 + this.canvas._offsets.left; + var y = (v[1][1] + v[2][1])/2 + this.canvas._offsets.top; + + var labelelem = $('<span class="jqplot-funnel-series jqplot-data-label" style="position:absolute;">' + label + '</span>').insertBefore(plot.eventCanvas._elem); + x -= labelelem.width()/2; + y -= labelelem.height()/2; + x = Math.round(x); + y = Math.round(y); + labelelem.css({left: x, top: y}); + } + + } + + }; + + $.jqplot.FunnelAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.FunnelAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.FunnelAxisRenderer.prototype.constructor = $.jqplot.FunnelAxisRenderer; + + + // There are no traditional axes on a funnel chart. We just need to provide + // dummy objects with properties so the plot will render. + // called with scope of axis object. + $.jqplot.FunnelAxisRenderer.prototype.init = function(options){ + // + this.tickRenderer = $.jqplot.FunnelTickRenderer; + $.extend(true, this, options); + // I don't think I'm going to need _dataBounds here. + // have to go Axis scaling in a way to fit chart onto plot area + // and provide u2p and p2u functionality for mouse cursor, etc. + // for convienence set _dataBounds to 0 and 100 and + // set min/max to 0 and 100. + this._dataBounds = {min:0, max:100}; + this.min = 0; + this.max = 100; + this.showTicks = false; + this.ticks = []; + this.showMark = false; + this.show = false; + }; + + + + /** + * Class: $.jqplot.FunnelLegendRenderer + * Legend Renderer specific to funnel plots. Set by default + * when the user creates a funnel plot. + */ + $.jqplot.FunnelLegendRenderer = function(){ + $.jqplot.TableLegendRenderer.call(this); + }; + + $.jqplot.FunnelLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.FunnelLegendRenderer.prototype.constructor = $.jqplot.FunnelLegendRenderer; + + $.jqplot.FunnelLegendRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: numberRows + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // prop: numberColumns + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + $.extend(true, this, options); + }; + + // called with context of legend + $.jqplot.FunnelLegendRenderer.prototype.draw = function() { + var legend = this; + if (this.show) { + var series = this._series; + var ss = 'position:absolute;'; + ss += (this.background) ? 'background:'+this.background+';' : ''; + ss += (this.border) ? 'border:'+this.border+';' : ''; + ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; + ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; + ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; + ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; + ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; + ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; + this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); + // Funnel charts legends don't go by number of series, but by number of data points + // in the series. Refactor things here for that. + + var pad = false, + reverse = false, + nr, nc; + var s = series[0]; + var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); + + if (s.show) { + var pd = s.data; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(pd.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(pd.length/this.numberColumns); + } + else { + nr = pd.length; + nc = 1; + } + + var i, j, tr, td1, td2, lt, rs, color; + var idx = 0; + + for (i=0; i<nr; i++) { + if (reverse){ + tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); + } + else{ + tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); + } + for (j=0; j<nc; j++) { + if (idx < pd.length){ + lt = this.labels[idx] || pd[idx][0].toString(); + color = colorGenerator.next(); + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+ + '</div></td>'); + td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + td2.prependTo(tr); + td1.prependTo(tr); + } + else { + td1.appendTo(tr); + td2.appendTo(tr); + } + pad = true; + } + idx++; + } + } + } + } + return this._elem; + }; + + // $.jqplot.FunnelLegendRenderer.prototype.pack = function(offsets) { + // if (this.show) { + // // fake a grid for positioning + // var grid = {_top:offsets.top, _left:offsets.left, _right:offsets.right, _bottom:this._plotDimensions.height - offsets.bottom}; + // if (this.placement == 'insideGrid') { + // switch (this.location) { + // case 'nw': + // var a = grid._left + this.xoffset; + // var b = grid._top + this.yoffset; + // this._elem.css('left', a); + // this._elem.css('top', b); + // break; + // case 'n': + // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + // var b = grid._top + this.yoffset; + // this._elem.css('left', a); + // this._elem.css('top', b); + // break; + // case 'ne': + // var a = offsets.right + this.xoffset; + // var b = grid._top + this.yoffset; + // this._elem.css({right:a, top:b}); + // break; + // case 'e': + // var a = offsets.right + this.xoffset; + // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + // this._elem.css({right:a, top:b}); + // break; + // case 'se': + // var a = offsets.right + this.xoffset; + // var b = offsets.bottom + this.yoffset; + // this._elem.css({right:a, bottom:b}); + // break; + // case 's': + // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + // var b = offsets.bottom + this.yoffset; + // this._elem.css({left:a, bottom:b}); + // break; + // case 'sw': + // var a = grid._left + this.xoffset; + // var b = offsets.bottom + this.yoffset; + // this._elem.css({left:a, bottom:b}); + // break; + // case 'w': + // var a = grid._left + this.xoffset; + // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + // this._elem.css({left:a, top:b}); + // break; + // default: // same as 'se' + // var a = grid._right - this.xoffset; + // var b = grid._bottom + this.yoffset; + // this._elem.css({right:a, bottom:b}); + // break; + // } + // + // } + // else { + // switch (this.location) { + // case 'nw': + // var a = this._plotDimensions.width - grid._left + this.xoffset; + // var b = grid._top + this.yoffset; + // this._elem.css('right', a); + // this._elem.css('top', b); + // break; + // case 'n': + // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + // var b = this._plotDimensions.height - grid._top + this.yoffset; + // this._elem.css('left', a); + // this._elem.css('bottom', b); + // break; + // case 'ne': + // var a = this._plotDimensions.width - offsets.right + this.xoffset; + // var b = grid._top + this.yoffset; + // this._elem.css({left:a, top:b}); + // break; + // case 'e': + // var a = this._plotDimensions.width - offsets.right + this.xoffset; + // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + // this._elem.css({left:a, top:b}); + // break; + // case 'se': + // var a = this._plotDimensions.width - offsets.right + this.xoffset; + // var b = offsets.bottom + this.yoffset; + // this._elem.css({left:a, bottom:b}); + // break; + // case 's': + // var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + // var b = this._plotDimensions.height - offsets.bottom + this.yoffset; + // this._elem.css({left:a, top:b}); + // break; + // case 'sw': + // var a = this._plotDimensions.width - grid._left + this.xoffset; + // var b = offsets.bottom + this.yoffset; + // this._elem.css({right:a, bottom:b}); + // break; + // case 'w': + // var a = this._plotDimensions.width - grid._left + this.xoffset; + // var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + // this._elem.css({right:a, top:b}); + // break; + // default: // same as 'se' + // var a = grid._right - this.xoffset; + // var b = grid._bottom + this.yoffset; + // this._elem.css({right:a, bottom:b}); + // break; + // } + // } + // } + // }; + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + // only set these if there is a funnel series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.FunnelRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.FunnelRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.FunnelAxisRenderer; + options.legend.renderer = $.jqplot.FunnelLegendRenderer; + options.legend.preDraw = true; + options.sortData = false; + options.seriesDefaults.pointLabels = {show: false}; + } + } + + function postInit(target, data, options) { + // if multiple series, add a reference to the previous one so that + // funnel rings can nest. + for (var i=0; i<this.series.length; i++) { + if (this.series[i].renderer.constructor == $.jqplot.FunnelRenderer) { + // don't allow mouseover and mousedown at same time. + if (this.series[i].highlightMouseOver) { + this.series[i].highlightMouseDown = false; + } + } + } + } + + // called with scope of plot + function postParseOptions(options) { + for (var i=0; i<this.series.length; i++) { + this.series[i].seriesColors = this.seriesColors; + this.series[i].colorGenerator = $.jqplot.colorGenerator; + } + } + + function highlight (plot, sidx, pidx) { + var s = plot.series[sidx]; + var canvas = plot.plugins.funnelRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.funnelRenderer.highlightedSeriesIndex = sidx; + s.renderer.drawSection.call(s, canvas._ctx, s._vertices[pidx], s.highlightColors[pidx], false); + } + + function unhighlight (plot) { + var canvas = plot.plugins.funnelRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.funnelRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.funnelRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.funnelRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.funnelRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var idx = plot.plugins.funnelRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.funnelRenderer && this.plugins.funnelRenderer.highlightCanvas) { + this.plugins.funnelRenderer.highlightCanvas.resetCanvas(); + this.plugins.funnelRenderer.highlightCanvas = null; + } + + this.plugins.funnelRenderer = {}; + this.plugins.funnelRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + + // do we have any data labels? if so, put highlight canvas before those + var labels = $(this.targetId+' .jqplot-data-label'); + if (labels.length) { + $(labels[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this)); + } + // else put highlight canvas before event canvas. + else { + this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this)); + } + var hctx = this.plugins.funnelRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + $.jqplot.preInitHooks.push(preInit); + + $.jqplot.FunnelTickRenderer = function() { + $.jqplot.AxisTickRenderer.call(this); + }; + + $.jqplot.FunnelTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); + $.jqplot.FunnelTickRenderer.prototype.constructor = $.jqplot.FunnelTickRenderer; + +})(jQuery); + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.min.js new file mode 100644 index 0000000..8a705de --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.funnelRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.FunnelRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.FunnelRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.FunnelRenderer.prototype.constructor=e.jqplot.FunnelRenderer;e.jqplot.FunnelRenderer.prototype.init=function(p,t){this.padding={top:20,right:20,bottom:20,left:20};this.sectionMargin=6;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.widthRatio=0.2;this.lineWidth=2;this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this._type="funnel";this.tickRenderer=e.jqplot.FunnelTickRenderer;if(p.highlightMouseDown&&p.highlightMouseOver==null){p.highlightMouseOver=false}e.extend(true,this,p);this._highlightedPoint=null;this._bases=[];this._atot;this._areas=[];this._lengths=[];this._angle;this._dataIndices=[];this._unorderedData=e.extend(true,[],this.data);var o=e.extend(true,[],this.data);for(var r=0;r<o.length;r++){o[r].push(r)}this.data.sort(function(v,u){return u[1]-v[1]});o.sort(function(v,u){return u[1]-v[1]});for(var r=0;r<o.length;r++){this._dataIndices.push(o[r][2])}if(this.highlightColors.length==0){for(var r=0;r<this.seriesColors.length;r++){var q=e.jqplot.getColorComponents(this.seriesColors[r]);var m=[q[0],q[1],q[2]];var s=m[0]+m[1]+m[2];for(var n=0;n<3;n++){m[n]=(s>570)?m[n]*0.8:m[n]+0.4*(255-m[n]);m[n]=parseInt(m[n],10)}this.highlightColors.push("rgb("+m[0]+","+m[1]+","+m[2]+")")}}t.postParseOptionsHooks.addOnce(k);t.postInitHooks.addOnce(g);t.eventListenerHooks.addOnce("jqplotMouseMove",a);t.eventListenerHooks.addOnce("jqplotMouseDown",b);t.eventListenerHooks.addOnce("jqplotMouseUp",j);t.eventListenerHooks.addOnce("jqplotClick",f);t.eventListenerHooks.addOnce("jqplotRightClick",l);t.postDrawHooks.addOnce(h)};e.jqplot.FunnelRenderer.prototype.setGridData=function(o){var n=0;var p=[];for(var m=0;m<this.data.length;m++){n+=this.data[m][1];p.push([this.data[m][0],this.data[m][1]])}for(var m=0;m<p.length;m++){p[m][1]=p[m][1]/n}this._bases=new Array(p.length+1);this._lengths=new Array(p.length);this.gridData=p};e.jqplot.FunnelRenderer.prototype.makeGridData=function(o,p){var n=0;var q=[];for(var m=0;m<this.data.length;m++){n+=this.data[m][1];q.push([this.data[m][0],this.data[m][1]])}for(var m=0;m<q.length;m++){q[m][1]=q[m][1]/n}this._bases=new Array(q.length+1);this._lengths=new Array(q.length);return q};e.jqplot.FunnelRenderer.prototype.drawSection=function(n,p,o,s){var t=this.fill;var m=this.lineWidth;n.save();if(s){for(var r=0;r<this.shadowDepth;r++){n.save();n.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q()}}else{q()}function q(){n.beginPath();n.fillStyle=o;n.strokeStyle=o;n.lineWidth=m;n.moveTo(p[0][0],p[0][1]);for(var u=1;u<4;u++){n.lineTo(p[u][0],p[u][1])}n.closePath();if(t){n.fill()}else{n.stroke()}}if(s){for(var r=0;r<this.shadowDepth;r++){n.restore()}}n.restore()};e.jqplot.FunnelRenderer.prototype.draw=function(G,B,J,p){var Y;var L=(J!=undefined)?J:{};var w=0;var u=0;var R=1;this._areas=[];if(J.legendInfo&&J.legendInfo.placement=="insideGrid"){var O=J.legendInfo;switch(O.location){case"nw":w=O.width+O.xoffset;break;case"w":w=O.width+O.xoffset;break;case"sw":w=O.width+O.xoffset;break;case"ne":w=O.width+O.xoffset;R=-1;break;case"e":w=O.width+O.xoffset;R=-1;break;case"se":w=O.width+O.xoffset;R=-1;break;case"n":u=O.height+O.yoffset;break;case"s":u=O.height+O.yoffset;R=-1;break;default:break}}var t=(R==1)?this.padding.left+w:this.padding.left;var F=(R==1)?this.padding.top+u:this.padding.top;var M=(R==-1)?this.padding.right+w:this.padding.right;var o=(R==-1)?this.padding.bottom+u:this.padding.bottom;var P=(L.shadow!=undefined)?L.shadow:this.shadow;var q=(L.showLine!=undefined)?L.showLine:this.showLine;var C=(L.fill!=undefined)?L.fill:this.fill;var H=G.canvas.width;var N=G.canvas.height;this._bases[0]=H-t-M;var I=this._length=N-F-o;var r=this._bases[0]*this.widthRatio;this._atot=I/2*(this._bases[0]+this._bases[0]*this.widthRatio);this._angle=Math.atan((this._bases[0]-r)/2/I);for(Y=0;Y<B.length;Y++){this._areas.push(B[Y][1]*this._atot)}var E,aa,W,Q=0;var n=0.0001;for(Y=0;Y<this._areas.length;Y++){E=this._areas[Y]/this._bases[Y];aa=999999;this._lengths[Y]=E;W=0;while(aa>this._lengths[Y]*n&&W<100){this._lengths[Y]=this._areas[Y]/(this._bases[Y]-this._lengths[Y]*Math.tan(this._angle));aa=Math.abs(this._lengths[Y]-E);this._bases[Y+1]=this._bases[Y]-(2*this._lengths[Y]*Math.tan(this._angle));E=this._lengths[Y];W++}Q+=this._lengths[Y]}this._vertices=new Array(B.length);var ae=[t,F],ad=[t+this._bases[0],F],ac=[t+(this._bases[0]-this._bases[this._bases.length-1])/2,F+this._length],ab=[ac[0]+this._bases[this._bases.length-1],ac[1]];function V(ag){var x=(ae[1]-ac[1])/(ae[0]-ac[0]);var v=ae[1]-x*ae[0];var ah=ag+ae[1];return[(ah-v)/x,ah]}function D(ag){var x=(ad[1]-ab[1])/(ad[0]-ab[0]);var v=ad[1]-x*ad[0];var ah=ag+ad[1];return[(ah-v)/x,ah]}var T=w,S=u;var Z=0,m=0;for(Y=0;Y<B.length;Y++){this._vertices[Y]=new Array();var U=this._vertices[Y];var A=this.sectionMargin;if(Y==0){m=0}if(Y==1){m=A/3}else{if(Y>0&&Y<B.length-1){m=A/2}else{if(Y==B.length-1){m=2*A/3}}}U.push(V(Z+m));U.push(D(Z+m));Z+=this._lengths[Y];if(Y==0){m=-2*A/3}else{if(Y>0&&Y<B.length-1){m=-A/2}else{if(Y==B.length-1){m=0}}}U.push(D(Z+m));U.push(V(Z+m))}if(this.shadow){var af="rgba(0,0,0,"+this.shadowAlpha+")";for(var Y=0;Y<B.length;Y++){this.renderer.drawSection.call(this,G,this._vertices[Y],af,true)}}for(var Y=0;Y<B.length;Y++){var U=this._vertices[Y];this.renderer.drawSection.call(this,G,U,this.seriesColors[Y]);if(this.showDataLabels&&B[Y][1]*100>=this.dataLabelThreshold){var K,X;if(this.dataLabels=="label"){K=this.dataLabelFormatString||"%s";X=e.jqplot.sprintf(K,B[Y][0])}else{if(this.dataLabels=="value"){K=this.dataLabelFormatString||"%d";X=e.jqplot.sprintf(K,this.data[Y][1])}else{if(this.dataLabels=="percent"){K=this.dataLabelFormatString||"%d%%";X=e.jqplot.sprintf(K,B[Y][1]*100)}else{if(this.dataLabels.constructor==Array){K=this.dataLabelFormatString||"%s";X=e.jqplot.sprintf(K,this.dataLabels[this._dataIndices[Y]])}}}}var s=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var T=(U[0][0]+U[1][0])/2+this.canvas._offsets.left;var S=(U[1][1]+U[2][1])/2+this.canvas._offsets.top;var z=e('<span class="jqplot-funnel-series jqplot-data-label" style="position:absolute;">'+X+"</span>").insertBefore(p.eventCanvas._elem);T-=z.width()/2;S-=z.height()/2;T=Math.round(T);S=Math.round(S);z.css({left:T,top:S})}}};e.jqplot.FunnelAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.FunnelAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.FunnelAxisRenderer.prototype.constructor=e.jqplot.FunnelAxisRenderer;e.jqplot.FunnelAxisRenderer.prototype.init=function(m){this.tickRenderer=e.jqplot.FunnelTickRenderer;e.extend(true,this,m);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.FunnelLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.FunnelLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.FunnelLegendRenderer.prototype.constructor=e.jqplot.FunnelLegendRenderer;e.jqplot.FunnelLegendRenderer.prototype.init=function(m){this.numberRows=null;this.numberColumns=null;e.extend(true,this,m)};e.jqplot.FunnelLegendRenderer.prototype.draw=function(){var p=this;if(this.show){var x=this._series;var A="position:absolute;";A+=(this.background)?"background:"+this.background+";":"";A+=(this.border)?"border:"+this.border+";":"";A+=(this.fontSize)?"font-size:"+this.fontSize+";":"";A+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";A+=(this.textColor)?"color:"+this.textColor+";":"";A+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";A+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";A+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";A+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=e('<table class="jqplot-table-legend" style="'+A+'"></table>');var E=false,w=false,m,u;var y=x[0];var n=new e.jqplot.ColorGenerator(y.seriesColors);if(y.show){var F=y.data;if(this.numberRows){m=this.numberRows;if(!this.numberColumns){u=Math.ceil(F.length/m)}else{u=this.numberColumns}}else{if(this.numberColumns){u=this.numberColumns;m=Math.ceil(F.length/this.numberColumns)}else{m=F.length;u=1}}var D,C,o,r,q,t,v,B;var z=0;for(D=0;D<m;D++){if(w){o=e('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{o=e('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(C=0;C<u;C++){if(z<F.length){t=this.labels[z]||F[z][0].toString();B=n.next();if(!w){if(D>0){E=true}else{E=false}}else{if(D==m-1){E=false}else{E=true}}v=(E)?this.rowSpacing:"0";r=e('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+v+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+B+';"></div></div></td>');q=e('<td class="jqplot-table-legend" style="padding-top:'+v+';"></td>');if(this.escapeHtml){q.text(t)}else{q.html(t)}if(w){q.prependTo(o);r.prependTo(o)}else{r.appendTo(o);q.appendTo(o)}E=true}z++}}}}return this._elem};function c(q,p,n){n=n||{};n.axesDefaults=n.axesDefaults||{};n.legend=n.legend||{};n.seriesDefaults=n.seriesDefaults||{};var m=false;if(n.seriesDefaults.renderer==e.jqplot.FunnelRenderer){m=true}else{if(n.series){for(var o=0;o<n.series.length;o++){if(n.series[o].renderer==e.jqplot.FunnelRenderer){m=true}}}}if(m){n.axesDefaults.renderer=e.jqplot.FunnelAxisRenderer;n.legend.renderer=e.jqplot.FunnelLegendRenderer;n.legend.preDraw=true;n.sortData=false;n.seriesDefaults.pointLabels={show:false}}}function g(p,o,m){for(var n=0;n<this.series.length;n++){if(this.series[n].renderer.constructor==e.jqplot.FunnelRenderer){if(this.series[n].highlightMouseOver){this.series[n].highlightMouseDown=false}}}}function k(m){for(var n=0;n<this.series.length;n++){this.series[n].seriesColors=this.seriesColors;this.series[n].colorGenerator=e.jqplot.colorGenerator}}function d(q,p,o){var n=q.series[p];var m=q.plugins.funnelRenderer.highlightCanvas;m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);n._highlightedPoint=o;q.plugins.funnelRenderer.highlightedSeriesIndex=p;n.renderer.drawSection.call(n,m._ctx,n._vertices[o],n.highlightColors[o],false)}function i(o){var m=o.plugins.funnelRenderer.highlightCanvas;m._ctx.clearRect(0,0,m._ctx.canvas.width,m._ctx.canvas.height);for(var n=0;n<o.series.length;n++){o.series[n]._highlightedPoint=null}o.plugins.funnelRenderer.highlightedSeriesIndex=null;o.target.trigger("jqplotDataUnhighlight")}function a(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var n=jQuery.Event("jqplotDataMouseOver");n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.funnelRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){var m=jQuery.Event("jqplotDataHighlight");m.which=q.which;m.pageX=q.pageX;m.pageY=q.pageY;r.target.trigger(m,o);d(r,o[0],o[1])}}else{if(s==null){i(r)}}}function b(p,o,s,r,q){if(r){var n=[r.seriesIndex,r.pointIndex,r.data];if(q.series[n[0]].highlightMouseDown&&!(n[0]==q.plugins.funnelRenderer.highlightedSeriesIndex&&n[1]==q.series[n[0]]._highlightedPoint)){var m=jQuery.Event("jqplotDataHighlight");m.which=p.which;m.pageX=p.pageX;m.pageY=p.pageY;q.target.trigger(m,n);d(q,n[0],n[1])}}else{if(r==null){i(q)}}}function j(o,n,r,q,p){var m=p.plugins.funnelRenderer.highlightedSeriesIndex;if(m!=null&&p.series[m].highlightMouseDown){i(p)}}function f(p,o,s,r,q){if(r){var n=[r.seriesIndex,r.pointIndex,r.data];var m=jQuery.Event("jqplotDataClick");m.which=p.which;m.pageX=p.pageX;m.pageY=p.pageY;q.target.trigger(m,n)}}function l(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];var m=r.plugins.funnelRenderer.highlightedSeriesIndex;if(m!=null&&r.series[m].highlightMouseDown){i(r)}var n=jQuery.Event("jqplotDataRightClick");n.which=q.which;n.pageX=q.pageX;n.pageY=q.pageY;r.target.trigger(n,o)}}function h(){if(this.plugins.funnelRenderer&&this.plugins.funnelRenderer.highlightCanvas){this.plugins.funnelRenderer.highlightCanvas.resetCanvas();this.plugins.funnelRenderer.highlightCanvas=null}this.plugins.funnelRenderer={};this.plugins.funnelRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var n=e(this.targetId+" .jqplot-data-label");if(n.length){e(n[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-funnelRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-funnelRenderer-highlight-canvas",this._plotDimensions,this))}var m=this.plugins.funnelRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(o){i(o.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.FunnelTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.FunnelTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.FunnelTickRenderer.prototype.constructor=e.jqplot.FunnelTickRenderer})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.js new file mode 100644 index 0000000..3105c85 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.js @@ -0,0 +1,465 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]); + + /** + * Class: $.jqplot.Highlighter + * Plugin which will highlight data points when they are moused over. + * + * To use this plugin, include the js + * file in your source: + * + * > <script type="text/javascript" src="plugins/jqplot.highlighter.js"></script> + * + * A tooltip providing information about the data point is enabled by default. + * To disable the tooltip, set "showTooltip" to false. + * + * You can control what data is displayed in the tooltip with various + * options. The "tooltipAxes" option controls whether the x, y or both + * data values are displayed. + * + * Some chart types (e.g. hi-low-close) have more than one y value per + * data point. To display the additional values in the tooltip, set the + * "yvalues" option to the desired number of y values present (3 for a hlc chart). + * + * By default, data values will be formatted with the same formatting + * specifiers as used to format the axis ticks. A custom format code + * can be supplied with the tooltipFormatString option. This will apply + * to all values in the tooltip. + * + * For more complete control, the "formatString" option can be set. This + * Allows conplete control over tooltip formatting. Values are passed to + * the format string in an order determined by the "tooltipAxes" and "yvalues" + * options. So, if you have a hi-low-close chart and you just want to display + * the hi-low-close values in the tooltip, you could set a formatString like: + * + * > highlighter: { + * > tooltipAxes: 'y', + * > yvalues: 3, + * > formatString:'<table class="jqplot-highlighter"> + * > <tr><td>hi:</td><td>%s</td></tr> + * > <tr><td>low:</td><td>%s</td></tr> + * > <tr><td>close:</td><td>%s</td></tr></table>' + * > } + * + */ + $.jqplot.Highlighter = function(options) { + // Group: Properties + // + //prop: show + // true to show the highlight. + this.show = $.jqplot.config.enablePlugins; + // prop: markerRenderer + // Renderer used to draw the marker of the highlighted point. + // Renderer will assimilate attributes from the data point being highlighted, + // so no attributes need set on the renderer directly. + // Default is to turn off shadow drawing on the highlighted point. + this.markerRenderer = new $.jqplot.MarkerRenderer({shadow:false}); + // prop: showMarker + // true to show the marker + this.showMarker = true; + // prop: lineWidthAdjust + // Pixels to add to the lineWidth of the highlight. + this.lineWidthAdjust = 2.5; + // prop: sizeAdjust + // Pixels to add to the overall size of the highlight. + this.sizeAdjust = 5; + // prop: showTooltip + // Show a tooltip with data point values. + this.showTooltip = true; + // prop: tooltipLocation + // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + this.tooltipLocation = 'nw'; + // prop: fadeTooltip + // true = fade in/out tooltip, flase = show/hide tooltip + this.fadeTooltip = true; + // prop: tooltipFadeSpeed + // 'slow', 'def', 'fast', or number of milliseconds. + this.tooltipFadeSpeed = "fast"; + // prop: tooltipOffset + // Pixel offset of tooltip from the highlight. + this.tooltipOffset = 2; + // prop: tooltipAxes + // Which axes to display in tooltip, 'x', 'y' or 'both', 'xy' or 'yx' + // 'both' and 'xy' are equivalent, 'yx' reverses order of labels. + this.tooltipAxes = 'both'; + // prop; tooltipSeparator + // String to use to separate x and y axes in tooltip. + this.tooltipSeparator = ', '; + // prop; tooltipContentEditor + // Function used to edit/augment/replace the formatted tooltip contents. + // Called as str = tooltipContentEditor(str, seriesIndex, pointIndex) + // where str is the generated tooltip html and seriesIndex and pointIndex identify + // the data point being highlighted. Should return the html for the tooltip contents. + this.tooltipContentEditor = null; + // prop: useAxesFormatters + // Use the x and y axes formatters to format the text in the tooltip. + this.useAxesFormatters = true; + // prop: tooltipFormatString + // sprintf format string for the tooltip. + // Uses Ash Searle's javascript sprintf implementation + // found here: http://hexmen.com/blog/2007/03/printf-sprintf/ + // See http://perldoc.perl.org/functions/sprintf.html for reference. + // Additional "p" and "P" format specifiers added by Chris Leonello. + this.tooltipFormatString = '%.5P'; + // prop: formatString + // alternative to tooltipFormatString + // will format the whole tooltip text, populating with x, y values as + // indicated by tooltipAxes option. So, you could have a tooltip like: + // 'Date: %s, number of cats: %d' to format the whole tooltip at one go. + // If useAxesFormatters is true, values will be formatted according to + // Axes formatters and you can populate your tooltip string with + // %s placeholders. + this.formatString = null; + // prop: yvalues + // Number of y values to expect in the data point array. + // Typically this is 1. Certain plots, like OHLC, will + // have more y values in each data point array. + this.yvalues = 1; + // prop: bringSeriesToFront + // This option requires jQuery 1.4+ + // True to bring the series of the highlighted point to the front + // of other series. + this.bringSeriesToFront = false; + this._tooltipElem; + this.isHighlighting = false; + this.currentNeighbor = null; + + $.extend(true, this, options); + }; + + var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']; + var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7}; + var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; + + // axis.renderer.tickrenderer.formatter + + // called with scope of plot + $.jqplot.Highlighter.init = function (target, data, opts){ + var options = opts || {}; + // add a highlighter attribute to the plot + this.plugins.highlighter = new $.jqplot.Highlighter(options.highlighter); + }; + + // called within scope of series + $.jqplot.Highlighter.parseOptions = function (defaults, options) { + // Add a showHighlight option to the series + // and set it to true by default. + this.showHighlight = true; + }; + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + $.jqplot.Highlighter.postPlotDraw = function() { + // Memory Leaks patch + if (this.plugins.highlighter && this.plugins.highlighter.highlightCanvas) { + this.plugins.highlighter.highlightCanvas.resetCanvas(); + this.plugins.highlighter.highlightCanvas = null; + } + + if (this.plugins.highlighter && this.plugins.highlighter._tooltipElem) { + this.plugins.highlighter._tooltipElem.emptyForce(); + this.plugins.highlighter._tooltipElem = null; + } + + this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions, this)); + this.plugins.highlighter.highlightCanvas.setContext(); + + var elem = document.createElement('div'); + this.plugins.highlighter._tooltipElem = $(elem); + elem = null; + this.plugins.highlighter._tooltipElem.addClass('jqplot-highlighter-tooltip'); + this.plugins.highlighter._tooltipElem.css({position:'absolute', display:'none'}); + + this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem); + }; + + $.jqplot.preInitHooks.push($.jqplot.Highlighter.init); + $.jqplot.preParseSeriesOptionsHooks.push($.jqplot.Highlighter.parseOptions); + $.jqplot.postDrawHooks.push($.jqplot.Highlighter.postPlotDraw); + + function draw(plot, neighbor) { + var hl = plot.plugins.highlighter; + var s = plot.series[neighbor.seriesIndex]; + var smr = s.markerRenderer; + var mr = hl.markerRenderer; + mr.style = smr.style; + mr.lineWidth = smr.lineWidth + hl.lineWidthAdjust; + mr.size = smr.size + hl.sizeAdjust; + var rgba = $.jqplot.getColorComponents(smr.color); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var alpha = (rgba[3] >= 0.6) ? rgba[3]*0.6 : rgba[3]*(2-rgba[3]); + mr.color = 'rgba('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+','+alpha+')'; + mr.init(); + mr.draw(s.gridData[neighbor.pointIndex][0], s.gridData[neighbor.pointIndex][1], hl.highlightCanvas._ctx); + } + + function showTooltip(plot, series, neighbor) { + // neighbor looks like: {seriesIndex: i, pointIndex:j, gridData:p, data:s.data[j]} + // gridData should be x,y pixel coords on the grid. + // add the plot._gridPadding to that to get x,y in the target. + var hl = plot.plugins.highlighter; + var elem = hl._tooltipElem; + var serieshl = series.highlighter || {}; + + var opts = $.extend(true, {}, hl, serieshl); + + if (opts.useAxesFormatters) { + var xf = series._xaxis._ticks[0].formatter; + var yf = series._yaxis._ticks[0].formatter; + var xfstr = series._xaxis._ticks[0].formatString; + var yfstr = series._yaxis._ticks[0].formatString; + var str; + var xstr = xf(xfstr, neighbor.data[0]); + var ystrs = []; + for (var i=1; i<opts.yvalues+1; i++) { + ystrs.push(yf(yfstr, neighbor.data[i])); + } + if (typeof opts.formatString === 'string') { + switch (opts.tooltipAxes) { + case 'both': + case 'xy': + ystrs.unshift(xstr); + ystrs.unshift(opts.formatString); + str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); + break; + case 'yx': + ystrs.push(xstr); + ystrs.unshift(opts.formatString); + str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); + break; + case 'x': + str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString, xstr]); + break; + case 'y': + ystrs.unshift(opts.formatString); + str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); + break; + default: // same as xy + ystrs.unshift(xstr); + ystrs.unshift(opts.formatString); + str = $.jqplot.sprintf.apply($.jqplot.sprintf, ystrs); + break; + } + } + else { + switch (opts.tooltipAxes) { + case 'both': + case 'xy': + str = xstr; + for (var i=0; i<ystrs.length; i++) { + str += opts.tooltipSeparator + ystrs[i]; + } + break; + case 'yx': + str = ''; + for (var i=0; i<ystrs.length; i++) { + str += ystrs[i] + opts.tooltipSeparator; + } + str += xstr; + break; + case 'x': + str = xstr; + break; + case 'y': + str = ystrs.join(opts.tooltipSeparator); + break; + default: // same as 'xy' + str = xstr; + for (var i=0; i<ystrs.length; i++) { + str += opts.tooltipSeparator + ystrs[i]; + } + break; + + } + } + } + else { + var str; + if (typeof opts.formatString === 'string') { + str = $.jqplot.sprintf.apply($.jqplot.sprintf, [opts.formatString].concat(neighbor.data)); + } + + else { + if (opts.tooltipAxes == 'both' || opts.tooltipAxes == 'xy') { + str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]); + } + else if (opts.tooltipAxes == 'yx') { + str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]) + opts.tooltipSeparator + $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]); + } + else if (opts.tooltipAxes == 'x') { + str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[0]); + } + else if (opts.tooltipAxes == 'y') { + str = $.jqplot.sprintf(opts.tooltipFormatString, neighbor.data[1]); + } + } + } + if ($.isFunction(opts.tooltipContentEditor)) { + // args str, seriesIndex, pointIndex are essential so the hook can look up + // extra data for the point. + str = opts.tooltipContentEditor(str, neighbor.seriesIndex, neighbor.pointIndex, plot); + } + elem.html(str); + var gridpos = {x:neighbor.gridData[0], y:neighbor.gridData[1]}; + var ms = 0; + var fact = 0.707; + if (series.markerRenderer.show == true) { + ms = (series.markerRenderer.size + opts.sizeAdjust)/2; + } + + var loc = locations; + if (series.fillToZero && series.fill && neighbor.data[1] < 0) { + loc = oppositeLocations; + } + + switch (loc[locationIndicies[opts.tooltipLocation]]) { + case 'nw': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; + var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; + break; + case 'n': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; + var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - ms; + break; + case 'ne': + var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms; + var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; + break; + case 'e': + var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + ms; + var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + case 'se': + var x = gridpos.x + plot._gridPadding.left + opts.tooltipOffset + fact * ms; + var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms; + break; + case 's': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true)/2; + var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + ms; + break; + case 'sw': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; + var y = gridpos.y + plot._gridPadding.top + opts.tooltipOffset + fact * ms; + break; + case 'w': + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - ms; + var y = gridpos.y + plot._gridPadding.top - elem.outerHeight(true)/2; + break; + default: // same as 'nw' + var x = gridpos.x + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset - fact * ms; + var y = gridpos.y + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true) - fact * ms; + break; + } + elem.css('left', x); + elem.css('top', y); + if (opts.fadeTooltip) { + // Fix for stacked up animations. Thnanks Trevor! + elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed); + } + else { + elem.show(); + } + elem = null; + + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + var hl = plot.plugins.highlighter; + var c = plot.plugins.cursor; + if (hl.show) { + if (neighbor == null && hl.isHighlighting) { + var evt = jQuery.Event('jqplotHighlighterUnhighlight'); + plot.target.trigger(evt); + + var ctx = hl.highlightCanvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + if (hl.fadeTooltip) { + hl._tooltipElem.fadeOut(hl.tooltipFadeSpeed); + } + else { + hl._tooltipElem.hide(); + } + if (hl.bringSeriesToFront) { + plot.restorePreviousSeriesOrder(); + } + hl.isHighlighting = false; + hl.currentNeighbor = null; + ctx = null; + } + else if (neighbor != null && plot.series[neighbor.seriesIndex].showHighlight && !hl.isHighlighting) { + var evt = jQuery.Event('jqplotHighlighterHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data, plot]; + plot.target.trigger(evt, ins); + + hl.isHighlighting = true; + hl.currentNeighbor = neighbor; + if (hl.showMarker) { + draw(plot, neighbor); + } + if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) { + showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor); + } + if (hl.bringSeriesToFront) { + plot.moveSeriesToFront(neighbor.seriesIndex); + } + } + // check to see if we're highlighting the wrong point. + else if (neighbor != null && hl.isHighlighting && hl.currentNeighbor != neighbor) { + // highlighting the wrong point. + + // if new series allows highlighting, highlight new point. + if (plot.series[neighbor.seriesIndex].showHighlight) { + var ctx = hl.highlightCanvas._ctx; + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + hl.isHighlighting = true; + hl.currentNeighbor = neighbor; + if (hl.showMarker) { + draw(plot, neighbor); + } + if (plot.series[neighbor.seriesIndex].show && hl.showTooltip && (!c || !c._zoom.started)) { + showTooltip(plot, plot.series[neighbor.seriesIndex], neighbor); + } + if (hl.bringSeriesToFront) { + plot.moveSeriesToFront(neighbor.seriesIndex); + } + } + } + } + } +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.min.js new file mode 100644 index 0000000..0e9d809 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.highlighter.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(d){d.jqplot.eventListenerHooks.push(["jqplotMouseMove",f]);d.jqplot.Highlighter=function(h){this.show=d.jqplot.config.enablePlugins;this.markerRenderer=new d.jqplot.MarkerRenderer({shadow:false});this.showMarker=true;this.lineWidthAdjust=2.5;this.sizeAdjust=5;this.showTooltip=true;this.tooltipLocation="nw";this.fadeTooltip=true;this.tooltipFadeSpeed="fast";this.tooltipOffset=2;this.tooltipAxes="both";this.tooltipSeparator=", ";this.tooltipContentEditor=null;this.useAxesFormatters=true;this.tooltipFormatString="%.5P";this.formatString=null;this.yvalues=1;this.bringSeriesToFront=false;this._tooltipElem;this.isHighlighting=false;this.currentNeighbor=null;d.extend(true,this,h)};var b=["nw","n","ne","e","se","s","sw","w"];var e={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var c=["se","s","sw","w","nw","n","ne","e"];d.jqplot.Highlighter.init=function(k,j,i){var h=i||{};this.plugins.highlighter=new d.jqplot.Highlighter(h.highlighter)};d.jqplot.Highlighter.parseOptions=function(i,h){this.showHighlight=true};d.jqplot.Highlighter.postPlotDraw=function(){if(this.plugins.highlighter&&this.plugins.highlighter.highlightCanvas){this.plugins.highlighter.highlightCanvas.resetCanvas();this.plugins.highlighter.highlightCanvas=null}if(this.plugins.highlighter&&this.plugins.highlighter._tooltipElem){this.plugins.highlighter._tooltipElem.emptyForce();this.plugins.highlighter._tooltipElem=null}this.plugins.highlighter.highlightCanvas=new d.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding,"jqplot-highlight-canvas",this._plotDimensions,this));this.plugins.highlighter.highlightCanvas.setContext();var h=document.createElement("div");this.plugins.highlighter._tooltipElem=d(h);h=null;this.plugins.highlighter._tooltipElem.addClass("jqplot-highlighter-tooltip");this.plugins.highlighter._tooltipElem.css({position:"absolute",display:"none"});this.eventCanvas._elem.before(this.plugins.highlighter._tooltipElem)};d.jqplot.preInitHooks.push(d.jqplot.Highlighter.init);d.jqplot.preParseSeriesOptionsHooks.push(d.jqplot.Highlighter.parseOptions);d.jqplot.postDrawHooks.push(d.jqplot.Highlighter.postPlotDraw);function a(m,o){var j=m.plugins.highlighter;var p=m.series[o.seriesIndex];var h=p.markerRenderer;var i=j.markerRenderer;i.style=h.style;i.lineWidth=h.lineWidth+j.lineWidthAdjust;i.size=h.size+j.sizeAdjust;var l=d.jqplot.getColorComponents(h.color);var n=[l[0],l[1],l[2]];var k=(l[3]>=0.6)?l[3]*0.6:l[3]*(2-l[3]);i.color="rgba("+n[0]+","+n[1]+","+n[2]+","+k+")";i.init();i.draw(p.gridData[o.pointIndex][0],p.gridData[o.pointIndex][1],j.highlightCanvas._ctx)}function g(A,q,m){var k=A.plugins.highlighter;var D=k._tooltipElem;var r=q.highlighter||{};var t=d.extend(true,{},k,r);if(t.useAxesFormatters){var w=q._xaxis._ticks[0].formatter;var h=q._yaxis._ticks[0].formatter;var E=q._xaxis._ticks[0].formatString;var s=q._yaxis._ticks[0].formatString;var z;var u=w(E,m.data[0]);var l=[];for(var B=1;B<t.yvalues+1;B++){l.push(h(s,m.data[B]))}if(typeof t.formatString==="string"){switch(t.tooltipAxes){case"both":case"xy":l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"yx":l.push(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;case"x":z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString,u]);break;case"y":l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break;default:l.unshift(u);l.unshift(t.formatString);z=d.jqplot.sprintf.apply(d.jqplot.sprintf,l);break}}else{switch(t.tooltipAxes){case"both":case"xy":z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break;case"yx":z="";for(var B=0;B<l.length;B++){z+=l[B]+t.tooltipSeparator}z+=u;break;case"x":z=u;break;case"y":z=l.join(t.tooltipSeparator);break;default:z=u;for(var B=0;B<l.length;B++){z+=t.tooltipSeparator+l[B]}break}}}else{var z;if(typeof t.formatString==="string"){z=d.jqplot.sprintf.apply(d.jqplot.sprintf,[t.formatString].concat(m.data))}else{if(t.tooltipAxes=="both"||t.tooltipAxes=="xy"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}else{if(t.tooltipAxes=="yx"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])+t.tooltipSeparator+d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="x"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[0])}else{if(t.tooltipAxes=="y"){z=d.jqplot.sprintf(t.tooltipFormatString,m.data[1])}}}}}}if(d.isFunction(t.tooltipContentEditor)){z=t.tooltipContentEditor(z,m.seriesIndex,m.pointIndex,A)}D.html(z);var C={x:m.gridData[0],y:m.gridData[1]};var v=0;var j=0.707;if(q.markerRenderer.show==true){v=(q.markerRenderer.size+t.sizeAdjust)/2}var o=b;if(q.fillToZero&&q.fill&&m.data[1]<0){o=c}switch(o[e[t.tooltipLocation]]){case"nw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"n":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-v;break;case"ne":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break;case"e":var p=C.x+A._gridPadding.left+t.tooltipOffset+v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;case"se":var p=C.x+A._gridPadding.left+t.tooltipOffset+j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"s":var p=C.x+A._gridPadding.left-D.outerWidth(true)/2;var n=C.y+A._gridPadding.top+t.tooltipOffset+v;break;case"sw":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top+t.tooltipOffset+j*v;break;case"w":var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-v;var n=C.y+A._gridPadding.top-D.outerHeight(true)/2;break;default:var p=C.x+A._gridPadding.left-D.outerWidth(true)-t.tooltipOffset-j*v;var n=C.y+A._gridPadding.top-t.tooltipOffset-D.outerHeight(true)-j*v;break}D.css("left",p);D.css("top",n);if(t.fadeTooltip){D.stop(true,true).fadeIn(t.tooltipFadeSpeed)}else{D.show()}D=null}function f(n,j,i,p,l){var h=l.plugins.highlighter;var m=l.plugins.cursor;if(h.show){if(p==null&&h.isHighlighting){var o=jQuery.Event("jqplotHighlighterUnhighlight");l.target.trigger(o);var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);if(h.fadeTooltip){h._tooltipElem.fadeOut(h.tooltipFadeSpeed)}else{h._tooltipElem.hide()}if(h.bringSeriesToFront){l.restorePreviousSeriesOrder()}h.isHighlighting=false;h.currentNeighbor=null;q=null}else{if(p!=null&&l.series[p.seriesIndex].showHighlight&&!h.isHighlighting){var o=jQuery.Event("jqplotHighlighterHighlight");o.which=n.which;o.pageX=n.pageX;o.pageY=n.pageY;var k=[p.seriesIndex,p.pointIndex,p.data,l];l.target.trigger(o,k);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}else{if(p!=null&&h.isHighlighting&&h.currentNeighbor!=p){if(l.series[p.seriesIndex].showHighlight){var q=h.highlightCanvas._ctx;q.clearRect(0,0,q.canvas.width,q.canvas.height);h.isHighlighting=true;h.currentNeighbor=p;if(h.showMarker){a(l,p)}if(l.series[p.seriesIndex].show&&h.showTooltip&&(!m||!m._zoom.started)){g(l,l.series[p.seriesIndex],p)}if(h.bringSeriesToFront){l.moveSeriesToFront(p.seriesIndex)}}}}}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.js new file mode 100644 index 0000000..46fb942 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.js @@ -0,0 +1,475 @@ +/* + 2010-11-01 Chris Leonello + + Slightly modified version of the original json2.js to put JSON + functions under the $.jqplot namespace. + + licensing and orignal comments follow: + + http://www.JSON.org/json2.js + 2010-08-25 + + Public Domain. + + NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. + + See http://www.JSON.org/js.html + + + This code should be minified before deployment. + See http://javascript.crockford.com/jsmin.html + + USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO + NOT CONTROL. + + + This file creates a global JSON object containing two methods: stringify + and parse. + + $.jqplot.JSON.stringify(value, replacer, space) + value any JavaScript value, usually an object or array. + + replacer an optional parameter that determines how object + values are stringified for objects. It can be a + function or an array of strings. + + space an optional parameter that specifies the indentation + of nested structures. If it is omitted, the text will + be packed without extra whitespace. If it is a number, + it will specify the number of spaces to indent at each + level. If it is a string (such as '\t' or ' '), + it contains the characters used to indent at each level. + + This method produces a JSON text from a JavaScript value. + + When an object value is found, if the object contains a toJSON + method, its toJSON method will be called and the result will be + stringified. A toJSON method does not serialize: it returns the + value represented by the name/value pair that should be serialized, + or undefined if nothing should be serialized. The toJSON method + will be passed the key associated with the value, and this will be + bound to the value + + For example, this would serialize Dates as ISO strings. + + Date.prototype.toJSON = function (key) { + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + return this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z'; + }; + + You can provide an optional replacer method. It will be passed the + key and value of each member, with this bound to the containing + object. The value that is returned from your method will be + serialized. If your method returns undefined, then the member will + be excluded from the serialization. + + If the replacer parameter is an array of strings, then it will be + used to select the members to be serialized. It filters the results + such that only members with keys listed in the replacer array are + stringified. + + Values that do not have JSON representations, such as undefined or + functions, will not be serialized. Such values in objects will be + dropped; in arrays they will be replaced with null. You can use + a replacer function to replace those with JSON values. + $.jqplot.JSON.stringify(undefined) returns undefined. + + The optional space parameter produces a stringification of the + value that is filled with line breaks and indentation to make it + easier to read. + + If the space parameter is a non-empty string, then that string will + be used for indentation. If the space parameter is a number, then + the indentation will be that many spaces. + + Example: + + text = $.jqplot.JSON.stringify(['e', {pluribus: 'unum'}]); + // text is '["e",{"pluribus":"unum"}]' + + + text = $.jqplot.JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); + // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' + + text = $.jqplot.JSON.stringify([new Date()], function (key, value) { + return this[key] instanceof Date ? + 'Date(' + this[key] + ')' : value; + }); + // text is '["Date(---current time---)"]' + + + $.jqplot.JSON.parse(text, reviver) + This method parses a JSON text to produce an object or array. + It can throw a SyntaxError exception. + + The optional reviver parameter is a function that can filter and + transform the results. It receives each of the keys and values, + and its return value is used instead of the original value. + If it returns what it received, then the structure is not modified. + If it returns undefined then the member is deleted. + + Example: + + // Parse the text. Values that look like ISO date strings will + // be converted to Date objects. + + myData = $.jqplot.JSON.parse(text, function (key, value) { + var a; + if (typeof value === 'string') { + a = +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); + if (a) { + return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], + +a[5], +a[6])); + } + } + return value; + }); + + myData = $.jqplot.JSON.parse('["Date(09/09/2001)"]', function (key, value) { + var d; + if (typeof value === 'string' && + value.slice(0, 5) === 'Date(' && + value.slice(-1) === ')') { + d = new Date(value.slice(5, -1)); + if (d) { + return d; + } + } + return value; + }); + + + This is a reference implementation. You are free to copy, modify, or + redistribute. +*/ + +(function($) { + + $.jqplot.JSON = window.JSON; + + if (!window.JSON) { + $.jqplot.JSON = {}; + } + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? + '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : + '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 ? '[]' : + gap ? '[\n' + gap + + partial.join(',\n' + gap) + '\n' + + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + k = rep[i]; + if (typeof k === 'string') { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 ? '{}' : + gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + + mind + '}' : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof $.jqplot.JSON.stringify !== 'function') { + $.jqplot.JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('$.jqplot.JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof $.jqplot.JSON.parse !== 'function') { + $.jqplot.JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('$.jqplot.JSON.parse'); + }; + } +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.min.js new file mode 100644 index 0000000..414ed9f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.json2.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function($){$.jqplot.JSON=window.JSON;if(!window.JSON){$.jqplot.JSON={}}function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof $.jqplot.JSON.stringify!=="function"){$.jqplot.JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("$.jqplot.JSON.stringify")}return str("",{"":value})}}if(typeof $.jqplot.JSON.parse!=="function"){$.jqplot.JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("$.jqplot.JSON.parse")}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.js new file mode 100644 index 0000000..3bd3e2a --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.js @@ -0,0 +1,534 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * class: $.jqplot.LogAxisRenderer + * A plugin for a jqPlot to render a logarithmic axis. + * + * To use this renderer, include the plugin in your source + * > <script type="text/javascript" language="javascript" src="plugins/jqplot.logAxisRenderer.js"></script> + * + * and supply the appropriate options to your plot + * + * > {axes:{xaxis:{renderer:$.jqplot.LogAxisRenderer}}} + **/ + $.jqplot.LogAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + // prop: axisDefaults + // Default properties which will be applied directly to the series. + // + // Group: Properties + // + // Properties + // + // base - the logarithmic base, commonly 2, 10 or Math.E + // tickDistribution - Deprecated. "power" distribution of ticks + // always used. Option has no effect. + this.axisDefaults = { + base : 10, + tickDistribution :'power' + }; + }; + + $.jqplot.LogAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.LogAxisRenderer.prototype.constructor = $.jqplot.LogAxisRenderer; + + $.jqplot.LogAxisRenderer.prototype.init = function(options) { + // prop: drawBaseline + // True to draw the axis baseline. + this.drawBaseline = true; + // prop: minorTicks + // Number of ticks to add between "major" ticks. + // Major ticks are ticks supplied by user or auto computed. + // Minor ticks cannot be created by user. + this.minorTicks = 'auto'; + this._scalefact = 1.0; + + $.extend(true, this, options); + + this._autoFormatString = '%d'; + this._overrideFormatString = false; + + for (var d in this.renderer.axisDefaults) { + if (this[d] == null) { + this[d] = this.renderer.axisDefaults[d]; + } + } + + this.resetDataBounds(); + }; + + $.jqplot.LogAxisRenderer.prototype.createTicks = function(plot) { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + var db = this._dataBounds; + var dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; + var interval; + var min, max; + var pos1, pos2; + var tt, i; + + var threshold = 30; + // For some reason scalefactor is screwing up ticks. + this._scalefact = (Math.max(dim, threshold+1) - threshold)/300; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i<userTicks.length; i++){ + var ut = userTicks[i]; + var t = new this.tickRenderer(this.tickOptions); + if (ut.constructor == Array) { + t.value = ut[0]; + t.label = ut[1]; + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(ut[0], this.name); + this._ticks.push(t); + } + + else if ($.isPlainObject(ut)) { + $.extend(true, t, ut); + t.axis = this.name; + this._ticks.push(t); + } + + else { + t.value = ut; + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(ut, this.name); + this._ticks.push(t); + } + } + this.numberTicks = userTicks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this.numberTicks-1].value; + } + + // we don't have any ticks yet, let's make some! + else if (this.min == null && this.max == null) { + min = db.min * (2 - this.padMin); + max = db.max * this.padMax; + + // if min and max are same, space them out a bit + if (min == max) { + var adj = 0.05; + min = min*(1-adj); + max = max*(1+adj); + } + + // perform some checks + if (this.min != null && this.min <= 0) { + throw new Error("Log axis minimum must be greater than 0"); + } + if (this.max != null && this.max <= 0) { + throw new Error("Log axis maximum must be greater than 0"); + } + + function findCeil (val) { + var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10)); + return Math.ceil(val/order) * order; + } + + function findFloor(val) { + var order = Math.pow(10, Math.floor(Math.log(val)/Math.LN10)); + return Math.floor(val/order) * order; + } + + // var range = max - min; + var rmin, rmax; + + // for power distribution, open up range to get a nice power of axis.renderer.base. + // power distribution won't respect the user's min/max settings. + rmin = Math.pow(this.base, Math.floor(Math.log(min)/Math.log(this.base))); + rmax = Math.pow(this.base, Math.ceil(Math.log(max)/Math.log(this.base))); + + // // if min and max are same, space them out a bit + // if (rmin === rmax) { + // var adj = 0.05; + // rmin = rmin*(1-adj); + // rmax = rmax*(1+adj); + // } + + // Handle case where a data value was zero + if (rmin === 0) { + rmin = 1; + } + + var order = Math.round(Math.log(rmin)/Math.LN10); + + if (this.tickOptions == null || !this.tickOptions.formatString) { + this._overrideFormatString = true; + } + + this.min = rmin; + this.max = rmax; + var range = this.max - this.min; + + var minorTicks = (this.minorTicks === 'auto') ? 0 : this.minorTicks; + var numberTicks; + if (this.numberTicks == null){ + if (dim > 140) { + numberTicks = Math.round(Math.log(this.max/this.min)/Math.log(this.base) + 1); + if (numberTicks < 2) { + numberTicks = 2; + } + if (minorTicks === 0) { + var temp = dim/(numberTicks - 1); + if (temp < 100) { + minorTicks = 0; + } + else if (temp < 190) { + minorTicks = 1; + } + else if (temp < 250) { + minorTicks = 3; + } + else if (temp < 600) { + minorTicks = 4; + } + else { + minorTicks = 9; + } + } + } + else { + numberTicks = 2; + if (minorTicks === 0) { + minorTicks = 1; + } + minorTicks = 0; + } + } + else { + numberTicks = this.numberTicks; + } + + if (order >= 0 && minorTicks !== 3) { + this._autoFormatString = '%d'; + } + // Adjust format string for case with 3 ticks where we'll have like 1, 2.5, 5, 7.5, 10 + else if (order <= 0 && minorTicks === 3) { + var temp = -(order - 1); + this._autoFormatString = '%.'+ Math.abs(order-1) + 'f'; + } + + // Adjust format string for values less than 1. + else if (order < 0) { + var temp = -order; + this._autoFormatString = '%.'+ Math.abs(order) + 'f'; + } + + else { + this._autoFormatString = '%d'; + } + + var to, t, val, tt1, spread, interval; + for (var i=0; i<numberTicks; i++){ + tt = Math.pow(this.base, i - numberTicks + 1) * this.max; + + t = new this.tickRenderer(this.tickOptions); + + if (this._overrideFormatString) { + t.formatString = this._autoFormatString; + } + + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(tt, this.name); + this._ticks.push(t); + + if (minorTicks && i<numberTicks-1) { + tt1 = Math.pow(this.base, i - numberTicks + 2) * this.max; + spread = tt1 - tt; + interval = tt1 / (minorTicks+1); + for (var j=minorTicks-1; j>=0; j--) { + val = tt1-interval*(j+1); + t = new this.tickRenderer(this.tickOptions); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(val, this.name); + this._ticks.push(t); + } + } + } + } + + // min and max are set as would be the case with zooming + else if (this.min != null && this.max != null) { + var opts = $.extend(true, {}, this.tickOptions, {name: this.name, value: null}); + var nt, ti; + // don't have an interval yet, pick one that gives the most + // "round" ticks we can get. + if (this.numberTicks == null && this.tickInterval == null) { + // var threshold = 30; + var tdim = Math.max(dim, threshold+1); + var nttarget = Math.ceil((tdim-threshold)/35 + 1); + + var ret = $.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min, this.max, nttarget); + + this._autoFormatString = ret[3]; + nt = ret[2]; + ti = ret[4]; + + for (var i=0; i<nt; i++) { + opts.value = this.min + i * ti; + t = new this.tickRenderer(opts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + this._ticks.push(t); + } + } + + // for loose zoom, number ticks and interval are also set. + else if (this.numberTicks != null && this.tickInterval != null) { + nt = this.numberTicks; + for (var i=0; i<nt; i++) { + opts.value = this.min + i * this.tickInterval; + t = new this.tickRenderer(opts); + + if (this._overrideFormatString && this._autoFormatString != '') { + t.formatString = this._autoFormatString; + } + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + this._ticks.push(t); + } + } + } + }; + + $.jqplot.LogAxisRenderer.prototype.pack = function(pos, offsets) { + var lb = parseInt(this.base, 10); + var ticks = this._ticks; + var trans = function (v) { return Math.log(v)/Math.log(lb); }; + var invtrans = function (v) { return Math.pow(Math.E, (Math.log(lb)*v)); }; + var max = trans(this.max); + var min = trans(this.min); + var offmax = offsets.max; + var offmin = offsets.min; + var lshow = (this._label == null) ? false : this._label.show; + + for (var p in pos) { + this._elem.css(p, pos[p]); + } + + this._offsets = offsets; + // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. + var pixellength = offmax - offmin; + var unitlength = max - min; + + // point to unit and unit to point conversions references to Plot DOM element top left corner. + this.p2u = function(p){ + return invtrans((p - offmin) * unitlength / pixellength + min); + }; + + this.u2p = function(u){ + return (trans(u) - min) * pixellength / unitlength + offmin; + }; + + if (this.name == 'xaxis' || this.name == 'x2axis'){ + this.series_u2p = function(u){ + return (trans(u) - min) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return invtrans(p * unitlength / pixellength + min); + }; + } + // yaxis is max at top of canvas. + else { + this.series_u2p = function(u){ + return (trans(u) - max) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return invtrans(p * unitlength / pixellength + max); + }; + } + + if (this.show) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + switch (t.labelPosition) { + case 'auto': + // position at end + if (t.angle < 0) { + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + } + // position at start + else { + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + } + break; + case 'end': + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + case 'start': + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + break; + case 'middle': + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + default: + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + } + } + else { + shim = -t.getWidth()/2; + } + // var shim = t.getWidth()/2; + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('left', val); + t.pack(); + } + } + if (lshow) { + var w = this._label._elem.outerWidth(true); + this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); + if (this.name == 'xaxis') { + this._label._elem.css('bottom', '0px'); + } + else { + this._label._elem.css('top', '0px'); + } + this._label.pack(); + } + } + else { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + switch (t.labelPosition) { + case 'auto': + // position at end + case 'end': + if (t.angle < 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'start': + if (t.angle > 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'middle': + // if (t.angle > 0) { + // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + // } + // else { + // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + // } + shim = -t.getHeight()/2; + break; + default: + shim = -t.getHeight()/2; + break; + } + } + else { + shim = -t.getHeight()/2; + } + + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('top', val); + t.pack(); + } + } + if (lshow) { + var h = this._label._elem.outerHeight(true); + this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); + if (this.name == 'yaxis') { + this._label._elem.css('left', '0px'); + } + else { + this._label._elem.css('right', '0px'); + } + this._label.pack(); + } + } + } + }; +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.min.js new file mode 100644 index 0000000..483c3d2 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.logAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.LogAxisRenderer=function(){a.jqplot.LinearAxisRenderer.call(this);this.axisDefaults={base:10,tickDistribution:"power"}};a.jqplot.LogAxisRenderer.prototype=new a.jqplot.LinearAxisRenderer();a.jqplot.LogAxisRenderer.prototype.constructor=a.jqplot.LogAxisRenderer;a.jqplot.LogAxisRenderer.prototype.init=function(b){this.drawBaseline=true;this.minorTicks="auto";this._scalefact=1;a.extend(true,this,b);this._autoFormatString="%d";this._overrideFormatString=false;for(var c in this.renderer.axisDefaults){if(this[c]==null){this[c]=this.renderer.axisDefaults[c]}}this.resetDataBounds()};a.jqplot.LogAxisRenderer.prototype.createTicks=function(d){var G=this._ticks;var w=this.ticks;var s=this.name;var u=this._dataBounds;var b=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;var k;var N,v;var m,l;var M,K;var g=30;this._scalefact=(Math.max(b,g+1)-g)/300;if(w.length){for(K=0;K<w.length;K++){var A=w[K];var H=new this.tickRenderer(this.tickOptions);if(A.constructor==Array){H.value=A[0];H.label=A[1];if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(A[0],this.name);this._ticks.push(H)}else{if(a.isPlainObject(A)){a.extend(true,H,A);H.axis=this.name;this._ticks.push(H)}else{H.value=A;if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(A,this.name);this._ticks.push(H)}}}this.numberTicks=w.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value}else{if(this.min==null&&this.max==null){N=u.min*(2-this.padMin);v=u.max*this.padMax;if(N==v){var c=0.05;N=N*(1-c);v=v*(1+c)}if(this.min!=null&&this.min<=0){throw new Error("Log axis minimum must be greater than 0")}if(this.max!=null&&this.max<=0){throw new Error("Log axis maximum must be greater than 0")}function f(j){var i=Math.pow(10,Math.floor(Math.log(j)/Math.LN10));return Math.ceil(j/i)*i}function x(j){var i=Math.pow(10,Math.floor(Math.log(j)/Math.LN10));return Math.floor(j/i)*i}var F,r;F=Math.pow(this.base,Math.floor(Math.log(N)/Math.log(this.base)));r=Math.pow(this.base,Math.ceil(Math.log(v)/Math.log(this.base)));if(F===0){F=1}var E=Math.round(Math.log(F)/Math.LN10);if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}this.min=F;this.max=r;var q=this.max-this.min;var C=(this.minorTicks==="auto")?0:this.minorTicks;var h;if(this.numberTicks==null){if(b>140){h=Math.round(Math.log(this.max/this.min)/Math.log(this.base)+1);if(h<2){h=2}if(C===0){var o=b/(h-1);if(o<100){C=0}else{if(o<190){C=1}else{if(o<250){C=3}else{if(o<600){C=4}else{C=9}}}}}}else{h=2;if(C===0){C=1}C=0}}else{h=this.numberTicks}if(E>=0&&C!==3){this._autoFormatString="%d"}else{if(E<=0&&C===3){var o=-(E-1);this._autoFormatString="%."+Math.abs(E-1)+"f"}else{if(E<0){var o=-E;this._autoFormatString="%."+Math.abs(E)+"f"}else{this._autoFormatString="%d"}}}var O,H,z,p,n,k;for(var K=0;K<h;K++){M=Math.pow(this.base,K-h+1)*this.max;H=new this.tickRenderer(this.tickOptions);if(this._overrideFormatString){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(M,this.name);this._ticks.push(H);if(C&&K<h-1){p=Math.pow(this.base,K-h+2)*this.max;n=p-M;k=p/(C+1);for(var J=C-1;J>=0;J--){z=p-k*(J+1);H=new this.tickRenderer(this.tickOptions);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}H.setTick(z,this.name);this._ticks.push(H)}}}}else{if(this.min!=null&&this.max!=null){var y=a.extend(true,{},this.tickOptions,{name:this.name,value:null});var I,e;if(this.numberTicks==null&&this.tickInterval==null){var D=Math.max(b,g+1);var L=Math.ceil((D-g)/35+1);var B=a.jqplot.LinearTickGenerator.bestConstrainedInterval(this.min,this.max,L);this._autoFormatString=B[3];I=B[2];e=B[4];for(var K=0;K<I;K++){y.value=this.min+K*e;H=new this.tickRenderer(y);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}this._ticks.push(H)}}else{if(this.numberTicks!=null&&this.tickInterval!=null){I=this.numberTicks;for(var K=0;K<I;K++){y.value=this.min+K*this.tickInterval;H=new this.tickRenderer(y);if(this._overrideFormatString&&this._autoFormatString!=""){H.formatString=this._autoFormatString}if(!this.showTicks){H.showLabel=false;H.showMark=false}else{if(!this.showTickMarks){H.showMark=false}}this._ticks.push(H)}}}}}}};a.jqplot.LogAxisRenderer.prototype.pack=function(f,e){var r=parseInt(this.base,10);var y=this._ticks;var d=function(h){return Math.log(h)/Math.log(r)};var b=function(h){return Math.pow(Math.E,(Math.log(r)*h))};var u=d(this.max);var s=d(this.min);var m=e.max;var k=e.min;var o=(this._label==null)?false:this._label.show;for(var q in f){this._elem.css(q,f[q])}this._offsets=e;var g=m-k;var j=u-s;this.p2u=function(h){return b((h-k)*j/g+s)};this.u2p=function(h){return(d(h)-s)*g/j+k};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(h){return(d(h)-s)*g/j};this.series_p2u=function(h){return b(h*j/g+s)}}else{this.series_u2p=function(h){return(d(h)-u)*g/j};this.series_p2u=function(h){return b(h*j/g+u)}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var v=0;v<y.length;v++){var n=y[v];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){switch(n.labelPosition){case"auto":if(n.angle<0){c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2}else{c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2}break;case"end":c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;case"start":c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"middle":c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;default:c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break}}else{c=-n.getWidth()/2}var z=this.u2p(n.value)+c+"px";n._elem.css("left",z);n.pack()}}if(o){var l=this._label._elem.outerWidth(true);this._label._elem.css("left",k+g/2-l/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var v=0;v<y.length;v++){var n=y[v];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){switch(n.labelPosition){case"auto":case"end":if(n.angle<0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"start":if(n.angle>0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var z=this.u2p(n.value)+c+"px";n._elem.css("top",z);n.pack()}}if(o){var x=this._label._elem.outerHeight(true);this._label._elem.css("top",m-g/2-x/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.js new file mode 100644 index 0000000..b90c5bc --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.js @@ -0,0 +1,611 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + // class: $.jqplot.MekkoAxisRenderer + // An axis renderer for a Mekko chart. + // Should be used with a Mekko chart where the mekkoRenderer is used on the series. + // Displays the Y axis as a range from 0 to 1 (0 to 100%) and the x axis with a tick + // for each series scaled to the sum of all the y values. + $.jqplot.MekkoAxisRenderer = function() { + }; + + // called with scope of axis object. + $.jqplot.MekkoAxisRenderer.prototype.init = function(options){ + // prop: tickMode + // How to space the ticks on the axis. + // 'bar' will place a tick at the width of each bar. + // This is the default for the x axis. + // 'even' will place ticks at even intervals. This is + // the default for x2 axis and y axis. y axis cannot be changed. + this.tickMode; + // prop: barLabelRenderer + // renderer to use to draw labels under each bar. + this.barLabelRenderer = $.jqplot.AxisLabelRenderer; + // prop: barLabels + // array of labels to put under each bar. + this.barLabels = this.barLabels || []; + // prop: barLabelOptions + // options object to pass to the bar label renderer. + this.barLabelOptions = {}; + this.tickOptions = $.extend(true, {showGridline:false}, this.tickOptions); + this._barLabels = []; + $.extend(true, this, options); + if (this.name == 'yaxis') { + this.tickOptions.formatString = this.tickOptions.formatString || "%d\%"; + } + var db = this._dataBounds; + db.min = 0; + // for y axes, scale always go from 0 to 1 (0 to 100%) + if (this.name == 'yaxis' || this.name == 'y2axis') { + db.max = 100; + this.tickMode = 'even'; + } + // For x axes, scale goes from 0 to sum of all y values. + else if (this.name == 'xaxis'){ + this.tickMode = (this.tickMode == null) ? 'bar' : this.tickMode; + for (var i=0; i<this._series.length; i++) { + db.max += this._series[i]._sumy; + } + } + else if (this.name == 'x2axis'){ + this.tickMode = (this.tickMode == null) ? 'even' : this.tickMode; + for (var i=0; i<this._series.length; i++) { + db.max += this._series[i]._sumy; + } + } + }; + + // called with scope of axis + $.jqplot.MekkoAxisRenderer.prototype.draw = function(ctx, plot) { + if (this.show) { + // populate the axis label and value properties. + // createTicks is a method on the renderer, but + // call it within the scope of the axis. + this.renderer.createTicks.call(this); + // fill a div with axes labels in the right direction. + // Need to pregenerate each axis to get its bounds and + // position it and the labels correctly on the plot. + var dim=0; + var temp; + + var elem = document.createElement('div'); + this._elem = $(elem); + this._elem.addClass('jqplot-axis jqplot-'+this.name); + this._elem.css('position', 'absolute'); + elem = null; + + if (this.name == 'xaxis' || this.name == 'x2axis') { + this._elem.width(this._plotDimensions.width); + } + else { + this._elem.height(this._plotDimensions.height); + } + + // draw the axis label + // create a _label object. + this.labelOptions.axis = this.name; + this._label = new this.labelRenderer(this.labelOptions); + if (this._label.show) { + this._elem.append(this._label.draw(ctx)); + } + + var t, tick, elem; + if (this.showTicks) { + t = this._ticks; + for (var i=0; i<t.length; i++) { + tick = t[i]; + if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + this._elem.append(tick.draw(ctx)); + } + } + } + + // draw the series labels + for (i=0; i<this.barLabels.length; i++) { + this.barLabelOptions.axis = this.name; + this.barLabelOptions.label = this.barLabels[i]; + this._barLabels.push(new this.barLabelRenderer(this.barLabelOptions)); + if (this.tickMode != 'bar') { + this._barLabels[i].show = false; + } + if (this._barLabels[i].show) { + var elem = this._barLabels[i].draw(ctx, plot); + elem.removeClass('jqplot-'+this.name+'-label'); + elem.addClass('jqplot-'+this.name+'-tick'); + elem.addClass('jqplot-mekko-barLabel'); + elem.appendTo(this._elem); + elem = null; + } + } + + } + return this._elem; + }; + + // called with scope of an axis + $.jqplot.MekkoAxisRenderer.prototype.reset = function() { + this.min = this._min; + this.max = this._max; + this.tickInterval = this._tickInterval; + this.numberTicks = this._numberTicks; + // this._ticks = this.__ticks; + }; + + // called with scope of axis + $.jqplot.MekkoAxisRenderer.prototype.set = function() { + var dim = 0; + var temp; + var w = 0; + var h = 0; + var lshow = (this._label == null) ? false : this._label.show; + if (this.show && this.showTicks) { + var t = this._ticks; + for (var i=0; i<t.length; i++) { + var tick = t[i]; + if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + temp = tick._elem.outerHeight(true); + } + else { + temp = tick._elem.outerWidth(true); + } + if (temp > dim) { + dim = temp; + } + } + } + + if (lshow) { + w = this._label._elem.outerWidth(true); + h = this._label._elem.outerHeight(true); + } + if (this.name == 'xaxis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); + } + else if (this.name == 'x2axis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); + } + else if (this.name == 'yaxis') { + dim = dim + w; + this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + else { + dim = dim + w; + this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + } + }; + + // called with scope of axis + $.jqplot.MekkoAxisRenderer.prototype.createTicks = function() { + // we're are operating on an axis here + var ticks = this._ticks; + var userTicks = this.ticks; + var name = this.name; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim, interval; + var min, max; + var pos1, pos2; + var t, tt, i, j; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0; i<userTicks.length; i++){ + var ut = userTicks[i]; + var t = new this.tickRenderer(this.tickOptions); + if (ut.constructor == Array) { + t.value = ut[0]; + t.label = ut[1]; + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(ut[0], this.name); + this._ticks.push(t); + } + + else { + t.value = ut; + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(ut, this.name); + this._ticks.push(t); + } + } + this.numberTicks = userTicks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this.numberTicks-1].value; + this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); + } + + // we don't have any ticks yet, let's make some! + else { + if (name == 'xaxis' || name == 'x2axis') { + dim = this._plotDimensions.width; + } + else { + dim = this._plotDimensions.height; + } + + // if min, max and number of ticks specified, user can't specify interval. + if (this.min != null && this.max != null && this.numberTicks != null) { + this.tickInterval = null; + } + + min = (this.min != null) ? this.min : db.min; + max = (this.max != null) ? this.max : db.max; + + // if min and max are same, space them out a bit.+ + if (min == max) { + var adj = 0.05; + if (min > 0) { + adj = Math.max(Math.log(min)/Math.LN10, 0.05); + } + min -= adj; + max += adj; + } + + var range = max - min; + var rmin, rmax; + var temp, prev, curr; + var ynumticks = [3,5,6,11,21]; + + // yaxis divide ticks in nice intervals from 0 to 1. + if (this.name == 'yaxis' || this.name == 'y2axis') { + this.min = 0; + this.max = 100; + // user didn't specify number of ticks. + if (!this.numberTicks){ + if (this.tickInterval) { + this.numberTicks = 3 + Math.ceil(range / this.tickInterval); + } + else { + temp = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); + for (i=0; i<ynumticks.length; i++) { + curr = temp/ynumticks[i]; + if (curr == 1) { + this.numberTicks = ynumticks[i]; + break; + } + else if (curr > 1) { + prev = curr; + continue; + } + else if (curr < 1) { + // was prev or is curr closer to one? + if (Math.abs(prev - 1) < Math.abs(curr - 1)) { + this.numberTicks = ynumticks[i-1]; + break; + } + else { + this.numberTicks = ynumticks[i]; + break; + } + } + else if (i == ynumticks.length -1) { + this.numberTicks = ynumticks[i]; + } + } + this.tickInterval = range / (this.numberTicks - 1); + } + } + + // user did specify number of ticks. + else { + this.tickInterval = range / (this.numberTicks - 1); + } + + for (var i=0; i<this.numberTicks; i++){ + tt = this.min + i * this.tickInterval; + t = new this.tickRenderer(this.tickOptions); + // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(tt, this.name); + this._ticks.push(t); + } + } + + // for x axes, have number ot ticks equal to number of series and ticks placed + // at sum of y values for each series. + else if (this.tickMode == 'bar') { + this.min = 0; + this.numberTicks = this._series.length + 1; + t = new this.tickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(0, this.name); + this._ticks.push(t); + + temp = 0; + + for (i=1; i<this.numberTicks; i++){ + temp += this._series[i-1]._sumy; + t = new this.tickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(temp, this.name); + this._ticks.push(t); + } + this.max = this.max || temp; + + // if user specified a max and it is greater than sum, add a tick + if (this.max > temp) { + t = new this.tickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(this.max, this.name); + this._ticks.push(t); + + } + } + + else if (this.tickMode == 'even') { + this.min = 0; + this.max = this.max || db.max; + // get a desired number of ticks + var nt = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); + range = this.max - this.min; + this.numberTicks = nt; + this.tickInterval = range / (this.numberTicks - 1); + + for (i=0; i<this.numberTicks; i++){ + tt = this.min + i * this.tickInterval; + t = new this.tickRenderer(this.tickOptions); + // var t = new $.jqplot.AxisTickRenderer(this.tickOptions); + if (!this.showTicks) { + t.showLabel = false; + t.showMark = false; + } + else if (!this.showTickMarks) { + t.showMark = false; + } + t.setTick(tt, this.name); + this._ticks.push(t); + } + + } + } + }; + + // called with scope of axis + $.jqplot.MekkoAxisRenderer.prototype.pack = function(pos, offsets) { + var ticks = this._ticks; + var max = this.max; + var min = this.min; + var offmax = offsets.max; + var offmin = offsets.min; + var lshow = (this._label == null) ? false : this._label.show; + + for (var p in pos) { + this._elem.css(p, pos[p]); + } + + this._offsets = offsets; + // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. + var pixellength = offmax - offmin; + var unitlength = max - min; + + // point to unit and unit to point conversions references to Plot DOM element top left corner. + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + this.u2p = function(u){ + return (u - min) * pixellength / unitlength + offmin; + }; + + if (this.name == 'xaxis' || this.name == 'x2axis'){ + this.series_u2p = function(u){ + return (u - min) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + else { + this.series_u2p = function(u){ + return (u - max) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + + if (this.show) { + if (this.name == 'xaxis' || this.name == 'x2axis') { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'xaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + if (temp * t.angle < 0) { + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + } + // position at start + else { + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + } + break; + case 'end': + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + case 'start': + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + break; + case 'middle': + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + default: + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + } + } + else { + shim = -t.getWidth()/2; + } + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('left', val); + t.pack(); + } + } + var w; + if (lshow) { + w = this._label._elem.outerWidth(true); + this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); + if (this.name == 'xaxis') { + this._label._elem.css('bottom', '0px'); + } + else { + this._label._elem.css('top', '0px'); + } + this._label.pack(); + } + // now show the labels under the bars. + var b, l, r; + for (var i=0; i<this.barLabels.length; i++) { + b = this._barLabels[i]; + if (b.show) { + w = b.getWidth(); + l = this._ticks[i].getLeft() + this._ticks[i].getWidth(); + r = this._ticks[i+1].getLeft(); + b._elem.css('left', (r+l-w)/2+'px'); + b._elem.css('top', this._ticks[i]._elem.css('top')); + b.pack(); + } + } + } + else { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'yaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + case 'end': + if (temp * t.angle < 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'start': + if (t.angle > 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'middle': + shim = -t.getHeight()/2; + break; + default: + shim = -t.getHeight()/2; + break; + } + } + else { + shim = -t.getHeight()/2; + } + + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('top', val); + t.pack(); + } + } + if (lshow) { + var h = this._label._elem.outerHeight(true); + this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); + if (this.name == 'yaxis') { + this._label._elem.css('left', '0px'); + } + else { + this._label._elem.css('right', '0px'); + } + this._label.pack(); + } + } + } + }; +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js new file mode 100644 index 0000000..420dd13 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.MekkoAxisRenderer=function(){};a.jqplot.MekkoAxisRenderer.prototype.init=function(c){this.tickMode;this.barLabelRenderer=a.jqplot.AxisLabelRenderer;this.barLabels=this.barLabels||[];this.barLabelOptions={};this.tickOptions=a.extend(true,{showGridline:false},this.tickOptions);this._barLabels=[];a.extend(true,this,c);if(this.name=="yaxis"){this.tickOptions.formatString=this.tickOptions.formatString||"%d%"}var b=this._dataBounds;b.min=0;if(this.name=="yaxis"||this.name=="y2axis"){b.max=100;this.tickMode="even"}else{if(this.name=="xaxis"){this.tickMode=(this.tickMode==null)?"bar":this.tickMode;for(var d=0;d<this._series.length;d++){b.max+=this._series[d]._sumy}}else{if(this.name=="x2axis"){this.tickMode=(this.tickMode==null)?"even":this.tickMode;for(var d=0;d<this._series.length;d++){b.max+=this._series[d]._sumy}}}}};a.jqplot.MekkoAxisRenderer.prototype.draw=function(b,j){if(this.show){this.renderer.createTicks.call(this);var h=0;var c;var g=document.createElement("div");this._elem=a(g);this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");g=null;if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){this._elem.append(this._label.draw(b))}var f,e,g;if(this.showTicks){f=this._ticks;for(var d=0;d<f.length;d++){e=f[d];if(e.showLabel&&(!e.isMinorTick||this.showMinorTicks)){this._elem.append(e.draw(b))}}}for(d=0;d<this.barLabels.length;d++){this.barLabelOptions.axis=this.name;this.barLabelOptions.label=this.barLabels[d];this._barLabels.push(new this.barLabelRenderer(this.barLabelOptions));if(this.tickMode!="bar"){this._barLabels[d].show=false}if(this._barLabels[d].show){var g=this._barLabels[d].draw(b,j);g.removeClass("jqplot-"+this.name+"-label");g.addClass("jqplot-"+this.name+"-tick");g.addClass("jqplot-mekko-barLabel");g.appendTo(this._elem);g=null}}}return this._elem};a.jqplot.MekkoAxisRenderer.prototype.reset=function(){this.min=this._min;this.max=this._max;this.tickInterval=this._tickInterval;this.numberTicks=this._numberTicks};a.jqplot.MekkoAxisRenderer.prototype.set=function(){var k=0;var d;var c=0;var j=0;var b=(this._label==null)?false:this._label.show;if(this.show&&this.showTicks){var g=this._ticks;for(var f=0;f<g.length;f++){var e=g[f];if(e.showLabel&&(!e.isMinorTick||this.showMinorTicks)){if(this.name=="xaxis"||this.name=="x2axis"){d=e._elem.outerHeight(true)}else{d=e._elem.outerWidth(true)}if(d>k){k=d}}}if(b){c=this._label._elem.outerWidth(true);j=this._label._elem.outerHeight(true)}if(this.name=="xaxis"){k=k+j;this._elem.css({height:k+"px",left:"0px",bottom:"0px"})}else{if(this.name=="x2axis"){k=k+j;this._elem.css({height:k+"px",left:"0px",top:"0px"})}else{if(this.name=="yaxis"){k=k+c;this._elem.css({width:k+"px",left:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}else{k=k+c;this._elem.css({width:k+"px",right:"0px",top:"0px"});if(b&&this._label.constructor==a.jqplot.AxisLabelRenderer){this._label._elem.css("width",c+"px")}}}}}};a.jqplot.MekkoAxisRenderer.prototype.createTicks=function(){var z=this._ticks;var w=this.ticks;var B=this.name;var y=this._dataBounds;var p,x;var n,r;var d,c;var h,b,s,q;if(w.length){for(s=0;s<w.length;s++){var e=w[s];var h=new this.tickRenderer(this.tickOptions);if(e.constructor==Array){h.value=e[0];h.label=e[1];if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(e[0],this.name);this._ticks.push(h)}else{h.value=e;if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(e,this.name);this._ticks.push(h)}}this.numberTicks=w.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1)}else{if(B=="xaxis"||B=="x2axis"){p=this._plotDimensions.width}else{p=this._plotDimensions.height}if(this.min!=null&&this.max!=null&&this.numberTicks!=null){this.tickInterval=null}n=(this.min!=null)?this.min:y.min;r=(this.max!=null)?this.max:y.max;if(n==r){var g=0.05;if(n>0){g=Math.max(Math.log(n)/Math.LN10,0.05)}n-=g;r+=g}var k=r-n;var m,o;var v,l,u;var f=[3,5,6,11,21];if(this.name=="yaxis"||this.name=="y2axis"){this.min=0;this.max=100;if(!this.numberTicks){if(this.tickInterval){this.numberTicks=3+Math.ceil(k/this.tickInterval)}else{v=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);for(s=0;s<f.length;s++){u=v/f[s];if(u==1){this.numberTicks=f[s];break}else{if(u>1){l=u;continue}else{if(u<1){if(Math.abs(l-1)<Math.abs(u-1)){this.numberTicks=f[s-1];break}else{this.numberTicks=f[s];break}}else{if(s==f.length-1){this.numberTicks=f[s]}}}}}this.tickInterval=k/(this.numberTicks-1)}}else{this.tickInterval=k/(this.numberTicks-1)}for(var s=0;s<this.numberTicks;s++){b=this.min+s*this.tickInterval;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(b,this.name);this._ticks.push(h)}}else{if(this.tickMode=="bar"){this.min=0;this.numberTicks=this._series.length+1;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(0,this.name);this._ticks.push(h);v=0;for(s=1;s<this.numberTicks;s++){v+=this._series[s-1]._sumy;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(v,this.name);this._ticks.push(h)}this.max=this.max||v;if(this.max>v){h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(this.max,this.name);this._ticks.push(h)}}else{if(this.tickMode=="even"){this.min=0;this.max=this.max||y.max;var A=2+Math.ceil((p-(this.tickSpacing-1))/this.tickSpacing);k=this.max-this.min;this.numberTicks=A;this.tickInterval=k/(this.numberTicks-1);for(s=0;s<this.numberTicks;s++){b=this.min+s*this.tickInterval;h=new this.tickRenderer(this.tickOptions);if(!this.showTicks){h.showLabel=false;h.showMark=false}else{if(!this.showTickMarks){h.showMark=false}}h.setTick(b,this.name);this._ticks.push(h)}}}}}};a.jqplot.MekkoAxisRenderer.prototype.pack=function(e,d){var C=this._ticks;var x=this.max;var v=this.min;var m=d.max;var j=d.min;var o=(this._label==null)?false:this._label.show;for(var s in e){this._elem.css(s,e[s])}this._offsets=d;var f=m-j;var g=x-v;this.p2u=function(b){return(b-j)*g/f+v};this.u2p=function(b){return(b-v)*f/g+j};if(this.name=="xaxis"||this.name=="x2axis"){this.series_u2p=function(b){return(b-v)*f/g};this.series_p2u=function(b){return b*g/f+v}}else{this.series_u2p=function(b){return(b-x)*f/g};this.series_p2u=function(b){return b*g/f+x}}if(this.show){if(this.name=="xaxis"||this.name=="x2axis"){for(var y=0;y<C.length;y++){var n=C[y];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var A=(this.name=="xaxis")?1:-1;switch(n.labelPosition){case"auto":if(A*n.angle<0){c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2}else{c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2}break;case"end":c=-n.getWidth()+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;case"start":c=-n._textRenderer.height*Math.sin(n._textRenderer.angle)/2;break;case"middle":c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break;default:c=-n.getWidth()/2+n._textRenderer.height*Math.sin(-n._textRenderer.angle)/2;break}}else{c=-n.getWidth()/2}var D=this.u2p(n.value)+c+"px";n._elem.css("left",D);n.pack()}}var k;if(o){k=this._label._elem.outerWidth(true);this._label._elem.css("left",j+f/2-k/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}var B,u,q;for(var y=0;y<this.barLabels.length;y++){B=this._barLabels[y];if(B.show){k=B.getWidth();u=this._ticks[y].getLeft()+this._ticks[y].getWidth();q=this._ticks[y+1].getLeft();B._elem.css("left",(q+u-k)/2+"px");B._elem.css("top",this._ticks[y]._elem.css("top"));B.pack()}}}else{for(var y=0;y<C.length;y++){var n=C[y];if(n.show&&n.showLabel){var c;if(n.constructor==a.jqplot.CanvasAxisTickRenderer&&n.angle){var A=(this.name=="yaxis")?1:-1;switch(n.labelPosition){case"auto":case"end":if(A*n.angle<0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"start":if(n.angle>0){c=-n._textRenderer.height*Math.cos(-n._textRenderer.angle)/2}else{c=-n.getHeight()+n._textRenderer.height*Math.cos(n._textRenderer.angle)/2}break;case"middle":c=-n.getHeight()/2;break;default:c=-n.getHeight()/2;break}}else{c=-n.getHeight()/2}var D=this.u2p(n.value)+c+"px";n._elem.css("top",D);n.pack()}}if(o){var z=this._label._elem.outerHeight(true);this._label._elem.css("top",m-f/2-z/2+"px");if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{this._label._elem.css("right","0px")}this._label.pack()}}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.js new file mode 100644 index 0000000..05f495f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.js @@ -0,0 +1,437 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.MekkoRenderer + * Draws a Mekko style chart which shows 3 dimensional data on a 2 dimensional graph. + * the <$.jqplot.MekkoAxisRenderer> should be used with mekko charts. The mekko renderer + * overrides the default legend renderer with its own $.jqplot.MekkoLegendRenderer + * which allows more flexibility to specify number of rows and columns in the legend. + * + * Data is specified per bar in the chart. You can specify data as an array of y values, or as + * an array of [label, value] pairs. Note that labels are used only on the first series. + * Labels on subsequent series are ignored: + * + * > bar1 = [['shirts', 8],['hats', 14],['shoes', 6],['gloves', 16],['dolls', 12]]; + * > bar2 = [15,6,9,13,6]; + * > bar3 = [['grumpy',4],['sneezy',2],['happy',7],['sleepy',9],['doc',7]]; + * + * If you want to place labels for each bar under the axis, you use the barLabels option on + * the axes. The bar labels can be styled with the ".jqplot-mekko-barLabel" css class. + * + * > barLabels = ['Mickey Mouse', 'Donald Duck', 'Goofy']; + * > axes:{xaxis:{barLabels:barLabels}} + * + */ + + + $.jqplot.MekkoRenderer = function(){ + this.shapeRenderer = new $.jqplot.ShapeRenderer(); + // prop: borderColor + // color of the borders between areas on the chart + this.borderColor = null; + // prop: showBorders + // True to draw borders lines between areas on the chart. + // False will draw borders lines with the same color as the area. + this.showBorders = true; + }; + + // called with scope of series. + $.jqplot.MekkoRenderer.prototype.init = function(options, plot) { + this.fill = false; + this.fillRect = true; + this.strokeRect = true; + this.shadow = false; + // width of bar on x axis. + this._xwidth = 0; + this._xstart = 0; + $.extend(true, this.renderer, options); + // set the shape renderer options + var opts = {lineJoin:'miter', lineCap:'butt', isarc:false, fillRect:this.fillRect, strokeRect:this.strokeRect}; + this.renderer.shapeRenderer.init(opts); + plot.axes.x2axis._series.push(this); + this._type = 'mekko'; + }; + + // Method: setGridData + // converts the user data values to grid coordinates and stores them + // in the gridData array. Will convert user data into appropriate + // rectangles. + // Called with scope of a series. + $.jqplot.MekkoRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var data = this._plotData; + this.gridData = []; + // figure out width on x axis. + // this._xwidth = this._sumy / plot._sumy * this.canvas.getWidth(); + this._xwidth = xp(this._sumy) - xp(0); + if (this.index>0) { + this._xstart = plot.series[this.index-1]._xstart + plot.series[this.index-1]._xwidth; + } + var totheight = this.canvas.getHeight(); + var sumy = 0; + var cury; + var curheight; + for (var i=0; i<data.length; i++) { + if (data[i] != null) { + sumy += data[i][1]; + cury = totheight - (sumy / this._sumy * totheight); + curheight = data[i][1] / this._sumy * totheight; + this.gridData.push([this._xstart, cury, this._xwidth, curheight]); + } + } + }; + + // Method: makeGridData + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.MekkoRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + // figure out width on x axis. + var xp = this._xaxis.series_u2p; + var totheight = this.canvas.getHeight(); + var sumy = 0; + var cury; + var curheight; + var gd = []; + for (var i=0; i<data.length; i++) { + if (data[i] != null) { + sumy += data[i][1]; + cury = totheight - (sumy / this._sumy * totheight); + curheight = data[i][1] / this._sumy * totheight; + gd.push([this._xstart, cury, this._xwidth, curheight]); + } + } + return gd; + }; + + + // called within scope of series. + $.jqplot.MekkoRenderer.prototype.draw = function(ctx, gd, options) { + var i; + var opts = (options != undefined) ? options : {}; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); + ctx.save(); + if (gd.length) { + if (showLine) { + for (i=0; i<gd.length; i++){ + opts.fillStyle = colorGenerator.next(); + if (this.renderer.showBorders) { + opts.strokeStyle = this.renderer.borderColor; + } + else { + opts.strokeStyle = opts.fillStyle; + } + this.renderer.shapeRenderer.draw(ctx, gd[i], opts); + } + } + } + + ctx.restore(); + }; + + $.jqplot.MekkoRenderer.prototype.drawShadow = function(ctx, gd, options) { + // This is a no-op, no shadows on mekko charts. + }; + + /** + * Class: $.jqplot.MekkoLegendRenderer + * Legend renderer used by mekko charts with options for + * controlling number or rows and columns as well as placement + * outside of plot area. + * + */ + $.jqplot.MekkoLegendRenderer = function(){ + // + }; + + $.jqplot.MekkoLegendRenderer.prototype.init = function(options) { + // prop: numberRows + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // prop: numberColumns + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + // this will override the placement option on the Legend object + this.placement = "outside"; + $.extend(true, this, options); + }; + + // called with scope of legend + $.jqplot.MekkoLegendRenderer.prototype.draw = function() { + var legend = this; + if (this.show) { + var series = this._series; + var ss = 'position:absolute;'; + ss += (this.background) ? 'background:'+this.background+';' : ''; + ss += (this.border) ? 'border:'+this.border+';' : ''; + ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; + ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; + this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); + // Mekko charts legends don't go by number of series, but by number of data points + // in the series. Refactor things here for that. + + var pad = false, + reverse = true, // mekko charts are always stacked, so reverse + nr, nc; + var s = series[0]; + var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); + + if (s.show) { + var pd = s.data; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(pd.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(pd.length/this.numberColumns); + } + else { + nr = pd.length; + nc = 1; + } + + var i, j, tr, td1, td2, lt, rs, color; + var idx = 0; + + for (i=0; i<nr; i++) { + if (reverse){ + tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); + } + else{ + tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); + } + for (j=0; j<nc; j++) { + if (idx < pd.length) { + lt = this.labels[idx] || pd[idx][0].toString(); + color = colorGenerator.next(); + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+ + '</div></td>'); + td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + td2.prependTo(tr); + td1.prependTo(tr); + } + else { + td1.appendTo(tr); + td2.appendTo(tr); + } + pad = true; + } + idx++; + } + } + + tr = null; + td1 = null; + td2 = null; + } + } + return this._elem; + }; + + $.jqplot.MekkoLegendRenderer.prototype.pack = function(offsets) { + if (this.show) { + // fake a grid for positioning + var grid = {_top:offsets.top, _left:offsets.left, _right:offsets.right, _bottom:this._plotDimensions.height - offsets.bottom}; + if (this.placement == 'insideGrid') { + switch (this.location) { + case 'nw': + var a = grid._left + this.xoffset; + var b = grid._top + this.yoffset; + this._elem.css('left', a); + this._elem.css('top', b); + break; + case 'n': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = grid._top + this.yoffset; + this._elem.css('left', a); + this._elem.css('top', b); + break; + case 'ne': + var a = offsets.right + this.xoffset; + var b = grid._top + this.yoffset; + this._elem.css({right:a, top:b}); + break; + case 'e': + var a = offsets.right + this.xoffset; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({right:a, top:b}); + break; + case 'se': + var a = offsets.right + this.xoffset; + var b = offsets.bottom + this.yoffset; + this._elem.css({right:a, bottom:b}); + break; + case 's': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = offsets.bottom + this.yoffset; + this._elem.css({left:a, bottom:b}); + break; + case 'sw': + var a = grid._left + this.xoffset; + var b = offsets.bottom + this.yoffset; + this._elem.css({left:a, bottom:b}); + break; + case 'w': + var a = grid._left + this.xoffset; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({left:a, top:b}); + break; + default: // same as 'se' + var a = grid._right - this.xoffset; + var b = grid._bottom + this.yoffset; + this._elem.css({right:a, bottom:b}); + break; + } + + } + else { + switch (this.location) { + case 'nw': + var a = this._plotDimensions.width - grid._left + this.xoffset; + var b = grid._top + this.yoffset; + this._elem.css('right', a); + this._elem.css('top', b); + break; + case 'n': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = this._plotDimensions.height - grid._top + this.yoffset; + this._elem.css('left', a); + this._elem.css('bottom', b); + break; + case 'ne': + var a = this._plotDimensions.width - offsets.right + this.xoffset; + var b = grid._top + this.yoffset; + this._elem.css({left:a, top:b}); + break; + case 'e': + var a = this._plotDimensions.width - offsets.right + this.xoffset; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({left:a, top:b}); + break; + case 'se': + var a = this._plotDimensions.width - offsets.right + this.xoffset; + var b = offsets.bottom + this.yoffset; + this._elem.css({left:a, bottom:b}); + break; + case 's': + var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2; + var b = this._plotDimensions.height - offsets.bottom + this.yoffset; + this._elem.css({left:a, top:b}); + break; + case 'sw': + var a = this._plotDimensions.width - grid._left + this.xoffset; + var b = offsets.bottom + this.yoffset; + this._elem.css({right:a, bottom:b}); + break; + case 'w': + var a = this._plotDimensions.width - grid._left + this.xoffset; + var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2; + this._elem.css({right:a, top:b}); + break; + default: // same as 'se' + var a = grid._right - this.xoffset; + var b = grid._bottom + this.yoffset; + this._elem.css({right:a, bottom:b}); + break; + } + } + } + }; + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.MekkoRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.MekkoRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.MekkoAxisRenderer; + options.legend.renderer = $.jqplot.MekkoLegendRenderer; + options.legend.preDraw = true; + } + } + + $.jqplot.preInitHooks.push(preInit); + +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.min.js new file mode 100644 index 0000000..cece3cd --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mekkoRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(b){b.jqplot.MekkoRenderer=function(){this.shapeRenderer=new b.jqplot.ShapeRenderer();this.borderColor=null;this.showBorders=true};b.jqplot.MekkoRenderer.prototype.init=function(c,e){this.fill=false;this.fillRect=true;this.strokeRect=true;this.shadow=false;this._xwidth=0;this._xstart=0;b.extend(true,this.renderer,c);var d={lineJoin:"miter",lineCap:"butt",isarc:false,fillRect:this.fillRect,strokeRect:this.strokeRect};this.renderer.shapeRenderer.init(d);e.axes.x2axis._series.push(this);this._type="mekko"};b.jqplot.MekkoRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var c=this._yaxis.series_u2p;var g=this._plotData;this.gridData=[];this._xwidth=e(this._sumy)-e(0);if(this.index>0){this._xstart=h.series[this.index-1]._xstart+h.series[this.index-1]._xwidth}var l=this.canvas.getHeight();var d=0;var k;var j;for(var f=0;f<g.length;f++){if(g[f]!=null){d+=g[f][1];k=l-(d/this._sumy*l);j=g[f][1]/this._sumy*l;this.gridData.push([this._xstart,k,this._xwidth,j])}}};b.jqplot.MekkoRenderer.prototype.makeGridData=function(f,g){var d=this._xaxis.series_u2p;var l=this.canvas.getHeight();var c=0;var j;var h;var k=[];for(var e=0;e<f.length;e++){if(f[e]!=null){c+=f[e][1];j=l-(c/this._sumy*l);h=f[e][1]/this._sumy*l;k.push([this._xstart,j,this._xwidth,h])}}return k};b.jqplot.MekkoRenderer.prototype.draw=function(c,h,d){var e;var g=(d!=undefined)?d:{};var f=(g.showLine!=undefined)?g.showLine:this.showLine;var j=new b.jqplot.ColorGenerator(this.seriesColors);c.save();if(h.length){if(f){for(e=0;e<h.length;e++){g.fillStyle=j.next();if(this.renderer.showBorders){g.strokeStyle=this.renderer.borderColor}else{g.strokeStyle=g.fillStyle}this.renderer.shapeRenderer.draw(c,h[e],g)}}}c.restore()};b.jqplot.MekkoRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.MekkoLegendRenderer=function(){};b.jqplot.MekkoLegendRenderer.prototype.init=function(c){this.numberRows=null;this.numberColumns=null;this.placement="outside";b.extend(true,this,c)};b.jqplot.MekkoLegendRenderer.prototype.draw=function(){var f=this;if(this.show){var o=this._series;var r="position:absolute;";r+=(this.background)?"background:"+this.background+";":"";r+=(this.border)?"border:"+this.border+";":"";r+=(this.fontSize)?"font-size:"+this.fontSize+";":"";r+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";r+=(this.textColor)?"color:"+this.textColor+";":"";this._elem=b('<table class="jqplot-table-legend" style="'+r+'"></table>');var w=false,n=true,c,l;var p=o[0];var d=new b.jqplot.ColorGenerator(p.seriesColors);if(p.show){var x=p.data;if(this.numberRows){c=this.numberRows;if(!this.numberColumns){l=Math.ceil(x.length/c)}else{l=this.numberColumns}}else{if(this.numberColumns){l=this.numberColumns;c=Math.ceil(x.length/this.numberColumns)}else{c=x.length;l=1}}var v,u,e,h,g,k,m,t;var q=0;for(v=0;v<c;v++){if(n){e=b('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{e=b('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(u=0;u<l;u++){if(q<x.length){k=this.labels[q]||x[q][0].toString();t=d.next();if(!n){if(v>0){w=true}else{w=false}}else{if(v==c-1){w=false}else{w=true}}m=(w)?this.rowSpacing:"0";h=b('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+m+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+t+';"></div></div></td>');g=b('<td class="jqplot-table-legend" style="padding-top:'+m+';"></td>');if(this.escapeHtml){g.text(k)}else{g.html(k)}if(n){g.prependTo(e);h.prependTo(e)}else{h.appendTo(e);g.appendTo(e)}w=true}q++}}e=null;h=null;g=null}}return this._elem};b.jqplot.MekkoLegendRenderer.prototype.pack=function(f){if(this.show){var e={_top:f.top,_left:f.left,_right:f.right,_bottom:this._plotDimensions.height-f.bottom};if(this.placement=="insideGrid"){switch(this.location){case"nw":var d=e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=e._top+this.yoffset;this._elem.css("left",d);this._elem.css("top",c);break;case"ne":var d=f.right+this.xoffset;var c=e._top+this.yoffset;this._elem.css({right:d,top:c});break;case"e":var d=f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({right:d,top:c});break;case"se":var d=f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"sw":var d=e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"w":var d=e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}else{switch(this.location){case"nw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=e._top+this.yoffset;this._elem.css("right",d);this._elem.css("top",c);break;case"n":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-e._top+this.yoffset;this._elem.css("left",d);this._elem.css("bottom",c);break;case"ne":var d=this._plotDimensions.width-f.right+this.xoffset;var c=e._top+this.yoffset;this._elem.css({left:d,top:c});break;case"e":var d=this._plotDimensions.width-f.right+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({left:d,top:c});break;case"se":var d=this._plotDimensions.width-f.right+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({left:d,bottom:c});break;case"s":var d=(f.left+(this._plotDimensions.width-f.right))/2-this.getWidth()/2;var c=this._plotDimensions.height-f.bottom+this.yoffset;this._elem.css({left:d,top:c});break;case"sw":var d=this._plotDimensions.width-e._left+this.xoffset;var c=f.bottom+this.yoffset;this._elem.css({right:d,bottom:c});break;case"w":var d=this._plotDimensions.width-e._left+this.xoffset;var c=(f.top+(this._plotDimensions.height-f.bottom))/2-this.getHeight()/2;this._elem.css({right:d,top:c});break;default:var d=e._right-this.xoffset;var c=e._bottom+this.yoffset;this._elem.css({right:d,bottom:c});break}}}};function a(g,f,d){d=d||{};d.axesDefaults=d.axesDefaults||{};d.legend=d.legend||{};d.seriesDefaults=d.seriesDefaults||{};var c=false;if(d.seriesDefaults.renderer==b.jqplot.MekkoRenderer){c=true}else{if(d.series){for(var e=0;e<d.series.length;e++){if(d.series[e].renderer==b.jqplot.MekkoRenderer){c=true}}}}if(c){d.axesDefaults.renderer=b.jqplot.MekkoAxisRenderer;d.legend.renderer=b.jqplot.MekkoLegendRenderer;d.legend.preDraw=true}}b.jqplot.preInitHooks.push(a)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.js new file mode 100644 index 0000000..8bd899d --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.js @@ -0,0 +1,1029 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.MeterGaugeRenderer + * Plugin renderer to draw a meter gauge chart. + * + * Data consists of a single series with 1 data point to position the gauge needle. + * + * To use this renderer, you need to include the + * meter gauge renderer plugin, for example: + * + * > <script type="text/javascript" src="plugins/jqplot.meterGaugeRenderer.js"></script> + * + * Properties described here are passed into the $.jqplot function + * as options on the series renderer. For example: + * + * > plot0 = $.jqplot('chart0',[[18]],{ + * > title: 'Network Speed', + * > seriesDefaults: { + * > renderer: $.jqplot.MeterGaugeRenderer, + * > rendererOptions: { + * > label: 'MB/s' + * > } + * > } + * > }); + * + * A meterGauge plot does not support events. + */ + $.jqplot.MeterGaugeRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.MeterGaugeRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.MeterGaugeRenderer.prototype.constructor = $.jqplot.MeterGaugeRenderer; + + // called with scope of a series + $.jqplot.MeterGaugeRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: diameter + // Outer diameter of the meterGauge, auto computed by default + this.diameter = null; + // prop: padding + // padding between the meterGauge and plot edges, auto + // calculated by default. + this.padding = null; + // prop: shadowOffset + // offset of the shadow from the gauge ring and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.07; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 4; + // prop: background + // background color of the inside of the gauge. + this.background = "#efefef"; + // prop: ringColor + // color of the outer ring, hub, and needle of the gauge. + this.ringColor = "#BBC6D0"; + // needle color not implemented yet. + this.needleColor = "#C3D3E5"; + // prop: tickColor + // color of the tick marks around the gauge. + this.tickColor = "#989898"; + // prop: ringWidth + // width of the ring around the gauge. Auto computed by default. + this.ringWidth = null; + // prop: min + // Minimum value on the gauge. Auto computed by default + this.min; + // prop: max + // Maximum value on the gauge. Auto computed by default + this.max; + // prop: ticks + // Array of tick values. Auto computed by default. + this.ticks = []; + // prop: showTicks + // true to show ticks around gauge. + this.showTicks = true; + // prop: showTickLabels + // true to show tick labels next to ticks. + this.showTickLabels = true; + // prop: label + // A gauge label like 'kph' or 'Volts' + this.label = null; + // prop: labelHeightAdjust + // Number of Pixels to offset the label up (-) or down (+) from its default position. + this.labelHeightAdjust = 0; + // prop: labelPosition + // Where to position the label, either 'inside' or 'bottom'. + this.labelPosition = 'inside'; + // prop: intervals + // Array of ranges to be drawn around the gauge. + // Array of form: + // > [value1, value2, ...] + // indicating the values for the first, second, ... intervals. + this.intervals = []; + // prop: intervalColors + // Array of colors to use for the intervals. + this.intervalColors = [ "#4bb2c5", "#EAA228", "#c5b47f", "#579575", "#839557", "#958c12", "#953579", "#4b5de4", "#d8b83f", "#ff5800", "#0085cc", "#c747a3", "#cddf54", "#FBD178", "#26B4E3", "#bd70c7"]; + // prop: intervalInnerRadius + // Radius of the inner circle of the interval ring. + this.intervalInnerRadius = null; + // prop: intervalOuterRadius + // Radius of the outer circle of the interval ring. + this.intervalOuterRadius = null; + this.tickRenderer = $.jqplot.MeterGaugeTickRenderer; + // ticks spaced every 1, 2, 2.5, 5, 10, 20, .1, .2, .25, .5, etc. + this.tickPositions = [1, 2, 2.5, 5, 10]; + // prop: tickSpacing + // Degrees between ticks. This is a target number, if + // incompatible span and ticks are supplied, a suitable + // spacing close to this value will be computed. + this.tickSpacing = 30; + this.numberMinorTicks = null; + // prop: hubRadius + // Radius of the hub at the bottom center of gauge which the needle attaches to. + // Auto computed by default + this.hubRadius = null; + // prop: tickPadding + // padding of the tick marks to the outer ring and the tick labels to marks. + // Auto computed by default. + this.tickPadding = null; + // prop: needleThickness + // Maximum thickness the needle. Auto computed by default. + this.needleThickness = null; + // prop: needlePad + // Padding between needle and inner edge of the ring when the needle is at the min or max gauge value. + this.needlePad = 6; + // prop: pegNeedle + // True will stop needle just below/above the min/max values if data is below/above min/max, + // as if the meter is "pegged". + this.pegNeedle = true; + this._type = 'meterGauge'; + + $.extend(true, this, options); + this.type = null; + this.numberTicks = null; + this.tickInterval = null; + // span, the sweep (in degrees) from min to max. This gauge is + // a semi-circle. + this.span = 180; + // get rid of this nonsense + // this.innerSpan = this.span; + if (this.type == 'circular') { + this.semiCircular = false; + } + else if (this.type != 'circular') { + this.semiCircular = true; + } + else { + this.semiCircular = (this.span <= 180) ? true : false; + } + this._tickPoints = []; + // reference to label element. + this._labelElem = null; + + // start the gauge at the beginning of the span + this.startAngle = (90 + (360 - this.span)/2) * Math.PI/180; + this.endAngle = (90 - (360 - this.span)/2) * Math.PI/180; + + this.setmin = !!(this.min == null); + this.setmax = !!(this.max == null); + + // if given intervals and is an array of values, create labels and colors. + if (this.intervals.length) { + if (this.intervals[0].length == null || this.intervals.length == 1) { + for (var i=0; i<this.intervals.length; i++) { + this.intervals[i] = [this.intervals[i], this.intervals[i], this.intervalColors[i]]; + } + } + else if (this.intervals[0].length == 2) { + for (i=0; i<this.intervals.length; i++) { + this.intervals[i] = [this.intervals[i][0], this.intervals[i][1], this.intervalColors[i]]; + } + } + } + + // compute min, max and ticks if not supplied: + if (this.ticks.length) { + if (this.ticks[0].length == null || this.ticks[0].length == 1) { + for (var i=0; i<this.ticks.length; i++) { + this.ticks[i] = [this.ticks[i], this.ticks[i]]; + } + } + this.min = (this.min == null) ? this.ticks[0][0] : this.min; + this.max = (this.max == null) ? this.ticks[this.ticks.length-1][0] : this.max; + this.setmin = false; + this.setmax = false; + this.numberTicks = this.ticks.length; + this.tickInterval = this.ticks[1][0] - this.ticks[0][0]; + this.tickFactor = Math.floor(parseFloat((Math.log(this.tickInterval)/Math.log(10)).toFixed(11))); + // use the first interal to calculate minor ticks; + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor); + if (!this.numberMinorTicks) { + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor-1); + } + if (!this.numberMinorTicks) { + this.numberMinorTicks = 1; + } + } + + else if (this.intervals.length) { + this.min = (this.min == null) ? 0 : this.min; + this.setmin = false; + if (this.max == null) { + if (this.intervals[this.intervals.length-1][0] >= this.data[0][1]) { + this.max = this.intervals[this.intervals.length-1][0]; + this.setmax = false; + } + } + else { + this.setmax = false; + } + } + + else { + // no ticks and no intervals supplied, put needle in middle + this.min = (this.min == null) ? 0 : this.min; + this.setmin = false; + if (this.max == null) { + this.max = this.data[0][1] * 1.25; + this.setmax = true; + } + else { + this.setmax = false; + } + } + }; + + $.jqplot.MeterGaugeRenderer.prototype.setGridData = function(plot) { + // set gridData property. This will hold angle in radians of each data point. + var stack = []; + var td = []; + var sa = this.startAngle; + for (var i=0; i<this.data.length; i++){ + stack.push(this.data[i][1]); + td.push([this.data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + } + this.gridData = td; + }; + + $.jqplot.MeterGaugeRenderer.prototype.makeGridData = function(data, plot) { + var stack = []; + var td = []; + var sa = this.startAngle; + for (var i=0; i<data.length; i++){ + stack.push(data[i][1]); + td.push([data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + } + return td; + }; + + + function getnmt(pos, interval, fact) { + var temp; + for (var i=pos.length-1; i>=0; i--) { + temp = interval/(pos[i] * Math.pow(10, fact)); + if (temp == 4 || temp == 5) { + return temp - 1; + } + } + return null; + } + + // called with scope of series + $.jqplot.MeterGaugeRenderer.prototype.draw = function (ctx, gd, options) { + var i; + var opts = (options != undefined) ? options : {}; + // offset and direction of offset due to legend placement + var offx = 0; + var offy = 0; + var trans = 1; + if (options.legendInfo && options.legendInfo.placement == 'inside') { + var li = options.legendInfo; + switch (li.location) { + case 'nw': + offx = li.width + li.xoffset; + break; + case 'w': + offx = li.width + li.xoffset; + break; + case 'sw': + offx = li.width + li.xoffset; + break; + case 'ne': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'e': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'se': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'n': + offy = li.height + li.yoffset; + break; + case 's': + offy = li.height + li.yoffset; + trans = -1; + break; + default: + break; + } + } + + + + // pre-draw so can get its dimensions. + if (this.label) { + this._labelElem = $('<div class="jqplot-meterGauge-label" style="position:absolute;">'+this.label+'</div>'); + this.canvas._elem.after(this._labelElem); + } + + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var cw = ctx.canvas.width; + var ch = ctx.canvas.height; + if (this.padding == null) { + this.padding = Math.round(Math.min(cw, ch)/30); + } + var w = cw - offx - 2 * this.padding; + var h = ch - offy - 2 * this.padding; + if (this.labelPosition == 'bottom' && this.label) { + h -= this._labelElem.outerHeight(true); + } + var mindim = Math.min(w,h); + var d = mindim; + + if (!this.diameter) { + if (this.semiCircular) { + if ( w >= 2*h) { + if (!this.ringWidth) { + this.ringWidth = 2*h/35; + } + this.needleThickness = this.needleThickness || 2+Math.pow(this.ringWidth, 0.8); + this.innerPad = this.ringWidth/2 + this.needleThickness/2 + this.needlePad; + this.diameter = 2 * (h - 2*this.innerPad); + } + else { + if (!this.ringWidth) { + this.ringWidth = w/35; + } + this.needleThickness = this.needleThickness || 2+Math.pow(this.ringWidth, 0.8); + this.innerPad = this.ringWidth/2 + this.needleThickness/2 + this.needlePad; + this.diameter = w - 2*this.innerPad - this.ringWidth - this.padding; + } + // center taking into account legend and over draw for gauge bottom below hub. + // this will be center of hub. + this._center = [(cw - trans * offx)/2 + trans * offx, (ch + trans*offy - this.padding - this.ringWidth - this.innerPad)]; + } + else { + if (!this.ringWidth) { + this.ringWidth = d/35; + } + this.needleThickness = this.needleThickness || 2+Math.pow(this.ringWidth, 0.8); + this.innerPad = 0; + this.diameter = d - this.ringWidth; + // center in middle of canvas taking into account legend. + // will be center of hub. + this._center = [(cw-trans*offx)/2 + trans * offx, (ch-trans*offy)/2 + trans * offy]; + } + if (this._labelElem && this.labelPosition == 'bottom') { + this._center[1] -= this._labelElem.outerHeight(true); + } + + } + + this._radius = this.diameter/2; + + this.tickSpacing = 6000/this.diameter; + + if (!this.hubRadius) { + this.hubRadius = this.diameter/18; + } + + this.shadowOffset = 0.5 + this.ringWidth/9; + this.shadowWidth = this.ringWidth*1; + + this.tickPadding = 3 + Math.pow(this.diameter/20, 0.7); + this.tickOuterRadius = this._radius - this.ringWidth/2 - this.tickPadding; + this.tickLength = (this.showTicks) ? this._radius/13 : 0; + + if (this.ticks.length == 0) { + // no ticks, lets make some. + var max = this.max, + min = this.min, + setmax = this.setmax, + setmin = this.setmin, + ti = (max - min) * this.tickSpacing / this.span; + var tf = Math.floor(parseFloat((Math.log(ti)/Math.log(10)).toFixed(11))); + var tp = (ti/Math.pow(10, tf)); + (tp > 2 && tp <= 2.5) ? tp = 2.5 : tp = Math.ceil(tp); + var t = this.tickPositions; + var tpindex, nt; + + for (i=0; i<t.length; i++) { + if (tp == t[i] || i && t[i-1] < tp && tp < t[i]) { + ti = t[i]*Math.pow(10, tf); + tpindex = i; + } + } + + for (i=0; i<t.length; i++) { + if (tp == t[i] || i && t[i-1] < tp && tp < t[i]) { + ti = t[i]*Math.pow(10, tf); + nt = Math.ceil((max - min) / ti); + } + } + + // both max and min are free + if (setmax && setmin) { + var tmin = (min > 0) ? min - min % ti : min - min % ti - ti; + if (!this.forceZero) { + var diff = Math.min(min - tmin, 0.8*ti); + var ntp = Math.floor(diff/t[tpindex]); + if (ntp > 1) { + tmin = tmin + t[tpindex] * (ntp-1); + if (parseInt(tmin, 10) != tmin && parseInt(tmin-t[tpindex], 10) == tmin-t[tpindex]) { + tmin = tmin - t[tpindex]; + } + } + } + if (min == tmin) { + min -= ti; + } + else { + // tmin should always be lower than dataMin + if (min - tmin > 0.23*ti) { + min = tmin; + } + else { + min = tmin -ti; + nt += 1; + } + } + nt += 1; + var tmax = min + (nt - 1) * ti; + if (max >= tmax) { + tmax += ti; + nt += 1; + } + // now tmax should always be mroe than dataMax + if (tmax - max < 0.23*ti) { + tmax += ti; + nt += 1; + } + this.max = max = tmax; + this.min = min; + + this.tickInterval = ti; + this.numberTicks = nt; + var it; + for (i=0; i<nt; i++) { + it = parseFloat((min+i*ti).toFixed(11)); + this.ticks.push([it, it]); + } + this.max = this.ticks[nt-1][1]; + + this.tickFactor = tf; + // determine number of minor ticks + + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor); + + if (!this.numberMinorTicks) { + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor-1); + } + } + // max is free, min is fixed + else if (setmax) { + var tmax = min + (nt - 1) * ti; + if (max >= tmax) { + max = tmax + ti; + nt += 1; + } + else { + max = tmax; + } + + this.tickInterval = this.tickInterval || ti; + this.numberTicks = this.numberTicks || nt; + var it; + for (i=0; i<this.numberTicks; i++) { + it = parseFloat((min+i*this.tickInterval).toFixed(11)); + this.ticks.push([it, it]); + } + this.max = this.ticks[this.numberTicks-1][1]; + + this.tickFactor = tf; + // determine number of minor ticks + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor); + + if (!this.numberMinorTicks) { + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor-1); + } + } + + // not setting max or min + if (!setmax && !setmin) { + var range = this.max - this.min; + tf = Math.floor(parseFloat((Math.log(range)/Math.log(10)).toFixed(11))) - 1; + var nticks = [5,6,4,7,3,8,9,10,2], res, numticks, nonSigDigits=0, sigRange; + // check to see how many zeros are at the end of the range + if (range > 1) { + var rstr = String(range); + if (rstr.search(/\./) == -1) { + var pos = rstr.search(/0+$/); + nonSigDigits = (pos > 0) ? rstr.length - pos - 1 : 0; + } + } + sigRange = range/Math.pow(10, nonSigDigits); + for (i=0; i<nticks.length; i++) { + res = sigRange/(nticks[i]-1); + if (res == parseInt(res, 10)) { + this.numberTicks = nticks[i]; + this.tickInterval = range/(this.numberTicks-1); + this.tickFactor = tf+1; + break; + } + } + var it; + for (i=0; i<this.numberTicks; i++) { + it = parseFloat((this.min+i*this.tickInterval).toFixed(11)); + this.ticks.push([it, it]); + } + // determine number of minor ticks + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor); + + if (!this.numberMinorTicks) { + this.numberMinorTicks = getnmt(this.tickPositions, this.tickInterval, this.tickFactor-1); + } + + if (!this.numberMinorTicks) { + this.numberMinorTicks = 1; + var nums = [4, 5, 3, 6, 2]; + for (i=0; i<5; i++) { + var temp = this.tickInterval/nums[i]; + if (temp == parseInt(temp, 10)) { + this.numberMinorTicks = nums[i]-1; + break; + } + } + } + } + } + + + var r = this._radius, + sa = this.startAngle, + ea = this.endAngle, + pi = Math.PI, + hpi = Math.PI/2; + + if (this.semiCircular) { + var overAngle = Math.atan(this.innerPad/r), + outersa = this.outerStartAngle = sa - overAngle, + outerea = this.outerEndAngle = ea + overAngle, + hubsa = this.hubStartAngle = sa - Math.atan(this.innerPad/this.hubRadius*2), + hubea = this.hubEndAngle = ea + Math.atan(this.innerPad/this.hubRadius*2); + + ctx.save(); + + ctx.translate(this._center[0], this._center[1]); + ctx.lineJoin = "round"; + ctx.lineCap = "round"; + + // draw the innerbackground + ctx.save(); + ctx.beginPath(); + ctx.fillStyle = this.background; + ctx.arc(0, 0, r, outersa, outerea, false); + ctx.closePath(); + ctx.fill(); + ctx.restore(); + + // draw the shadow + // the outer ring. + var shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; + ctx.save(); + for (var i=0; i<this.shadowDepth; i++) { + ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); + ctx.beginPath(); + ctx.strokeStyle = shadowColor; + ctx.lineWidth = this.shadowWidth; + ctx.arc(0 ,0, r, outersa, outerea, false); + ctx.closePath(); + ctx.stroke(); + } + ctx.restore(); + + // the inner hub. + ctx.save(); + var tempd = parseInt((this.shadowDepth+1)/2, 10); + for (var i=0; i<tempd; i++) { + ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); + ctx.beginPath(); + ctx.fillStyle = shadowColor; + ctx.arc(0 ,0, this.hubRadius, hubsa, hubea, false); + ctx.closePath(); + ctx.fill(); + } + ctx.restore(); + + // draw the outer ring. + ctx.save(); + ctx.beginPath(); + ctx.strokeStyle = this.ringColor; + ctx.lineWidth = this.ringWidth; + ctx.arc(0 ,0, r, outersa, outerea, false); + ctx.closePath(); + ctx.stroke(); + ctx.restore(); + + // draw the hub + + ctx.save(); + ctx.beginPath(); + ctx.fillStyle = this.ringColor; + ctx.arc(0 ,0, this.hubRadius,hubsa, hubea, false); + ctx.closePath(); + ctx.fill(); + ctx.restore(); + + // draw the ticks + if (this.showTicks) { + ctx.save(); + var orad = this.tickOuterRadius, + tl = this.tickLength, + mtl = tl/2, + nmt = this.numberMinorTicks, + ts = this.span * Math.PI / 180 / (this.ticks.length-1), + mts = ts/(nmt + 1); + + for (i = 0; i<this.ticks.length; i++) { + ctx.beginPath(); + ctx.lineWidth = 1.5 + this.diameter/360; + ctx.strokeStyle = this.ringColor; + var wps = ts*i+sa; + ctx.moveTo(-orad * Math.cos(ts*i+sa), orad * Math.sin(ts*i+sa)); + ctx.lineTo(-(orad-tl) * Math.cos(ts*i+sa), (orad - tl) * Math.sin(ts*i+sa)); + this._tickPoints.push([(orad-tl) * Math.cos(ts*i+sa) + this._center[0] + this.canvas._offsets.left, (orad - tl) * Math.sin(ts*i+sa) + this._center[1] + this.canvas._offsets.top, ts*i+sa]); + ctx.stroke(); + ctx.lineWidth = 1.0 + this.diameter/440; + if (i<this.ticks.length-1) { + for (var j=1; j<=nmt; j++) { + ctx.beginPath(); + ctx.moveTo(-orad * Math.cos(ts*i+mts*j+sa), orad * Math.sin(ts*i+mts*j+sa)); + ctx.lineTo(-(orad-mtl) * Math.cos(ts*i+mts*j+sa), (orad-mtl) * Math.sin(ts*i+mts*j+sa)); + ctx.stroke(); + } + } + } + ctx.restore(); + } + + // draw the tick labels + if (this.showTickLabels) { + var elem, l, t, ew, eh, dim, maxdim=0; + var tp = this.tickPadding * (1 - 1/(this.diameter/80+1)); + for (i=0; i<this.ticks.length; i++) { + elem = $('<div class="jqplot-meterGauge-tick" style="position:absolute;">'+this.ticks[i][1]+'</div>'); + this.canvas._elem.after(elem); + ew = elem.outerWidth(true); + eh = elem.outerHeight(true); + l = this._tickPoints[i][0] - ew * (this._tickPoints[i][2]-Math.PI)/Math.PI - tp * Math.cos(this._tickPoints[i][2]); + t = this._tickPoints[i][1] - eh/2 + eh/2 * Math.pow(Math.abs((Math.sin(this._tickPoints[i][2]))), 0.5) + tp/3 * Math.pow(Math.abs((Math.sin(this._tickPoints[i][2]))), 0.5) ; + // t = this._tickPoints[i][1] - eh/2 - eh/2 * Math.sin(this._tickPoints[i][2]) - tp/2 * Math.sin(this._tickPoints[i][2]); + elem.css({left:l, top:t, color: this.tickColor}); + dim = ew*Math.cos(this._tickPoints[i][2]) + eh*Math.sin(Math.PI/2+this._tickPoints[i][2]/2); + maxdim = (dim > maxdim) ? dim : maxdim; + } + } + + // draw the gauge label + if (this.label && this.labelPosition == 'inside') { + var l = this._center[0] + this.canvas._offsets.left; + var tp = this.tickPadding * (1 - 1/(this.diameter/80+1)); + var t = 0.5*(this._center[1] + this.canvas._offsets.top - this.hubRadius) + 0.5*(this._center[1] + this.canvas._offsets.top - this.tickOuterRadius + this.tickLength + tp) + this.labelHeightAdjust; + // this._labelElem = $('<div class="jqplot-meterGauge-label" style="position:absolute;">'+this.label+'</div>'); + // this.canvas._elem.after(this._labelElem); + l -= this._labelElem.outerWidth(true)/2; + t -= this._labelElem.outerHeight(true)/2; + this._labelElem.css({left:l, top:t}); + } + + else if (this.label && this.labelPosition == 'bottom') { + var l = this._center[0] + this.canvas._offsets.left - this._labelElem.outerWidth(true)/2; + var t = this._center[1] + this.canvas._offsets.top + this.innerPad + this.ringWidth + this.padding + this.labelHeightAdjust; + this._labelElem.css({left:l, top:t}); + + } + + // draw the intervals + + ctx.save(); + var inner = this.intervalInnerRadius || this.hubRadius * 1.5; + if (this.intervalOuterRadius == null) { + if (this.showTickLabels) { + var outer = (this.tickOuterRadius - this.tickLength - this.tickPadding - this.diameter/8); + } + else { + var outer = (this.tickOuterRadius - this.tickLength - this.diameter/16); + } + } + else { + var outer = this.intervalOuterRadius; + } + var range = this.max - this.min; + var intrange = this.intervals[this.intervals.length-1] - this.min; + var start, end, span = this.span*Math.PI/180; + for (i=0; i<this.intervals.length; i++) { + start = (i == 0) ? sa : sa + (this.intervals[i-1][0] - this.min)*span/range; + if (start < 0) { + start = 0; + } + end = sa + (this.intervals[i][0] - this.min)*span/range; + if (end < 0) { + end = 0; + } + ctx.beginPath(); + ctx.fillStyle = this.intervals[i][2]; + ctx.arc(0, 0, inner, start, end, false); + ctx.lineTo(outer*Math.cos(end), outer*Math.sin(end)); + ctx.arc(0, 0, outer, end, start, true); + ctx.lineTo(inner*Math.cos(start), inner*Math.sin(start)); + ctx.closePath(); + ctx.fill(); + } + ctx.restore(); + + // draw the needle + var datapoint = this.data[0][1]; + var dataspan = this.max - this.min; + if (this.pegNeedle) { + if (this.data[0][1] > this.max + dataspan*3/this.span) { + datapoint = this.max + dataspan*3/this.span; + } + if (this.data[0][1] < this.min - dataspan*3/this.span) { + datapoint = this.min - dataspan*3/this.span; + } + } + var dataang = (datapoint - this.min)/dataspan * this.span * Math.PI/180 + this.startAngle; + + + ctx.save(); + ctx.beginPath(); + ctx.fillStyle = this.ringColor; + ctx.strokeStyle = this.ringColor; + this.needleLength = (this.tickOuterRadius - this.tickLength) * 0.85; + this.needleThickness = (this.needleThickness < 2) ? 2 : this.needleThickness; + var endwidth = this.needleThickness * 0.4; + + + var dl = this.needleLength/10; + var dt = (this.needleThickness - endwidth)/10; + var templ; + for (var i=0; i<10; i++) { + templ = this.needleThickness - i*dt; + ctx.moveTo(dl*i*Math.cos(dataang), dl*i*Math.sin(dataang)); + ctx.lineWidth = templ; + ctx.lineTo(dl*(i+1)*Math.cos(dataang), dl*(i+1)*Math.sin(dataang)); + ctx.stroke(); + } + + ctx.restore(); + } + else { + this._center = [(cw - trans * offx)/2 + trans * offx, (ch - trans*offy)/2 + trans * offy]; + } + }; + + $.jqplot.MeterGaugeAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.MeterGaugeAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.MeterGaugeAxisRenderer.prototype.constructor = $.jqplot.MeterGaugeAxisRenderer; + + + // There are no traditional axes on a gauge chart. We just need to provide + // dummy objects with properties so the plot will render. + // called with scope of axis object. + $.jqplot.MeterGaugeAxisRenderer.prototype.init = function(options){ + // + this.tickRenderer = $.jqplot.MeterGaugeTickRenderer; + $.extend(true, this, options); + // I don't think I'm going to need _dataBounds here. + // have to go Axis scaling in a way to fit chart onto plot area + // and provide u2p and p2u functionality for mouse cursor, etc. + // for convienence set _dataBounds to 0 and 100 and + // set min/max to 0 and 100. + this._dataBounds = {min:0, max:100}; + this.min = 0; + this.max = 100; + this.showTicks = false; + this.ticks = []; + this.showMark = false; + this.show = false; + }; + + $.jqplot.MeterGaugeLegendRenderer = function(){ + $.jqplot.TableLegendRenderer.call(this); + }; + + $.jqplot.MeterGaugeLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.MeterGaugeLegendRenderer.prototype.constructor = $.jqplot.MeterGaugeLegendRenderer; + + /** + * Class: $.jqplot.MeterGaugeLegendRenderer + *Meter gauges don't typically have a legend, this overrides the default legend renderer. + */ + $.jqplot.MeterGaugeLegendRenderer.prototype.init = function(options) { + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + $.extend(true, this, options); + }; + + // called with context of legend + $.jqplot.MeterGaugeLegendRenderer.prototype.draw = function() { + if (this.show) { + var series = this._series; + var ss = 'position:absolute;'; + ss += (this.background) ? 'background:'+this.background+';' : ''; + ss += (this.border) ? 'border:'+this.border+';' : ''; + ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : ''; + ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : ''; + ss += (this.textColor) ? 'color:'+this.textColor+';' : ''; + ss += (this.marginTop != null) ? 'margin-top:'+this.marginTop+';' : ''; + ss += (this.marginBottom != null) ? 'margin-bottom:'+this.marginBottom+';' : ''; + ss += (this.marginLeft != null) ? 'margin-left:'+this.marginLeft+';' : ''; + ss += (this.marginRight != null) ? 'margin-right:'+this.marginRight+';' : ''; + this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>'); + // MeterGauge charts legends don't go by number of series, but by number of data points + // in the series. Refactor things here for that. + + var pad = false, + reverse = false, + nr, nc; + var s = series[0]; + + if (s.show) { + var pd = s.data; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(pd.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(pd.length/this.numberColumns); + } + else { + nr = pd.length; + nc = 1; + } + + var i, j, tr, td1, td2, lt, rs, color; + var idx = 0; + + for (i=0; i<nr; i++) { + if (reverse){ + tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem); + } + else{ + tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem); + } + for (j=0; j<nc; j++) { + if (idx < pd.length){ + // debugger + lt = this.labels[idx] || pd[idx][0].toString(); + color = s.color; + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+ + '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+ + '</div></td>'); + td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>'); + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + td2.prependTo(tr); + td1.prependTo(tr); + } + else { + td1.appendTo(tr); + td2.appendTo(tr); + } + pad = true; + } + idx++; + } + } + } + } + return this._elem; + }; + + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + // debugger + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + options.grid = options.grid || {}; + + // only set these if there is a gauge series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.MeterGaugeRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.MeterGaugeRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.MeterGaugeAxisRenderer; + options.legend.renderer = $.jqplot.MeterGaugeLegendRenderer; + options.legend.preDraw = true; + options.grid.background = options.grid.background || 'white'; + options.grid.drawGridlines = false; + options.grid.borderWidth = (options.grid.borderWidth != null) ? options.grid.borderWidth : 0; + options.grid.shadow = (options.grid.shadow != null) ? options.grid.shadow : false; + } + } + + // called with scope of plot + function postParseOptions(options) { + // + } + + $.jqplot.preInitHooks.push(preInit); + $.jqplot.postParseOptionsHooks.push(postParseOptions); + + $.jqplot.MeterGaugeTickRenderer = function() { + $.jqplot.AxisTickRenderer.call(this); + }; + + $.jqplot.MeterGaugeTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); + $.jqplot.MeterGaugeTickRenderer.prototype.constructor = $.jqplot.MeterGaugeTickRenderer; + +})(jQuery); + + diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.min.js new file mode 100644 index 0000000..ab882a5 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.meterGaugeRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){c.jqplot.MeterGaugeRenderer=function(){c.jqplot.LineRenderer.call(this)};c.jqplot.MeterGaugeRenderer.prototype=new c.jqplot.LineRenderer();c.jqplot.MeterGaugeRenderer.prototype.constructor=c.jqplot.MeterGaugeRenderer;c.jqplot.MeterGaugeRenderer.prototype.init=function(e){this.diameter=null;this.padding=null;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=4;this.background="#efefef";this.ringColor="#BBC6D0";this.needleColor="#C3D3E5";this.tickColor="#989898";this.ringWidth=null;this.min;this.max;this.ticks=[];this.showTicks=true;this.showTickLabels=true;this.label=null;this.labelHeightAdjust=0;this.labelPosition="inside";this.intervals=[];this.intervalColors=["#4bb2c5","#EAA228","#c5b47f","#579575","#839557","#958c12","#953579","#4b5de4","#d8b83f","#ff5800","#0085cc","#c747a3","#cddf54","#FBD178","#26B4E3","#bd70c7"];this.intervalInnerRadius=null;this.intervalOuterRadius=null;this.tickRenderer=c.jqplot.MeterGaugeTickRenderer;this.tickPositions=[1,2,2.5,5,10];this.tickSpacing=30;this.numberMinorTicks=null;this.hubRadius=null;this.tickPadding=null;this.needleThickness=null;this.needlePad=6;this.pegNeedle=true;this._type="meterGauge";c.extend(true,this,e);this.type=null;this.numberTicks=null;this.tickInterval=null;this.span=180;if(this.type=="circular"){this.semiCircular=false}else{if(this.type!="circular"){this.semiCircular=true}else{this.semiCircular=(this.span<=180)?true:false}}this._tickPoints=[];this._labelElem=null;this.startAngle=(90+(360-this.span)/2)*Math.PI/180;this.endAngle=(90-(360-this.span)/2)*Math.PI/180;this.setmin=!!(this.min==null);this.setmax=!!(this.max==null);if(this.intervals.length){if(this.intervals[0].length==null||this.intervals.length==1){for(var f=0;f<this.intervals.length;f++){this.intervals[f]=[this.intervals[f],this.intervals[f],this.intervalColors[f]]}}else{if(this.intervals[0].length==2){for(f=0;f<this.intervals.length;f++){this.intervals[f]=[this.intervals[f][0],this.intervals[f][1],this.intervalColors[f]]}}}}if(this.ticks.length){if(this.ticks[0].length==null||this.ticks[0].length==1){for(var f=0;f<this.ticks.length;f++){this.ticks[f]=[this.ticks[f],this.ticks[f]]}}this.min=(this.min==null)?this.ticks[0][0]:this.min;this.max=(this.max==null)?this.ticks[this.ticks.length-1][0]:this.max;this.setmin=false;this.setmax=false;this.numberTicks=this.ticks.length;this.tickInterval=this.ticks[1][0]-this.ticks[0][0];this.tickFactor=Math.floor(parseFloat((Math.log(this.tickInterval)/Math.log(10)).toFixed(11)));this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}if(!this.numberMinorTicks){this.numberMinorTicks=1}}else{if(this.intervals.length){this.min=(this.min==null)?0:this.min;this.setmin=false;if(this.max==null){if(this.intervals[this.intervals.length-1][0]>=this.data[0][1]){this.max=this.intervals[this.intervals.length-1][0];this.setmax=false}}else{this.setmax=false}}else{this.min=(this.min==null)?0:this.min;this.setmin=false;if(this.max==null){this.max=this.data[0][1]*1.25;this.setmax=true}else{this.setmax=false}}}};c.jqplot.MeterGaugeRenderer.prototype.setGridData=function(j){var f=[];var k=[];var e=this.startAngle;for(var h=0;h<this.data.length;h++){f.push(this.data[h][1]);k.push([this.data[h][0]]);if(h>0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h<f.length;h++){k[h][1]=f[h]*g}this.gridData=k};c.jqplot.MeterGaugeRenderer.prototype.makeGridData=function(j,k){var f=[];var l=[];var e=this.startAngle;for(var h=0;h<j.length;h++){f.push(j[h][1]);l.push([j[h][0]]);if(h>0){f[h]+=f[h-1]}}var g=Math.PI*2/f[f.length-1];for(var h=0;h<f.length;h++){l[h][1]=f[h]*g}return l};function b(j,f,g){var e;for(var h=j.length-1;h>=0;h--){e=f/(j[h]*Math.pow(10,g));if(e==4||e==5){return e-1}}return null}c.jqplot.MeterGaugeRenderer.prototype.draw=function(X,aC,ap){var aa;var aM=(ap!=undefined)?ap:{};var ai=0;var ah=0;var at=1;if(ap.legendInfo&&ap.legendInfo.placement=="inside"){var aI=ap.legendInfo;switch(aI.location){case"nw":ai=aI.width+aI.xoffset;break;case"w":ai=aI.width+aI.xoffset;break;case"sw":ai=aI.width+aI.xoffset;break;case"ne":ai=aI.width+aI.xoffset;at=-1;break;case"e":ai=aI.width+aI.xoffset;at=-1;break;case"se":ai=aI.width+aI.xoffset;at=-1;break;case"n":ah=aI.height+aI.yoffset;break;case"s":ah=aI.height+aI.yoffset;at=-1;break;default:break}}if(this.label){this._labelElem=c('<div class="jqplot-meterGauge-label" style="position:absolute;">'+this.label+"</div>");this.canvas._elem.after(this._labelElem)}var m=(aM.shadow!=undefined)?aM.shadow:this.shadow;var N=(aM.showLine!=undefined)?aM.showLine:this.showLine;var I=(aM.fill!=undefined)?aM.fill:this.fill;var K=X.canvas.width;var S=X.canvas.height;if(this.padding==null){this.padding=Math.round(Math.min(K,S)/30)}var Q=K-ai-2*this.padding;var ab=S-ah-2*this.padding;if(this.labelPosition=="bottom"&&this.label){ab-=this._labelElem.outerHeight(true)}var L=Math.min(Q,ab);var ad=L;if(!this.diameter){if(this.semiCircular){if(Q>=2*ab){if(!this.ringWidth){this.ringWidth=2*ab/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=2*(ab-2*this.innerPad)}else{if(!this.ringWidth){this.ringWidth=Q/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=this.ringWidth/2+this.needleThickness/2+this.needlePad;this.diameter=Q-2*this.innerPad-this.ringWidth-this.padding}this._center=[(K-at*ai)/2+at*ai,(S+at*ah-this.padding-this.ringWidth-this.innerPad)]}else{if(!this.ringWidth){this.ringWidth=ad/35}this.needleThickness=this.needleThickness||2+Math.pow(this.ringWidth,0.8);this.innerPad=0;this.diameter=ad-this.ringWidth;this._center=[(K-at*ai)/2+at*ai,(S-at*ah)/2+at*ah]}if(this._labelElem&&this.labelPosition=="bottom"){this._center[1]-=this._labelElem.outerHeight(true)}}this._radius=this.diameter/2;this.tickSpacing=6000/this.diameter;if(!this.hubRadius){this.hubRadius=this.diameter/18}this.shadowOffset=0.5+this.ringWidth/9;this.shadowWidth=this.ringWidth*1;this.tickPadding=3+Math.pow(this.diameter/20,0.7);this.tickOuterRadius=this._radius-this.ringWidth/2-this.tickPadding;this.tickLength=(this.showTicks)?this._radius/13:0;if(this.ticks.length==0){var A=this.max,aL=this.min,q=this.setmax,aG=this.setmin,au=(A-aL)*this.tickSpacing/this.span;var aw=Math.floor(parseFloat((Math.log(au)/Math.log(10)).toFixed(11)));var an=(au/Math.pow(10,aw));(an>2&&an<=2.5)?an=2.5:an=Math.ceil(an);var T=this.tickPositions;var aA,ak;for(aa=0;aa<T.length;aa++){if(an==T[aa]||aa&&T[aa-1]<an&&an<T[aa]){au=T[aa]*Math.pow(10,aw);aA=aa}}for(aa=0;aa<T.length;aa++){if(an==T[aa]||aa&&T[aa-1]<an&&an<T[aa]){au=T[aa]*Math.pow(10,aw);ak=Math.ceil((A-aL)/au)}}if(q&&aG){var aP=(aL>0)?aL-aL%au:aL-aL%au-au;if(!this.forceZero){var D=Math.min(aL-aP,0.8*au);var o=Math.floor(D/T[aA]);if(o>1){aP=aP+T[aA]*(o-1);if(parseInt(aP,10)!=aP&&parseInt(aP-T[aA],10)==aP-T[aA]){aP=aP-T[aA]}}}if(aL==aP){aL-=au}else{if(aL-aP>0.23*au){aL=aP}else{aL=aP-au;ak+=1}}ak+=1;var E=aL+(ak-1)*au;if(A>=E){E+=au;ak+=1}if(E-A<0.23*au){E+=au;ak+=1}this.max=A=E;this.min=aL;this.tickInterval=au;this.numberTicks=ak;var O;for(aa=0;aa<ak;aa++){O=parseFloat((aL+aa*au).toFixed(11));this.ticks.push([O,O])}this.max=this.ticks[ak-1][1];this.tickFactor=aw;this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}}else{if(q){var E=aL+(ak-1)*au;if(A>=E){A=E+au;ak+=1}else{A=E}this.tickInterval=this.tickInterval||au;this.numberTicks=this.numberTicks||ak;var O;for(aa=0;aa<this.numberTicks;aa++){O=parseFloat((aL+aa*this.tickInterval).toFixed(11));this.ticks.push([O,O])}this.max=this.ticks[this.numberTicks-1][1];this.tickFactor=aw;this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}}}if(!q&&!aG){var P=this.max-this.min;aw=Math.floor(parseFloat((Math.log(P)/Math.log(10)).toFixed(11)))-1;var aN=[5,6,4,7,3,8,9,10,2],V,C,av=0,M;if(P>1){var aJ=String(P);if(aJ.search(/\./)==-1){var aF=aJ.search(/0+$/);av=(aF>0)?aJ.length-aF-1:0}}M=P/Math.pow(10,av);for(aa=0;aa<aN.length;aa++){V=M/(aN[aa]-1);if(V==parseInt(V,10)){this.numberTicks=aN[aa];this.tickInterval=P/(this.numberTicks-1);this.tickFactor=aw+1;break}}var O;for(aa=0;aa<this.numberTicks;aa++){O=parseFloat((this.min+aa*this.tickInterval).toFixed(11));this.ticks.push([O,O])}this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor);if(!this.numberMinorTicks){this.numberMinorTicks=b(this.tickPositions,this.tickInterval,this.tickFactor-1)}if(!this.numberMinorTicks){this.numberMinorTicks=1;var aH=[4,5,3,6,2];for(aa=0;aa<5;aa++){var ao=this.tickInterval/aH[aa];if(ao==parseInt(ao,10)){this.numberMinorTicks=aH[aa]-1;break}}}}}var U=this._radius,aE=this.startAngle,k=this.endAngle,H=Math.PI,e=Math.PI/2;if(this.semiCircular){var z=Math.atan(this.innerPad/U),ac=this.outerStartAngle=aE-z,aB=this.outerEndAngle=k+z,B=this.hubStartAngle=aE-Math.atan(this.innerPad/this.hubRadius*2),af=this.hubEndAngle=k+Math.atan(this.innerPad/this.hubRadius*2);X.save();X.translate(this._center[0],this._center[1]);X.lineJoin="round";X.lineCap="round";X.save();X.beginPath();X.fillStyle=this.background;X.arc(0,0,U,ac,aB,false);X.closePath();X.fill();X.restore();var aj="rgba(0,0,0,"+this.shadowAlpha+")";X.save();for(var aa=0;aa<this.shadowDepth;aa++){X.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));X.beginPath();X.strokeStyle=aj;X.lineWidth=this.shadowWidth;X.arc(0,0,U,ac,aB,false);X.closePath();X.stroke()}X.restore();X.save();var az=parseInt((this.shadowDepth+1)/2,10);for(var aa=0;aa<az;aa++){X.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));X.beginPath();X.fillStyle=aj;X.arc(0,0,this.hubRadius,B,af,false);X.closePath();X.fill()}X.restore();X.save();X.beginPath();X.strokeStyle=this.ringColor;X.lineWidth=this.ringWidth;X.arc(0,0,U,ac,aB,false);X.closePath();X.stroke();X.restore();X.save();X.beginPath();X.fillStyle=this.ringColor;X.arc(0,0,this.hubRadius,B,af,false);X.closePath();X.fill();X.restore();if(this.showTicks){X.save();var f=this.tickOuterRadius,aq=this.tickLength,v=aq/2,F=this.numberMinorTicks,am=this.span*Math.PI/180/(this.ticks.length-1),p=am/(F+1);for(aa=0;aa<this.ticks.length;aa++){X.beginPath();X.lineWidth=1.5+this.diameter/360;X.strokeStyle=this.ringColor;var ae=am*aa+aE;X.moveTo(-f*Math.cos(am*aa+aE),f*Math.sin(am*aa+aE));X.lineTo(-(f-aq)*Math.cos(am*aa+aE),(f-aq)*Math.sin(am*aa+aE));this._tickPoints.push([(f-aq)*Math.cos(am*aa+aE)+this._center[0]+this.canvas._offsets.left,(f-aq)*Math.sin(am*aa+aE)+this._center[1]+this.canvas._offsets.top,am*aa+aE]);X.stroke();X.lineWidth=1+this.diameter/440;if(aa<this.ticks.length-1){for(var Y=1;Y<=F;Y++){X.beginPath();X.moveTo(-f*Math.cos(am*aa+p*Y+aE),f*Math.sin(am*aa+p*Y+aE));X.lineTo(-(f-v)*Math.cos(am*aa+p*Y+aE),(f-v)*Math.sin(am*aa+p*Y+aE));X.stroke()}}}X.restore()}if(this.showTickLabels){var J,W,T,aO,g,G,n=0;var an=this.tickPadding*(1-1/(this.diameter/80+1));for(aa=0;aa<this.ticks.length;aa++){J=c('<div class="jqplot-meterGauge-tick" style="position:absolute;">'+this.ticks[aa][1]+"</div>");this.canvas._elem.after(J);aO=J.outerWidth(true);g=J.outerHeight(true);W=this._tickPoints[aa][0]-aO*(this._tickPoints[aa][2]-Math.PI)/Math.PI-an*Math.cos(this._tickPoints[aa][2]);T=this._tickPoints[aa][1]-g/2+g/2*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5)+an/3*Math.pow(Math.abs((Math.sin(this._tickPoints[aa][2]))),0.5);J.css({left:W,top:T,color:this.tickColor});G=aO*Math.cos(this._tickPoints[aa][2])+g*Math.sin(Math.PI/2+this._tickPoints[aa][2]/2);n=(G>n)?G:n}}if(this.label&&this.labelPosition=="inside"){var W=this._center[0]+this.canvas._offsets.left;var an=this.tickPadding*(1-1/(this.diameter/80+1));var T=0.5*(this._center[1]+this.canvas._offsets.top-this.hubRadius)+0.5*(this._center[1]+this.canvas._offsets.top-this.tickOuterRadius+this.tickLength+an)+this.labelHeightAdjust;W-=this._labelElem.outerWidth(true)/2;T-=this._labelElem.outerHeight(true)/2;this._labelElem.css({left:W,top:T})}else{if(this.label&&this.labelPosition=="bottom"){var W=this._center[0]+this.canvas._offsets.left-this._labelElem.outerWidth(true)/2;var T=this._center[1]+this.canvas._offsets.top+this.innerPad+this.ringWidth+this.padding+this.labelHeightAdjust;this._labelElem.css({left:W,top:T})}}X.save();var ax=this.intervalInnerRadius||this.hubRadius*1.5;if(this.intervalOuterRadius==null){if(this.showTickLabels){var ag=(this.tickOuterRadius-this.tickLength-this.tickPadding-this.diameter/8)}else{var ag=(this.tickOuterRadius-this.tickLength-this.diameter/16)}}else{var ag=this.intervalOuterRadius}var P=this.max-this.min;var aD=this.intervals[this.intervals.length-1]-this.min;var y,Z,u=this.span*Math.PI/180;for(aa=0;aa<this.intervals.length;aa++){y=(aa==0)?aE:aE+(this.intervals[aa-1][0]-this.min)*u/P;if(y<0){y=0}Z=aE+(this.intervals[aa][0]-this.min)*u/P;if(Z<0){Z=0}X.beginPath();X.fillStyle=this.intervals[aa][2];X.arc(0,0,ax,y,Z,false);X.lineTo(ag*Math.cos(Z),ag*Math.sin(Z));X.arc(0,0,ag,Z,y,true);X.lineTo(ax*Math.cos(y),ax*Math.sin(y));X.closePath();X.fill()}X.restore();var ay=this.data[0][1];var R=this.max-this.min;if(this.pegNeedle){if(this.data[0][1]>this.max+R*3/this.span){ay=this.max+R*3/this.span}if(this.data[0][1]<this.min-R*3/this.span){ay=this.min-R*3/this.span}}var al=(ay-this.min)/R*this.span*Math.PI/180+this.startAngle;X.save();X.beginPath();X.fillStyle=this.ringColor;X.strokeStyle=this.ringColor;this.needleLength=(this.tickOuterRadius-this.tickLength)*0.85;this.needleThickness=(this.needleThickness<2)?2:this.needleThickness;var aK=this.needleThickness*0.4;var x=this.needleLength/10;var s=(this.needleThickness-aK)/10;var ar;for(var aa=0;aa<10;aa++){ar=this.needleThickness-aa*s;X.moveTo(x*aa*Math.cos(al),x*aa*Math.sin(al));X.lineWidth=ar;X.lineTo(x*(aa+1)*Math.cos(al),x*(aa+1)*Math.sin(al));X.stroke()}X.restore()}else{this._center=[(K-at*ai)/2+at*ai,(S-at*ah)/2+at*ah]}};c.jqplot.MeterGaugeAxisRenderer=function(){c.jqplot.LinearAxisRenderer.call(this)};c.jqplot.MeterGaugeAxisRenderer.prototype=new c.jqplot.LinearAxisRenderer();c.jqplot.MeterGaugeAxisRenderer.prototype.constructor=c.jqplot.MeterGaugeAxisRenderer;c.jqplot.MeterGaugeAxisRenderer.prototype.init=function(e){this.tickRenderer=c.jqplot.MeterGaugeTickRenderer;c.extend(true,this,e);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};c.jqplot.MeterGaugeLegendRenderer=function(){c.jqplot.TableLegendRenderer.call(this)};c.jqplot.MeterGaugeLegendRenderer.prototype=new c.jqplot.TableLegendRenderer();c.jqplot.MeterGaugeLegendRenderer.prototype.constructor=c.jqplot.MeterGaugeLegendRenderer;c.jqplot.MeterGaugeLegendRenderer.prototype.init=function(e){this.numberRows=null;this.numberColumns=null;c.extend(true,this,e)};c.jqplot.MeterGaugeLegendRenderer.prototype.draw=function(){if(this.show){var p=this._series;var x="position:absolute;";x+=(this.background)?"background:"+this.background+";":"";x+=(this.border)?"border:"+this.border+";":"";x+=(this.fontSize)?"font-size:"+this.fontSize+";":"";x+=(this.fontFamily)?"font-family:"+this.fontFamily+";":"";x+=(this.textColor)?"color:"+this.textColor+";":"";x+=(this.marginTop!=null)?"margin-top:"+this.marginTop+";":"";x+=(this.marginBottom!=null)?"margin-bottom:"+this.marginBottom+";":"";x+=(this.marginLeft!=null)?"margin-left:"+this.marginLeft+";":"";x+=(this.marginRight!=null)?"margin-right:"+this.marginRight+";":"";this._elem=c('<table class="jqplot-table-legend" style="'+x+'"></table>');var f=false,q=false,u,o;var w=p[0];if(w.show){var t=w.data;if(this.numberRows){u=this.numberRows;if(!this.numberColumns){o=Math.ceil(t.length/u)}else{o=this.numberColumns}}else{if(this.numberColumns){o=this.numberColumns;u=Math.ceil(t.length/this.numberColumns)}else{u=t.length;o=1}}var n,m,r,g,e,l,k,h;var v=0;for(n=0;n<u;n++){if(q){r=c('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem)}else{r=c('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem)}for(m=0;m<o;m++){if(v<t.length){l=this.labels[v]||t[v][0].toString();h=w.color;if(!q){if(n>0){f=true}else{f=false}}else{if(n==u-1){f=false}else{f=true}}k=(f)?this.rowSpacing:"0";g=c('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+k+';"><div><div class="jqplot-table-legend-swatch" style="border-color:'+h+';"></div></div></td>');e=c('<td class="jqplot-table-legend" style="padding-top:'+k+';"></td>');if(this.escapeHtml){e.text(l)}else{e.html(l)}if(q){e.prependTo(r);g.prependTo(r)}else{g.appendTo(r);e.appendTo(r)}f=true}v++}}}}return this._elem};function a(j,h,f){f=f||{};f.axesDefaults=f.axesDefaults||{};f.legend=f.legend||{};f.seriesDefaults=f.seriesDefaults||{};f.grid=f.grid||{};var e=false;if(f.seriesDefaults.renderer==c.jqplot.MeterGaugeRenderer){e=true}else{if(f.series){for(var g=0;g<f.series.length;g++){if(f.series[g].renderer==c.jqplot.MeterGaugeRenderer){e=true}}}}if(e){f.axesDefaults.renderer=c.jqplot.MeterGaugeAxisRenderer;f.legend.renderer=c.jqplot.MeterGaugeLegendRenderer;f.legend.preDraw=true;f.grid.background=f.grid.background||"white";f.grid.drawGridlines=false;f.grid.borderWidth=(f.grid.borderWidth!=null)?f.grid.borderWidth:0;f.grid.shadow=(f.grid.shadow!=null)?f.grid.shadow:false}}function d(e){}c.jqplot.preInitHooks.push(a);c.jqplot.postParseOptionsHooks.push(d);c.jqplot.MeterGaugeTickRenderer=function(){c.jqplot.AxisTickRenderer.call(this)};c.jqplot.MeterGaugeTickRenderer.prototype=new c.jqplot.AxisTickRenderer();c.jqplot.MeterGaugeTickRenderer.prototype.constructor=c.jqplot.MeterGaugeTickRenderer})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.js new file mode 100644 index 0000000..fa68a5f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.js @@ -0,0 +1,45 @@ +/** + * jqplot.jquerymobile plugin + * jQuery Mobile virtual event support. + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2011 Takashi Okamoto + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + */ +(function($) { + function postInit(target, data, options){ + this.bindCustomEvents = function() { + this.eventCanvas._elem.bind('vclick', {plot:this}, this.onClick); + this.eventCanvas._elem.bind('dblclick', {plot:this}, this.onDblClick); + this.eventCanvas._elem.bind('taphold', {plot:this}, this.onDblClick); + this.eventCanvas._elem.bind('vmousedown', {plot:this}, this.onMouseDown); + this.eventCanvas._elem.bind('vmousemove', {plot:this}, this.onMouseMove); + this.eventCanvas._elem.bind('mouseenter', {plot:this}, this.onMouseEnter); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, this.onMouseLeave); + if (this.captureRightClick) { + this.eventCanvas._elem.bind('vmouseup', {plot:this}, this.onRightClick); + this.eventCanvas._elem.get(0).oncontextmenu = function() { + return false; + }; + } + else { + this.eventCanvas._elem.bind('vmouseup', {plot:this}, this.onMouseUp); + } + }; + this.plugins.mobile = true; + } + $.jqplot.postInitHooks.push(postInit); +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.min.js new file mode 100644 index 0000000..17f4970 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.mobile.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(b){function a(e,d,c){this.bindCustomEvents=function(){this.eventCanvas._elem.bind("vclick",{plot:this},this.onClick);this.eventCanvas._elem.bind("dblclick",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("taphold",{plot:this},this.onDblClick);this.eventCanvas._elem.bind("vmousedown",{plot:this},this.onMouseDown);this.eventCanvas._elem.bind("vmousemove",{plot:this},this.onMouseMove);this.eventCanvas._elem.bind("mouseenter",{plot:this},this.onMouseEnter);this.eventCanvas._elem.bind("mouseleave",{plot:this},this.onMouseLeave);if(this.captureRightClick){this.eventCanvas._elem.bind("vmouseup",{plot:this},this.onRightClick);this.eventCanvas._elem.get(0).oncontextmenu=function(){return false}}else{this.eventCanvas._elem.bind("vmouseup",{plot:this},this.onMouseUp)}};this.plugins.mobile=true}b.jqplot.postInitHooks.push(a)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.js new file mode 100644 index 0000000..3cffbfb --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.js @@ -0,0 +1,373 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.OHLCRenderer + * jqPlot Plugin to draw Open Hi Low Close, Candlestick and Hi Low Close charts. + * + * To use this plugin, include the renderer js file in + * your source: + * + * > <script type="text/javascript" src="plugins/jqplot.ohlcRenderer.js"></script> + * + * You will most likely want to use a date axis renderer + * for the x axis also, so include the date axis render js file also: + * + * > <script type="text/javascript" src="plugins/jqplot.dateAxisRenderer.js"></script> + * + * Then you set the renderer in the series options on your plot: + * + * > series: [{renderer:$.jqplot.OHLCRenderer}] + * + * For OHLC and candlestick charts, data should be specified + * like so: + * + * > dat = [['07/06/2009',138.7,139.68,135.18,135.4], ['06/29/2009',143.46,144.66,139.79,140.02], ...] + * + * If the data array has only 4 values per point instead of 5, + * the renderer will create a Hi Low Close chart instead. In that case, + * data should be supplied like: + * + * > dat = [['07/06/2009',139.68,135.18,135.4], ['06/29/2009',144.66,139.79,140.02], ...] + * + * To generate a candlestick chart instead of an OHLC chart, + * set the "candlestick" option to true: + * + * > series: [{renderer:$.jqplot.OHLCRenderer, rendererOptions:{candleStick:true}}], + * + */ + $.jqplot.OHLCRenderer = function(){ + // subclass line renderer to make use of some of its methods. + $.jqplot.LineRenderer.call(this); + // prop: candleStick + // true to render chart as candleStick. + // Must have an open price, cannot be a hlc chart. + this.candleStick = false; + // prop: tickLength + // length of the line in pixels indicating open and close price. + // Default will auto calculate based on plot width and + // number of points displayed. + this.tickLength = 'auto'; + // prop: bodyWidth + // width of the candlestick body in pixels. Default will auto calculate + // based on plot width and number of candlesticks displayed. + this.bodyWidth = 'auto'; + // prop: openColor + // color of the open price tick mark. Default is series color. + this.openColor = null; + // prop: closeColor + // color of the close price tick mark. Default is series color. + this.closeColor = null; + // prop: wickColor + // color of the hi-lo line thorugh the candlestick body. + // Default is the series color. + this.wickColor = null; + // prop: fillUpBody + // true to render an "up" day (close price greater than open price) + // with a filled candlestick body. + this.fillUpBody = false; + // prop: fillDownBody + // true to render a "down" day (close price lower than open price) + // with a filled candlestick body. + this.fillDownBody = true; + // prop: upBodyColor + // Color of candlestick body of an "up" day. Default is series color. + this.upBodyColor = null; + // prop: downBodyColor + // Color of candlestick body on a "down" day. Default is series color. + this.downBodyColor = null; + // prop: hlc + // true if is a hi-low-close chart (no open price). + // This is determined automatically from the series data. + this.hlc = false; + // prop: lineWidth + // Width of the hi-low line and open/close ticks. + // Must be set in the rendererOptions for the series. + this.lineWidth = 1.5; + this._tickLength; + this._bodyWidth; + }; + + $.jqplot.OHLCRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.OHLCRenderer.prototype.constructor = $.jqplot.OHLCRenderer; + + // called with scope of series. + $.jqplot.OHLCRenderer.prototype.init = function(options) { + options = options || {}; + // lineWidth has to be set on the series, changes in renderer + // constructor have no effect. set the default here + // if no renderer option for lineWidth is specified. + this.lineWidth = options.lineWidth || 1.5; + $.jqplot.LineRenderer.prototype.init.call(this, options); + this._type = 'ohlc'; + // set the yaxis data bounds here to account for hi and low values + var db = this._yaxis._dataBounds; + var d = this._plotData; + // if data points have less than 5 values, force a hlc chart. + if (d[0].length < 5) { + this.renderer.hlc = true; + + for (var j=0; j<d.length; j++) { + if (d[j][2] < db.min || db.min == null) { + db.min = d[j][2]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + else { + for (var j=0; j<d.length; j++) { + if (d[j][3] < db.min || db.min == null) { + db.min = d[j][3]; + } + if (d[j][2] > db.max || db.max == null) { + db.max = d[j][2]; + } + } + } + + }; + + // called within scope of series. + $.jqplot.OHLCRenderer.prototype.draw = function(ctx, gd, options) { + var d = this.data; + var xmin = this._xaxis.min; + var xmax = this._xaxis.max; + // index of last value below range of plot. + var xminidx = 0; + // index of first value above range of plot. + var xmaxidx = d.length; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var i, prevColor, ops, b, h, w, a, points; + var o; + var r = this.renderer; + var opts = (options != undefined) ? options : {}; + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var fillAndStroke = (opts.fillAndStroke != undefined) ? opts.fillAndStroke : this.fillAndStroke; + r.bodyWidth = (opts.bodyWidth != undefined) ? opts.bodyWidth : r.bodyWidth; + r.tickLength = (opts.tickLength != undefined) ? opts.tickLength : r.tickLength; + ctx.save(); + if (this.show) { + var x, open, hi, low, close; + // need to get widths based on number of points shown, + // not on total number of points. Use the results + // to speed up drawing in next step. + for (var i=0; i<d.length; i++) { + if (d[i][0] < xmin) { + xminidx = i; + } + else if (d[i][0] < xmax) { + xmaxidx = i+1; + } + } + + var dwidth = this.gridData[xmaxidx-1][0] - this.gridData[xminidx][0]; + var nvisiblePoints = xmaxidx - xminidx; + try { + var dinterval = Math.abs(this._xaxis.series_u2p(parseInt(this._xaxis._intervalStats[0].sortedIntervals[0].interval, 10)) - this._xaxis.series_u2p(0)); + } + + catch (e) { + var dinterval = dwidth / nvisiblePoints; + } + + if (r.candleStick) { + if (typeof(r.bodyWidth) == 'number') { + r._bodyWidth = r.bodyWidth; + } + else { + r._bodyWidth = Math.min(20, dinterval/1.65); + } + } + else { + if (typeof(r.tickLength) == 'number') { + r._tickLength = r.tickLength; + } + else { + r._tickLength = Math.min(10, dinterval/3.5); + } + } + + for (var i=xminidx; i<xmaxidx; i++) { + x = xp(d[i][0]); + if (r.hlc) { + open = null; + hi = yp(d[i][1]); + low = yp(d[i][2]); + close = yp(d[i][3]); + } + else { + open = yp(d[i][1]); + hi = yp(d[i][2]); + low = yp(d[i][3]); + close = yp(d[i][4]); + } + o = {}; + if (r.candleStick && !r.hlc) { + w = r._bodyWidth; + a = x - w/2; + // draw candle + // determine if candle up or down + // up, remember grid coordinates increase downward + if (close < open) { + // draw wick + if (r.wickColor) { + o.color = r.wickColor; + } + else if (r.downBodyColor) { + o.color = r.upBodyColor; + } + ops = $.extend(true, {}, opts, o); + r.shapeRenderer.draw(ctx, [[x, hi], [x, close]], ops); + r.shapeRenderer.draw(ctx, [[x, open], [x, low]], ops); + o = {}; + b = close; + h = open - close; + // if color specified, use it + if (r.fillUpBody) { + o.fillRect = true; + } + else { + o.strokeRect = true; + w = w - this.lineWidth; + a = x - w/2; + } + if (r.upBodyColor) { + o.color = r.upBodyColor; + o.fillStyle = r.upBodyColor; + } + points = [a, b, w, h]; + } + // down + else if (close > open) { + // draw wick + if (r.wickColor) { + o.color = r.wickColor; + } + else if (r.downBodyColor) { + o.color = r.downBodyColor; + } + ops = $.extend(true, {}, opts, o); + r.shapeRenderer.draw(ctx, [[x, hi], [x, open]], ops); + r.shapeRenderer.draw(ctx, [[x, close], [x, low]], ops); + + o = {}; + + b = open; + h = close - open; + // if color specified, use it + if (r.fillDownBody) { + o.fillRect = true; + } + else { + o.strokeRect = true; + w = w - this.lineWidth; + a = x - w/2; + } + if (r.downBodyColor) { + o.color = r.downBodyColor; + o.fillStyle = r.downBodyColor; + } + points = [a, b, w, h]; + } + // even, open = close + else { + // draw wick + if (r.wickColor) { + o.color = r.wickColor; + } + ops = $.extend(true, {}, opts, o); + r.shapeRenderer.draw(ctx, [[x, hi], [x, low]], ops); + o = {}; + o.fillRect = false; + o.strokeRect = false; + a = [x - w/2, open]; + b = [x + w/2, close]; + w = null; + h = null; + points = [a, b]; + } + ops = $.extend(true, {}, opts, o); + r.shapeRenderer.draw(ctx, points, ops); + } + else { + prevColor = opts.color; + if (r.openColor) { + opts.color = r.openColor; + } + // draw open tick + if (!r.hlc) { + r.shapeRenderer.draw(ctx, [[x-r._tickLength, open], [x, open]], opts); + } + opts.color = prevColor; + // draw wick + if (r.wickColor) { + opts.color = r.wickColor; + } + r.shapeRenderer.draw(ctx, [[x, hi], [x, low]], opts); + opts.color = prevColor; + // draw close tick + if (r.closeColor) { + opts.color = r.closeColor; + } + r.shapeRenderer.draw(ctx, [[x, close], [x+r._tickLength, close]], opts); + opts.color = prevColor; + } + } + } + + ctx.restore(); + }; + + $.jqplot.OHLCRenderer.prototype.drawShadow = function(ctx, gd, options) { + // This is a no-op, shadows drawn with lines. + }; + + // called with scope of plot. + $.jqplot.OHLCRenderer.checkOptions = function(target, data, options) { + // provide some sensible highlighter options by default + // These aren't good for hlc, only for ohlc or candlestick + if (!options.highlighter) { + options.highlighter = { + showMarker:false, + tooltipAxes: 'y', + yvalues: 4, + formatString:'<table class="jqplot-highlighter"><tr><td>date:</td><td>%s</td></tr><tr><td>open:</td><td>%s</td></tr><tr><td>hi:</td><td>%s</td></tr><tr><td>low:</td><td>%s</td></tr><tr><td>close:</td><td>%s</td></tr></table>' + }; + } + }; + + //$.jqplot.preInitHooks.push($.jqplot.OHLCRenderer.checkOptions); + +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.min.js new file mode 100644 index 0000000..94faa96 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.ohlcRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.OHLCRenderer=function(){a.jqplot.LineRenderer.call(this);this.candleStick=false;this.tickLength="auto";this.bodyWidth="auto";this.openColor=null;this.closeColor=null;this.wickColor=null;this.fillUpBody=false;this.fillDownBody=true;this.upBodyColor=null;this.downBodyColor=null;this.hlc=false;this.lineWidth=1.5;this._tickLength;this._bodyWidth};a.jqplot.OHLCRenderer.prototype=new a.jqplot.LineRenderer();a.jqplot.OHLCRenderer.prototype.constructor=a.jqplot.OHLCRenderer;a.jqplot.OHLCRenderer.prototype.init=function(e){e=e||{};this.lineWidth=e.lineWidth||1.5;a.jqplot.LineRenderer.prototype.init.call(this,e);this._type="ohlc";var b=this._yaxis._dataBounds;var f=this._plotData;if(f[0].length<5){this.renderer.hlc=true;for(var c=0;c<f.length;c++){if(f[c][2]<b.min||b.min==null){b.min=f[c][2]}if(f[c][1]>b.max||b.max==null){b.max=f[c][1]}}}else{for(var c=0;c<f.length;c++){if(f[c][3]<b.min||b.min==null){b.min=f[c][3]}if(f[c][2]>b.max||b.max==null){b.max=f[c][2]}}}};a.jqplot.OHLCRenderer.prototype.draw=function(A,N,j){var J=this.data;var v=this._xaxis.min;var z=this._xaxis.max;var l=0;var K=J.length;var p=this._xaxis.series_u2p;var G=this._yaxis.series_u2p;var D,E,f,M,F,n,O,C;var y;var u=this.renderer;var s=(j!=undefined)?j:{};var k=(s.shadow!=undefined)?s.shadow:this.shadow;var B=(s.fill!=undefined)?s.fill:this.fill;var c=(s.fillAndStroke!=undefined)?s.fillAndStroke:this.fillAndStroke;u.bodyWidth=(s.bodyWidth!=undefined)?s.bodyWidth:u.bodyWidth;u.tickLength=(s.tickLength!=undefined)?s.tickLength:u.tickLength;A.save();if(this.show){var m,q,g,Q,t;for(var D=0;D<J.length;D++){if(J[D][0]<v){l=D}else{if(J[D][0]<z){K=D+1}}}var I=this.gridData[K-1][0]-this.gridData[l][0];var L=K-l;try{var P=Math.abs(this._xaxis.series_u2p(parseInt(this._xaxis._intervalStats[0].sortedIntervals[0].interval,10))-this._xaxis.series_u2p(0))}catch(H){var P=I/L}if(u.candleStick){if(typeof(u.bodyWidth)=="number"){u._bodyWidth=u.bodyWidth}else{u._bodyWidth=Math.min(20,P/1.65)}}else{if(typeof(u.tickLength)=="number"){u._tickLength=u.tickLength}else{u._tickLength=Math.min(10,P/3.5)}}for(var D=l;D<K;D++){m=p(J[D][0]);if(u.hlc){q=null;g=G(J[D][1]);Q=G(J[D][2]);t=G(J[D][3])}else{q=G(J[D][1]);g=G(J[D][2]);Q=G(J[D][3]);t=G(J[D][4])}y={};if(u.candleStick&&!u.hlc){n=u._bodyWidth;O=m-n/2;if(t<q){if(u.wickColor){y.color=u.wickColor}else{if(u.downBodyColor){y.color=u.upBodyColor}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,t]],f);u.shapeRenderer.draw(A,[[m,q],[m,Q]],f);y={};M=t;F=q-t;if(u.fillUpBody){y.fillRect=true}else{y.strokeRect=true;n=n-this.lineWidth;O=m-n/2}if(u.upBodyColor){y.color=u.upBodyColor;y.fillStyle=u.upBodyColor}C=[O,M,n,F]}else{if(t>q){if(u.wickColor){y.color=u.wickColor}else{if(u.downBodyColor){y.color=u.downBodyColor}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,q]],f);u.shapeRenderer.draw(A,[[m,t],[m,Q]],f);y={};M=q;F=t-q;if(u.fillDownBody){y.fillRect=true}else{y.strokeRect=true;n=n-this.lineWidth;O=m-n/2}if(u.downBodyColor){y.color=u.downBodyColor;y.fillStyle=u.downBodyColor}C=[O,M,n,F]}else{if(u.wickColor){y.color=u.wickColor}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,[[m,g],[m,Q]],f);y={};y.fillRect=false;y.strokeRect=false;O=[m-n/2,q];M=[m+n/2,t];n=null;F=null;C=[O,M]}}f=a.extend(true,{},s,y);u.shapeRenderer.draw(A,C,f)}else{E=s.color;if(u.openColor){s.color=u.openColor}if(!u.hlc){u.shapeRenderer.draw(A,[[m-u._tickLength,q],[m,q]],s)}s.color=E;if(u.wickColor){s.color=u.wickColor}u.shapeRenderer.draw(A,[[m,g],[m,Q]],s);s.color=E;if(u.closeColor){s.color=u.closeColor}u.shapeRenderer.draw(A,[[m,t],[m+u._tickLength,t]],s);s.color=E}}}A.restore()};a.jqplot.OHLCRenderer.prototype.drawShadow=function(b,d,c){};a.jqplot.OHLCRenderer.checkOptions=function(d,c,b){if(!b.highlighter){b.highlighter={showMarker:false,tooltipAxes:"y",yvalues:4,formatString:'<table class="jqplot-highlighter"><tr><td>date:</td><td>%s</td></tr><tr><td>open:</td><td>%s</td></tr><tr><td>hi:</td><td>%s</td></tr><tr><td>low:</td><td>%s</td></tr><tr><td>close:</td><td>%s</td></tr></table>'}}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.js new file mode 100644 index 0000000..1d508bd --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.js @@ -0,0 +1,904 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + /** + * Class: $.jqplot.PieRenderer + * Plugin renderer to draw a pie chart. + * x values, if present, will be used as slice labels. + * y values give slice size. + * + * To use this renderer, you need to include the + * pie renderer plugin, for example: + * + * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script> + * + * Properties described here are passed into the $.jqplot function + * as options on the series renderer. For example: + * + * > plot2 = $.jqplot('chart2', [s1, s2], { + * > seriesDefaults: { + * > renderer:$.jqplot.PieRenderer, + * > rendererOptions:{ + * > sliceMargin: 2, + * > startAngle: -90 + * > } + * > } + * > }); + * + * A pie plot will trigger events on the plot target + * according to user interaction. All events return the event object, + * the series index, the point (slice) index, and the point data for + * the appropriate slice. + * + * 'jqplotDataMouseOver' - triggered when user mouseing over a slice. + * 'jqplotDataHighlight' - triggered the first time user mouses over a slice, + * if highlighting is enabled. + * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of + * a highlighted slice. + * 'jqplotDataClick' - triggered when the user clicks on a slice. + * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if + * the "captureRightClick" option is set to true on the plot. + */ + $.jqplot.PieRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer; + + // called with scope of a series + $.jqplot.PieRenderer.prototype.init = function(options, plot) { + // Group: Properties + // + // prop: diameter + // Outer diameter of the pie, auto computed by default + this.diameter = null; + // prop: padding + // padding between the pie and plot edges, legend, etc. + this.padding = 20; + // prop: sliceMargin + // angular spacing between pie slices in degrees. + this.sliceMargin = 0; + // prop: fill + // true or false, whether to fil the slices. + this.fill = true; + // prop: shadowOffset + // offset of the shadow from the slice and offset of + // each succesive stroke of the shadow from the last. + this.shadowOffset = 2; + // prop: shadowAlpha + // transparency of the shadow (0 = transparent, 1 = opaque) + this.shadowAlpha = 0.07; + // prop: shadowDepth + // number of strokes to apply to the shadow, + // each stroke offset shadowOffset from the last. + this.shadowDepth = 5; + // prop: highlightMouseOver + // True to highlight slice when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a slice. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a slice. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // an array of colors to use when highlighting a slice. + this.highlightColors = []; + // prop: dataLabels + // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. + // Defaults to percentage of each pie slice. + this.dataLabels = 'percent'; + // prop: showDataLabels + // true to show data labels on slices. + this.showDataLabels = false; + // prop: dataLabelFormatString + // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. + this.dataLabelFormatString = null; + // prop: dataLabelThreshold + // Threshhold in percentage (0-100) of pie area, below which no label will be displayed. + // This applies to all label types, not just to percentage labels. + this.dataLabelThreshold = 3; + // prop: dataLabelPositionFactor + // A Multiplier (0-1) of the pie radius which controls position of label on slice. + // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie. + this.dataLabelPositionFactor = 0.52; + // prop: dataLabelNudge + // Number of pixels to slide the label away from (+) or toward (-) the center of the pie. + this.dataLabelNudge = 2; + // prop: dataLabelCenterOn + // True to center the data label at its position. + // False to set the inside facing edge of the label at its position. + this.dataLabelCenterOn = true; + // prop: startAngle + // Angle to start drawing pie in degrees. + // According to orientation of canvas coordinate system: + // 0 = on the positive x axis + // -90 = on the positive y axis. + // 90 = on the negaive y axis. + // 180 or - 180 = on the negative x axis. + this.startAngle = 0; + this.tickRenderer = $.jqplot.PieTickRenderer; + // Used as check for conditions where pie shouldn't be drawn. + this._drawData = true; + this._type = 'pie'; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + $.extend(true, this, options); + + if (this.sliceMargin < 0) { + this.sliceMargin = 0; + } + + this._diameter = null; + this._radius = null; + // array of [start,end] angles arrays, one for each slice. In radians. + this._sliceAngles = []; + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + + // set highlight colors if none provided + if (this.highlightColors.length == 0) { + for (var i=0; i<this.seriesColors.length; i++){ + var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); + var newrgb = [rgba[0], rgba[1], rgba[2]]; + var sum = newrgb[0] + newrgb[1] + newrgb[2]; + for (var j=0; j<3; j++) { + // when darkening, lowest color component can be is 60. + newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); + } + } + + this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors); + + plot.postParseOptionsHooks.addOnce(postParseOptions); + plot.postInitHooks.addOnce(postInit); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); + plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); + plot.eventListenerHooks.addOnce('jqplotClick', handleClick); + plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); + plot.postDrawHooks.addOnce(postPlotDraw); + }; + + $.jqplot.PieRenderer.prototype.setGridData = function(plot) { + // set gridData property. This will hold angle in radians of each data point. + var stack = []; + var td = []; + var sa = this.startAngle/180*Math.PI; + var tot = 0; + // don't know if we have any valid data yet, so set plot to not draw. + this._drawData = false; + for (var i=0; i<this.data.length; i++){ + if (this.data[i][1] != 0) { + // we have data, O.K. to draw. + this._drawData = true; + } + stack.push(this.data[i][1]); + td.push([this.data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + tot += this.data[i][1]; + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + td[i][2] = this.data[i][1]/tot; + } + this.gridData = td; + }; + + $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) { + var stack = []; + var td = []; + var tot = 0; + var sa = this.startAngle/180*Math.PI; + // don't know if we have any valid data yet, so set plot to not draw. + this._drawData = false; + for (var i=0; i<data.length; i++){ + if (this.data[i][1] != 0) { + // we have data, O.K. to draw. + this._drawData = true; + } + stack.push(data[i][1]); + td.push([data[i][0]]); + if (i>0) { + stack[i] += stack[i-1]; + } + tot += data[i][1]; + } + var fact = Math.PI*2/stack[stack.length - 1]; + + for (var i=0; i<stack.length; i++) { + td[i][1] = stack[i] * fact; + td[i][2] = data[i][1]/tot; + } + return td; + }; + + function calcRadiusAdjustment(ang) { + return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0); + } + + function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) { + var rprime = 0; + var ang = ang2 - ang1; + var absang = Math.abs(ang); + var sm = sliceMargin; + if (fill == false) { + sm += lineWidth; + } + + if (sm > 0 && absang > 0.01 && absang < 6.282) { + rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang); + } + + return rprime; + } + + $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) { + if (this._drawData) { + var r = this._radius; + var fill = this.fill; + var lineWidth = this.lineWidth; + var sm = this.sliceMargin; + if (this.fill == false) { + sm += this.lineWidth; + } + ctx.save(); + ctx.translate(this._center[0], this._center[1]); + + var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); + + var transx = rprime * Math.cos((ang1 + ang2) / 2.0); + var transy = rprime * Math.sin((ang1 + ang2) / 2.0); + + if ((ang2 - ang1) <= Math.PI) { + r -= rprime; + } + else { + r += rprime; + } + + ctx.translate(transx, transy); + + if (isShadow) { + for (var i=0, l=this.shadowDepth; i<l; i++) { + ctx.save(); + ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); + doDraw(r); + } + for (var i=0, l=this.shadowDepth; i<l; i++) { + ctx.restore(); + } + } + + else { + doDraw(r); + } + ctx.restore(); + } + + function doDraw (rad) { + // Fix for IE and Chrome that can't seem to draw circles correctly. + // ang2 should always be <= 2 pi since that is the way the data is converted. + // 2Pi = 6.2831853, Pi = 3.1415927 + if (ang2 > 6.282 + this.startAngle) { + ang2 = 6.282 + this.startAngle; + if (ang1 > ang2) { + ang1 = 6.281 + this.startAngle; + } + } + // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids + // ugly line on unfilled pies. + if (ang1 >= ang2) { + return; + } + + ctx.beginPath(); + ctx.fillStyle = color; + ctx.strokeStyle = color; + ctx.lineWidth = lineWidth; + ctx.arc(0, 0, rad, ang1, ang2, false); + ctx.lineTo(0,0); + ctx.closePath(); + + if (fill) { + ctx.fill(); + } + else { + ctx.stroke(); + } + } + }; + + // called with scope of series + $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) { + var i; + var opts = (options != undefined) ? options : {}; + // offset and direction of offset due to legend placement + var offx = 0; + var offy = 0; + var trans = 1; + var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); + if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { + var li = options.legendInfo; + switch (li.location) { + case 'nw': + offx = li.width + li.xoffset; + break; + case 'w': + offx = li.width + li.xoffset; + break; + case 'sw': + offx = li.width + li.xoffset; + break; + case 'ne': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'e': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'se': + offx = li.width + li.xoffset; + trans = -1; + break; + case 'n': + offy = li.height + li.yoffset; + break; + case 's': + offy = li.height + li.yoffset; + trans = -1; + break; + default: + break; + } + } + + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var cw = ctx.canvas.width; + var ch = ctx.canvas.height; + var w = cw - offx - 2 * this.padding; + var h = ch - offy - 2 * this.padding; + var mindim = Math.min(w,h); + var d = mindim; + + // Fixes issue #272. Thanks hugwijst! + // reset slice angles array. + this._sliceAngles = []; + + var sm = this.sliceMargin; + if (this.fill == false) { + sm += this.lineWidth; + } + + var rprime; + var maxrprime = 0; + + var ang, ang1, ang2, shadowColor; + var sa = this.startAngle / 180 * Math.PI; + + // have to pre-draw shadows, so loop throgh here and calculate some values also. + for (var i=0, l=gd.length; i<l; i++) { + ang1 = (i == 0) ? sa : gd[i-1][1] + sa; + ang2 = gd[i][1] + sa; + + this._sliceAngles.push([ang1, ang2]); + + rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); + + if (Math.abs(ang2-ang1) > Math.PI) { + maxrprime = Math.max(rprime, maxrprime); + } + } + + if (this.diameter != null && this.diameter > 0) { + this._diameter = this.diameter - 2*maxrprime; + } + else { + this._diameter = d - 2*maxrprime; + } + + // Need to check for undersized pie. This can happen if + // plot area too small and legend is too big. + if (this._diameter < 6) { + $.jqplot.log('Diameter of pie too small, not rendering.'); + return; + } + + var r = this._radius = this._diameter/2; + + this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)]; + + if (this.shadow) { + for (var i=0, l=gd.length; i<l; i++) { + shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; + this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true); + } + } + + for (var i=0; i<gd.length; i++) { + + this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false); + + if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) { + var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label; + + if (this.dataLabels == 'label') { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, gd[i][0]); + } + else if (this.dataLabels == 'value') { + fstr = this.dataLabelFormatString || '%d'; + label = $.jqplot.sprintf(fstr, this.data[i][1]); + } + else if (this.dataLabels == 'percent') { + fstr = this.dataLabelFormatString || '%d%%'; + label = $.jqplot.sprintf(fstr, gd[i][2]*100); + } + else if (this.dataLabels.constructor == Array) { + fstr = this.dataLabelFormatString || '%s'; + label = $.jqplot.sprintf(fstr, this.dataLabels[i]); + } + + var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; + + var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left; + var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top; + + var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem); + if (this.dataLabelCenterOn) { + x -= labelelem.width()/2; + y -= labelelem.height()/2; + } + else { + x -= labelelem.width() * Math.sin(avgang/2); + y -= labelelem.height()/2; + } + x = Math.round(x); + y = Math.round(y); + labelelem.css({left: x, top: y}); + } + } + }; + + $.jqplot.PieAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer; + + + // There are no traditional axes on a pie chart. We just need to provide + // dummy objects with properties so the plot will render. + // called with scope of axis object. + $.jqplot.PieAxisRenderer.prototype.init = function(options){ + // + this.tickRenderer = $.jqplot.PieTickRenderer; + $.extend(true, this, options); + // I don't think I'm going to need _dataBounds here. + // have to go Axis scaling in a way to fit chart onto plot area + // and provide u2p and p2u functionality for mouse cursor, etc. + // for convienence set _dataBounds to 0 and 100 and + // set min/max to 0 and 100. + this._dataBounds = {min:0, max:100}; + this.min = 0; + this.max = 100; + this.showTicks = false; + this.ticks = []; + this.showMark = false; + this.show = false; + }; + + + + + $.jqplot.PieLegendRenderer = function(){ + $.jqplot.TableLegendRenderer.call(this); + }; + + $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); + $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer; + + /** + * Class: $.jqplot.PieLegendRenderer + * Legend Renderer specific to pie plots. Set by default + * when user creates a pie plot. + */ + $.jqplot.PieLegendRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: numberRows + // Maximum number of rows in the legend. 0 or null for unlimited. + this.numberRows = null; + // prop: numberColumns + // Maximum number of columns in the legend. 0 or null for unlimited. + this.numberColumns = null; + $.extend(true, this, options); + }; + + // called with context of legend + $.jqplot.PieLegendRenderer.prototype.draw = function() { + var legend = this; + if (this.show) { + var series = this._series; + + + this._elem = $(document.createElement('table')); + this._elem.addClass('jqplot-table-legend'); + + var ss = {position:'absolute'}; + if (this.background) { + ss['background'] = this.background; + } + if (this.border) { + ss['border'] = this.border; + } + if (this.fontSize) { + ss['fontSize'] = this.fontSize; + } + if (this.fontFamily) { + ss['fontFamily'] = this.fontFamily; + } + if (this.textColor) { + ss['textColor'] = this.textColor; + } + if (this.marginTop != null) { + ss['marginTop'] = this.marginTop; + } + if (this.marginBottom != null) { + ss['marginBottom'] = this.marginBottom; + } + if (this.marginLeft != null) { + ss['marginLeft'] = this.marginLeft; + } + if (this.marginRight != null) { + ss['marginRight'] = this.marginRight; + } + + this._elem.css(ss); + + // Pie charts legends don't go by number of series, but by number of data points + // in the series. Refactor things here for that. + + var pad = false, + reverse = false, + nr, + nc; + var s = series[0]; + var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); + + if (s.show) { + var pd = s.data; + if (this.numberRows) { + nr = this.numberRows; + if (!this.numberColumns){ + nc = Math.ceil(pd.length/nr); + } + else{ + nc = this.numberColumns; + } + } + else if (this.numberColumns) { + nc = this.numberColumns; + nr = Math.ceil(pd.length/this.numberColumns); + } + else { + nr = pd.length; + nc = 1; + } + + var i, j; + var tr, td1, td2; + var lt, rs, color; + var idx = 0; + var div0, div1; + + for (i=0; i<nr; i++) { + tr = $(document.createElement('tr')); + tr.addClass('jqplot-table-legend'); + + if (reverse){ + tr.prependTo(this._elem); + } + + else{ + tr.appendTo(this._elem); + } + + for (j=0; j<nc; j++) { + if (idx < pd.length){ + lt = this.labels[idx] || pd[idx][0].toString(); + color = colorGenerator.next(); + if (!reverse){ + if (i>0){ + pad = true; + } + else{ + pad = false; + } + } + else{ + if (i == nr -1){ + pad = false; + } + else{ + pad = true; + } + } + rs = (pad) ? this.rowSpacing : '0'; + + + + td1 = $(document.createElement('td')); + td1.addClass('jqplot-table-legend jqplot-table-legend-swatch'); + td1.css({textAlign: 'center', paddingTop: rs}); + + div0 = $(document.createElement('div')); + div0.addClass('jqplot-table-legend-swatch-outline'); + div1 = $(document.createElement('div')); + div1.addClass('jqplot-table-legend-swatch'); + div1.css({backgroundColor: color, borderColor: color}); + td1.append(div0.append(div1)); + + td2 = $(document.createElement('td')); + td2.addClass('jqplot-table-legend jqplot-table-legend-label'); + td2.css('paddingTop', rs); + + if (this.escapeHtml){ + td2.text(lt); + } + else { + td2.html(lt); + } + if (reverse) { + td2.prependTo(tr); + td1.prependTo(tr); + } + else { + td1.appendTo(tr); + td2.appendTo(tr); + } + pad = true; + } + idx++; + } + } + } + } + return this._elem; + }; + + $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + plot.target.trigger('jqplotDataMouseOver', ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + plot.target.trigger('jqplotDataHighlight', ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + }; + + + // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + // only set these if there is a pie series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.PieRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.PieAxisRenderer; + options.legend.renderer = $.jqplot.PieLegendRenderer; + options.legend.preDraw = true; + options.seriesDefaults.pointLabels = {show: false}; + } + } + + function postInit(target, data, options) { + for (var i=0; i<this.series.length; i++) { + if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) { + // don't allow mouseover and mousedown at same time. + if (this.series[i].highlightMouseOver) { + this.series[i].highlightMouseDown = false; + } + } + } + } + + // called with scope of plot + function postParseOptions(options) { + for (var i=0; i<this.series.length; i++) { + this.series[i].seriesColors = this.seriesColors; + this.series[i].colorGenerator = $.jqplot.colorGenerator; + } + } + + function highlight (plot, sidx, pidx) { + var s = plot.series[sidx]; + var canvas = plot.plugins.pieRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.pieRenderer.highlightedSeriesIndex = sidx; + s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false); + } + + function unhighlight (plot) { + var canvas = plot.plugins.pieRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.pieRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + } + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, ins[0], ins[1]); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { + var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + } + + function handleClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt = jQuery.Event('jqplotDataClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + function handleRightClick(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; + if (idx != null && plot.series[idx].highlightMouseDown) { + unhighlight(plot); + } + var evt = jQuery.Event('jqplotDataRightClick'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) { + this.plugins.pieRenderer.highlightCanvas.resetCanvas(); + this.plugins.pieRenderer.highlightCanvas = null; + } + + this.plugins.pieRenderer = {highlightedSeriesIndex:null}; + this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + + // do we have any data labels? if so, put highlight canvas before those + var labels = $(this.targetId+' .jqplot-data-label'); + if (labels.length) { + $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); + } + // else put highlight canvas before event canvas. + else { + this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); + } + + var hctx = this.plugins.pieRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + $.jqplot.preInitHooks.push(preInit); + + $.jqplot.PieTickRenderer = function() { + $.jqplot.AxisTickRenderer.call(this); + }; + + $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); + $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer; + +})(jQuery); + + \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.min.js new file mode 100644 index 0000000..5f08e61 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pieRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.PieRenderer=function(){e.jqplot.LineRenderer.call(this)};e.jqplot.PieRenderer.prototype=new e.jqplot.LineRenderer();e.jqplot.PieRenderer.prototype.constructor=e.jqplot.PieRenderer;e.jqplot.PieRenderer.prototype.init=function(q,u){this.diameter=null;this.padding=20;this.sliceMargin=0;this.fill=true;this.shadowOffset=2;this.shadowAlpha=0.07;this.shadowDepth=5;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.dataLabels="percent";this.showDataLabels=false;this.dataLabelFormatString=null;this.dataLabelThreshold=3;this.dataLabelPositionFactor=0.52;this.dataLabelNudge=2;this.dataLabelCenterOn=true;this.startAngle=0;this.tickRenderer=e.jqplot.PieTickRenderer;this._drawData=true;this._type="pie";if(q.highlightMouseDown&&q.highlightMouseOver==null){q.highlightMouseOver=false}e.extend(true,this,q);if(this.sliceMargin<0){this.sliceMargin=0}this._diameter=null;this._radius=null;this._sliceAngles=[];this._highlightedPoint=null;if(this.highlightColors.length==0){for(var s=0;s<this.seriesColors.length;s++){var r=e.jqplot.getColorComponents(this.seriesColors[s]);var o=[r[0],r[1],r[2]];var t=o[0]+o[1]+o[2];for(var p=0;p<3;p++){o[p]=(t>570)?o[p]*0.8:o[p]+0.3*(255-o[p]);o[p]=parseInt(o[p],10)}this.highlightColors.push("rgb("+o[0]+","+o[1]+","+o[2]+")")}}this.highlightColorGenerator=new e.jqplot.ColorGenerator(this.highlightColors);u.postParseOptionsHooks.addOnce(m);u.postInitHooks.addOnce(g);u.eventListenerHooks.addOnce("jqplotMouseMove",b);u.eventListenerHooks.addOnce("jqplotMouseDown",a);u.eventListenerHooks.addOnce("jqplotMouseUp",l);u.eventListenerHooks.addOnce("jqplotClick",f);u.eventListenerHooks.addOnce("jqplotRightClick",n);u.postDrawHooks.addOnce(i)};e.jqplot.PieRenderer.prototype.setGridData=function(t){var p=[];var u=[];var o=this.startAngle/180*Math.PI;var s=0;this._drawData=false;for(var r=0;r<this.data.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(this.data[r][1]);u.push([this.data[r][0]]);if(r>0){p[r]+=p[r-1]}s+=this.data[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){u[r][1]=p[r]*q;u[r][2]=this.data[r][1]/s}this.gridData=u};e.jqplot.PieRenderer.prototype.makeGridData=function(t,u){var p=[];var v=[];var s=0;var o=this.startAngle/180*Math.PI;this._drawData=false;for(var r=0;r<t.length;r++){if(this.data[r][1]!=0){this._drawData=true}p.push(t[r][1]);v.push([t[r][0]]);if(r>0){p[r]+=p[r-1]}s+=t[r][1]}var q=Math.PI*2/p[p.length-1];for(var r=0;r<p.length;r++){v[r][1]=p[r]*q;v[r][2]=t[r][1]/s}return v};function h(o){return Math.sin((o-(o-Math.PI)/8/Math.PI)/2)}function j(u,t,o,v,r){var w=0;var q=t-u;var s=Math.abs(q);var p=o;if(v==false){p+=r}if(p>0&&s>0.01&&s<6.282){w=parseFloat(p)/2/h(q)}return w}e.jqplot.PieRenderer.prototype.drawSlice=function(B,z,y,u,w){if(this._drawData){var p=this._radius;var A=this.fill;var x=this.lineWidth;var s=this.sliceMargin;if(this.fill==false){s+=this.lineWidth}B.save();B.translate(this._center[0],this._center[1]);var D=j(z,y,this.sliceMargin,this.fill,this.lineWidth);var o=D*Math.cos((z+y)/2);var C=D*Math.sin((z+y)/2);if((y-z)<=Math.PI){p-=D}else{p+=D}B.translate(o,C);if(w){for(var v=0,t=this.shadowDepth;v<t;v++){B.save();B.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI),this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));q(p)}for(var v=0,t=this.shadowDepth;v<t;v++){B.restore()}}else{q(p)}B.restore()}function q(r){if(y>6.282+this.startAngle){y=6.282+this.startAngle;if(z>y){z=6.281+this.startAngle}}if(z>=y){return}B.beginPath();B.fillStyle=u;B.strokeStyle=u;B.lineWidth=x;B.arc(0,0,r,z,y,false);B.lineTo(0,0);B.closePath();if(A){B.fill()}else{B.stroke()}}};e.jqplot.PieRenderer.prototype.draw=function(B,z,E,o){var W;var H=(E!=undefined)?E:{};var t=0;var s=0;var N=1;var L=new e.jqplot.ColorGenerator(this.seriesColors);if(E.legendInfo&&E.legendInfo.placement=="insideGrid"){var J=E.legendInfo;switch(J.location){case"nw":t=J.width+J.xoffset;break;case"w":t=J.width+J.xoffset;break;case"sw":t=J.width+J.xoffset;break;case"ne":t=J.width+J.xoffset;N=-1;break;case"e":t=J.width+J.xoffset;N=-1;break;case"se":t=J.width+J.xoffset;N=-1;break;case"n":s=J.height+J.yoffset;break;case"s":s=J.height+J.yoffset;N=-1;break;default:break}}var K=(H.shadow!=undefined)?H.shadow:this.shadow;var A=(H.fill!=undefined)?H.fill:this.fill;var C=B.canvas.width;var I=B.canvas.height;var Q=C-t-2*this.padding;var X=I-s-2*this.padding;var M=Math.min(Q,X);var Y=M;this._sliceAngles=[];var v=this.sliceMargin;if(this.fill==false){v+=this.lineWidth}var q;var G=0;var R,aa,Z,ab;var D=this.startAngle/180*Math.PI;for(var W=0,V=z.length;W<V;W++){aa=(W==0)?D:z[W-1][1]+D;Z=z[W][1]+D;this._sliceAngles.push([aa,Z]);q=j(aa,Z,this.sliceMargin,this.fill,this.lineWidth);if(Math.abs(Z-aa)>Math.PI){G=Math.max(q,G)}}if(this.diameter!=null&&this.diameter>0){this._diameter=this.diameter-2*G}else{this._diameter=Y-2*G}if(this._diameter<6){e.jqplot.log("Diameter of pie too small, not rendering.");return}var S=this._radius=this._diameter/2;this._center=[(C-N*t)/2+N*t+G*Math.cos(D),(I-N*s)/2+N*s+G*Math.sin(D)];if(this.shadow){for(var W=0,V=z.length;W<V;W++){ab="rgba(0,0,0,"+this.shadowAlpha+")";this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],ab,true)}}for(var W=0;W<z.length;W++){this.renderer.drawSlice.call(this,B,this._sliceAngles[W][0],this._sliceAngles[W][1],L.next(),false);if(this.showDataLabels&&z[W][2]*100>=this.dataLabelThreshold){var F,U=(this._sliceAngles[W][0]+this._sliceAngles[W][1])/2,T;if(this.dataLabels=="label"){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,z[W][0])}else{if(this.dataLabels=="value"){F=this.dataLabelFormatString||"%d";T=e.jqplot.sprintf(F,this.data[W][1])}else{if(this.dataLabels=="percent"){F=this.dataLabelFormatString||"%d%%";T=e.jqplot.sprintf(F,z[W][2]*100)}else{if(this.dataLabels.constructor==Array){F=this.dataLabelFormatString||"%s";T=e.jqplot.sprintf(F,this.dataLabels[W])}}}}var p=(this._radius)*this.dataLabelPositionFactor+this.sliceMargin+this.dataLabelNudge;var P=this._center[0]+Math.cos(U)*p+this.canvas._offsets.left;var O=this._center[1]+Math.sin(U)*p+this.canvas._offsets.top;var u=e('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">'+T+"</div>").insertBefore(o.eventCanvas._elem);if(this.dataLabelCenterOn){P-=u.width()/2;O-=u.height()/2}else{P-=u.width()*Math.sin(U/2);O-=u.height()/2}P=Math.round(P);O=Math.round(O);u.css({left:P,top:O})}}};e.jqplot.PieAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PieAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PieAxisRenderer.prototype.constructor=e.jqplot.PieAxisRenderer;e.jqplot.PieAxisRenderer.prototype.init=function(o){this.tickRenderer=e.jqplot.PieTickRenderer;e.extend(true,this,o);this._dataBounds={min:0,max:100};this.min=0;this.max=100;this.showTicks=false;this.ticks=[];this.showMark=false;this.show=false};e.jqplot.PieLegendRenderer=function(){e.jqplot.TableLegendRenderer.call(this)};e.jqplot.PieLegendRenderer.prototype=new e.jqplot.TableLegendRenderer();e.jqplot.PieLegendRenderer.prototype.constructor=e.jqplot.PieLegendRenderer;e.jqplot.PieLegendRenderer.prototype.init=function(o){this.numberRows=null;this.numberColumns=null;e.extend(true,this,o)};e.jqplot.PieLegendRenderer.prototype.draw=function(){var r=this;if(this.show){var B=this._series;this._elem=e(document.createElement("table"));this._elem.addClass("jqplot-table-legend");var E={position:"absolute"};if(this.background){E.background=this.background}if(this.border){E.border=this.border}if(this.fontSize){E.fontSize=this.fontSize}if(this.fontFamily){E.fontFamily=this.fontFamily}if(this.textColor){E.textColor=this.textColor}if(this.marginTop!=null){E.marginTop=this.marginTop}if(this.marginBottom!=null){E.marginBottom=this.marginBottom}if(this.marginLeft!=null){E.marginLeft=this.marginLeft}if(this.marginRight!=null){E.marginRight=this.marginRight}this._elem.css(E);var I=false,A=false,o,y;var C=B[0];var p=new e.jqplot.ColorGenerator(C.seriesColors);if(C.show){var J=C.data;if(this.numberRows){o=this.numberRows;if(!this.numberColumns){y=Math.ceil(J.length/o)}else{y=this.numberColumns}}else{if(this.numberColumns){y=this.numberColumns;o=Math.ceil(J.length/this.numberColumns)}else{o=J.length;y=1}}var H,G;var q,w,v;var x,z,F;var D=0;var u,t;for(H=0;H<o;H++){q=e(document.createElement("tr"));q.addClass("jqplot-table-legend");if(A){q.prependTo(this._elem)}else{q.appendTo(this._elem)}for(G=0;G<y;G++){if(D<J.length){x=this.labels[D]||J[D][0].toString();F=p.next();if(!A){if(H>0){I=true}else{I=false}}else{if(H==o-1){I=false}else{I=true}}z=(I)?this.rowSpacing:"0";w=e(document.createElement("td"));w.addClass("jqplot-table-legend jqplot-table-legend-swatch");w.css({textAlign:"center",paddingTop:z});u=e(document.createElement("div"));u.addClass("jqplot-table-legend-swatch-outline");t=e(document.createElement("div"));t.addClass("jqplot-table-legend-swatch");t.css({backgroundColor:F,borderColor:F});w.append(u.append(t));v=e(document.createElement("td"));v.addClass("jqplot-table-legend jqplot-table-legend-label");v.css("paddingTop",z);if(this.escapeHtml){v.text(x)}else{v.html(x)}if(A){v.prependTo(q);w.prependTo(q)}else{w.appendTo(q);v.appendTo(q)}I=true}D++}}}}return this._elem};e.jqplot.PieRenderer.prototype.handleMove=function(q,p,t,s,r){if(s){var o=[s.seriesIndex,s.pointIndex,s.data];r.target.trigger("jqplotDataMouseOver",o);if(r.series[o[0]].highlightMouseOver&&!(o[0]==r.plugins.pieRenderer.highlightedSeriesIndex&&o[1]==r.series[o[0]]._highlightedPoint)){r.target.trigger("jqplotDataHighlight",o);d(r,o[0],o[1])}}else{if(s==null){k(r)}}};function c(s,r,p){p=p||{};p.axesDefaults=p.axesDefaults||{};p.legend=p.legend||{};p.seriesDefaults=p.seriesDefaults||{};var o=false;if(p.seriesDefaults.renderer==e.jqplot.PieRenderer){o=true}else{if(p.series){for(var q=0;q<p.series.length;q++){if(p.series[q].renderer==e.jqplot.PieRenderer){o=true}}}}if(o){p.axesDefaults.renderer=e.jqplot.PieAxisRenderer;p.legend.renderer=e.jqplot.PieLegendRenderer;p.legend.preDraw=true;p.seriesDefaults.pointLabels={show:false}}}function g(r,q,o){for(var p=0;p<this.series.length;p++){if(this.series[p].renderer.constructor==e.jqplot.PieRenderer){if(this.series[p].highlightMouseOver){this.series[p].highlightMouseDown=false}}}}function m(o){for(var p=0;p<this.series.length;p++){this.series[p].seriesColors=this.seriesColors;this.series[p].colorGenerator=e.jqplot.colorGenerator}}function d(t,r,q){var p=t.series[r];var o=t.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);p._highlightedPoint=q;t.plugins.pieRenderer.highlightedSeriesIndex=r;p.renderer.drawSlice.call(p,o._ctx,p._sliceAngles[q][0],p._sliceAngles[q][1],p.highlightColorGenerator.get(q),false)}function k(q){var o=q.plugins.pieRenderer.highlightCanvas;o._ctx.clearRect(0,0,o._ctx.canvas.width,o._ctx.canvas.height);for(var p=0;p<q.series.length;p++){q.series[p]._highlightedPoint=null}q.plugins.pieRenderer.highlightedSeriesIndex=null;q.target.trigger("jqplotDataUnhighlight")}function b(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var p=jQuery.Event("jqplotDataMouseOver");p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q);if(t.series[q[0]].highlightMouseOver&&!(q[0]==t.plugins.pieRenderer.highlightedSeriesIndex&&q[1]==t.series[q[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=s.which;o.pageX=s.pageX;o.pageY=s.pageY;t.target.trigger(o,q);d(t,q[0],q[1])}}else{if(u==null){k(t)}}}function a(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];if(s.series[p[0]].highlightMouseDown&&!(p[0]==s.plugins.pieRenderer.highlightedSeriesIndex&&p[1]==s.series[p[0]]._highlightedPoint)){var o=jQuery.Event("jqplotDataHighlight");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p);d(s,p[0],p[1])}}else{if(t==null){k(s)}}}function l(q,p,t,s,r){var o=r.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&r.series[o].highlightMouseDown){k(r)}}function f(r,q,u,t,s){if(t){var p=[t.seriesIndex,t.pointIndex,t.data];var o=jQuery.Event("jqplotDataClick");o.which=r.which;o.pageX=r.pageX;o.pageY=r.pageY;s.target.trigger(o,p)}}function n(s,r,v,u,t){if(u){var q=[u.seriesIndex,u.pointIndex,u.data];var o=t.plugins.pieRenderer.highlightedSeriesIndex;if(o!=null&&t.series[o].highlightMouseDown){k(t)}var p=jQuery.Event("jqplotDataRightClick");p.which=s.which;p.pageX=s.pageX;p.pageY=s.pageY;t.target.trigger(p,q)}}function i(){if(this.plugins.pieRenderer&&this.plugins.pieRenderer.highlightCanvas){this.plugins.pieRenderer.highlightCanvas.resetCanvas();this.plugins.pieRenderer.highlightCanvas=null}this.plugins.pieRenderer={highlightedSeriesIndex:null};this.plugins.pieRenderer.highlightCanvas=new e.jqplot.GenericCanvas();var p=e(this.targetId+" .jqplot-data-label");if(p.length){e(p[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}else{this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pieRenderer-highlight-canvas",this._plotDimensions,this))}var o=this.plugins.pieRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(q){k(q.data.plot)})}e.jqplot.preInitHooks.push(c);e.jqplot.PieTickRenderer=function(){e.jqplot.AxisTickRenderer.call(this)};e.jqplot.PieTickRenderer.prototype=new e.jqplot.AxisTickRenderer();e.jqplot.PieTickRenderer.prototype.constructor=e.jqplot.PieTickRenderer})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.js new file mode 100644 index 0000000..4edc69e --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.js @@ -0,0 +1,377 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + /** + * Class: $.jqplot.PointLabels + * Plugin for putting labels at the data points. + * + * To use this plugin, include the js + * file in your source: + * + * > <script type="text/javascript" src="plugins/jqplot.pointLabels.js"></script> + * + * By default, the last value in the data ponit array in the data series is used + * for the label. For most series renderers, extra data can be added to the + * data point arrays and the last value will be used as the label. + * + * For instance, + * this series: + * + * > [[1,4], [3,5], [7,2]] + * + * Would, by default, use the y values in the labels. + * Extra data can be added to the series like so: + * + * > [[1,4,'mid'], [3 5,'hi'], [7,2,'low']] + * + * And now the point labels would be 'mid', 'low', and 'hi'. + * + * Options to the point labels and a custom labels array can be passed into the + * "pointLabels" option on the series option like so: + * + * > series:[{pointLabels:{ + * > labels:['mid', 'hi', 'low'], + * > location:'se', + * > ypadding: 12 + * > } + * > }] + * + * A custom labels array in the options takes precendence over any labels + * in the series data. If you have a custom labels array in the options, + * but still want to use values from the series array as labels, set the + * "labelsFromSeries" option to true. + * + * By default, html entities (<, >, etc.) are escaped in point labels. + * If you want to include actual html markup in the labels, + * set the "escapeHTML" option to false. + * + */ + $.jqplot.PointLabels = function(options) { + // Group: Properties + // + // prop: show + // show the labels or not. + this.show = $.jqplot.config.enablePlugins; + // prop: location + // compass location where to position the label around the point. + // 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw' + this.location = 'n'; + // prop: labelsFromSeries + // true to use labels within data point arrays. + this.labelsFromSeries = false; + // prop: seriesLabelIndex + // array index for location of labels within data point arrays. + // if null, will use the last element of the data point array. + this.seriesLabelIndex = null; + // prop: labels + // array of arrays of labels, one array for each series. + this.labels = []; + // actual labels that will get displayed. + // needed to preserve user specified labels in labels array. + this._labels = []; + // prop: stackedValue + // true to display value as stacked in a stacked plot. + // no effect if labels is specified. + this.stackedValue = false; + // prop: ypadding + // vertical padding in pixels between point and label + this.ypadding = 6; + // prop: xpadding + // horizontal padding in pixels between point and label + this.xpadding = 6; + // prop: escapeHTML + // true to escape html entities in the labels. + // If you want to include markup in the labels, set to false. + this.escapeHTML = true; + // prop: edgeTolerance + // Number of pixels that the label must be away from an axis + // boundary in order to be drawn. Negative values will allow overlap + // with the grid boundaries. + this.edgeTolerance = -5; + // prop: formatter + // A class of a formatter for the tick text. sprintf by default. + this.formatter = $.jqplot.DefaultTickFormatter; + // prop: formatString + // string passed to the formatter. + this.formatString = ''; + // prop: hideZeros + // true to not show a label for a value which is 0. + this.hideZeros = false; + this._elems = []; + + $.extend(true, this, options); + }; + + var locations = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']; + var locationIndicies = {'nw':0, 'n':1, 'ne':2, 'e':3, 'se':4, 's':5, 'sw':6, 'w':7}; + var oppositeLocations = ['se', 's', 'sw', 'w', 'nw', 'n', 'ne', 'e']; + + // called with scope of a series + $.jqplot.PointLabels.init = function (target, data, seriesDefaults, opts, plot){ + var options = $.extend(true, {}, seriesDefaults, opts); + options.pointLabels = options.pointLabels || {}; + if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal' && !options.pointLabels.location) { + options.pointLabels.location = 'e'; + } + // add a pointLabels attribute to the series plugins + this.plugins.pointLabels = new $.jqplot.PointLabels(options.pointLabels); + this.plugins.pointLabels.setLabels.call(this); + }; + + // called with scope of series + $.jqplot.PointLabels.prototype.setLabels = function() { + var p = this.plugins.pointLabels; + var labelIdx; + if (p.seriesLabelIndex != null) { + labelIdx = p.seriesLabelIndex; + } + else if (this.renderer.constructor === $.jqplot.BarRenderer && this.barDirection === 'horizontal') { + labelIdx = (this._plotData[0].length < 3) ? 0 : this._plotData[0].length -1; + } + else { + labelIdx = (this._plotData.length === 0) ? 0 : this._plotData[0].length -1; + } + p._labels = []; + if (p.labels.length === 0 || p.labelsFromSeries) { + if (p.stackedValue) { + if (this._plotData.length && this._plotData[0].length){ + // var idx = p.seriesLabelIndex || this._plotData[0].length -1; + for (var i=0; i<this._plotData.length; i++) { + p._labels.push(this._plotData[i][labelIdx]); + } + } + } + else { + // var d = this._plotData; + var d = this.data; + if (this.renderer.constructor === $.jqplot.BarRenderer && this.waterfall) { + d = this._data; + } + if (d.length && d[0].length) { + // var idx = p.seriesLabelIndex || d[0].length -1; + for (var i=0; i<d.length; i++) { + p._labels.push(d[i][labelIdx]); + } + } + d = null; + } + } + else if (p.labels.length){ + p._labels = p.labels; + } + }; + + $.jqplot.PointLabels.prototype.xOffset = function(elem, location, padding) { + location = location || this.location; + padding = padding || this.xpadding; + var offset; + + switch (location) { + case 'nw': + offset = -elem.outerWidth(true) - this.xpadding; + break; + case 'n': + offset = -elem.outerWidth(true)/2; + break; + case 'ne': + offset = this.xpadding; + break; + case 'e': + offset = this.xpadding; + break; + case 'se': + offset = this.xpadding; + break; + case 's': + offset = -elem.outerWidth(true)/2; + break; + case 'sw': + offset = -elem.outerWidth(true) - this.xpadding; + break; + case 'w': + offset = -elem.outerWidth(true) - this.xpadding; + break; + default: // same as 'nw' + offset = -elem.outerWidth(true) - this.xpadding; + break; + } + return offset; + }; + + $.jqplot.PointLabels.prototype.yOffset = function(elem, location, padding) { + location = location || this.location; + padding = padding || this.xpadding; + var offset; + + switch (location) { + case 'nw': + offset = -elem.outerHeight(true) - this.ypadding; + break; + case 'n': + offset = -elem.outerHeight(true) - this.ypadding; + break; + case 'ne': + offset = -elem.outerHeight(true) - this.ypadding; + break; + case 'e': + offset = -elem.outerHeight(true)/2; + break; + case 'se': + offset = this.ypadding; + break; + case 's': + offset = this.ypadding; + break; + case 'sw': + offset = this.ypadding; + break; + case 'w': + offset = -elem.outerHeight(true)/2; + break; + default: // same as 'nw' + offset = -elem.outerHeight(true) - this.ypadding; + break; + } + return offset; + }; + + // called with scope of series + $.jqplot.PointLabels.draw = function (sctx, options, plot) { + var p = this.plugins.pointLabels; + // set labels again in case they have changed. + p.setLabels.call(this); + // remove any previous labels + for (var i=0; i<p._elems.length; i++) { + // Memory Leaks patch + // p._elems[i].remove(); + p._elems[i].emptyForce(); + } + p._elems.splice(0, p._elems.length); + + if (p.show) { + var ax = '_'+this._stackAxis+'axis'; + + if (!p.formatString) { + p.formatString = this[ax]._ticks[0].formatString; + p.formatter = this[ax]._ticks[0].formatter; + } + + var pd = this._plotData; + var ppd = this._prevPlotData; + var xax = this._xaxis; + var yax = this._yaxis; + var elem, helem; + + for (var i=0, l=p._labels.length; i < l; i++) { + var label = p._labels[i]; + + if (label == null || (p.hideZeros && parseInt(label, 10) == 0)) { + continue; + } + + label = p.formatter(p.formatString, label); + + helem = document.createElement('div'); + p._elems[i] = $(helem); + + elem = p._elems[i]; + + + elem.addClass('jqplot-point-label jqplot-series-'+this.index+' jqplot-point-'+i); + elem.css('position', 'absolute'); + elem.insertAfter(sctx.canvas); + + if (p.escapeHTML) { + elem.text(label); + } + else { + elem.html(label); + } + var location = p.location; + if ((this.fillToZero && pd[i][1] < 0) || (this.fillToZero && this._type === 'bar' && this.barDirection === 'horizontal' && pd[i][0] < 0) || (this.waterfall && parseInt(label, 10)) < 0) { + location = oppositeLocations[locationIndicies[location]]; + } + + + var ell = xax.u2p(pd[i][0]) + p.xOffset(elem, location); + var elt = yax.u2p(pd[i][1]) + p.yOffset(elem, location); + + // we have stacked chart but are not showing stacked values, + // place labels in center. + if (this._stack && !p.stackedValue) { + if (this.barDirection === "vertical") { + elt = (this._barPoints[i][0][1] + this._barPoints[i][1][1]) / 2 + plot._gridPadding.top - 0.5 * elem.outerHeight(true); + } + else { + ell = (this._barPoints[i][2][0] + this._barPoints[i][0][0]) / 2 + plot._gridPadding.left - 0.5 * elem.outerWidth(true); + } + } + + if (this.renderer.constructor == $.jqplot.BarRenderer) { + if (this.barDirection == "vertical") { + ell += this._barNudge; + } + else { + elt -= this._barNudge; + } + } + elem.css('left', ell); + elem.css('top', elt); + var elr = ell + elem.width(); + var elb = elt + elem.height(); + var et = p.edgeTolerance; + var scl = $(sctx.canvas).position().left; + var sct = $(sctx.canvas).position().top; + var scr = sctx.canvas.width + scl; + var scb = sctx.canvas.height + sct; + // if label is outside of allowed area, remove it + if (ell - et < scl || elt - et < sct || elr + et > scr || elb + et > scb) { + elem.remove(); + } + + elem = null; + helem = null; + } + + // finally, animate them if the series is animated + // if (this.renderer.animation && this.renderer.animation._supported && this.renderer.animation.show && plot._drawCount < 2) { + // var sel = '.jqplot-point-label.jqplot-series-'+this.index; + // $(sel).hide(); + // $(sel).fadeIn(1000); + // } + + } + }; + + $.jqplot.postSeriesInitHooks.push($.jqplot.PointLabels.init); + $.jqplot.postDrawSeriesHooks.push($.jqplot.PointLabels.draw); +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.min.js new file mode 100644 index 0000000..54810c1 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pointLabels.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){c.jqplot.PointLabels=function(e){this.show=c.jqplot.config.enablePlugins;this.location="n";this.labelsFromSeries=false;this.seriesLabelIndex=null;this.labels=[];this._labels=[];this.stackedValue=false;this.ypadding=6;this.xpadding=6;this.escapeHTML=true;this.edgeTolerance=-5;this.formatter=c.jqplot.DefaultTickFormatter;this.formatString="";this.hideZeros=false;this._elems=[];c.extend(true,this,e)};var a=["nw","n","ne","e","se","s","sw","w"];var d={nw:0,n:1,ne:2,e:3,se:4,s:5,sw:6,w:7};var b=["se","s","sw","w","nw","n","ne","e"];c.jqplot.PointLabels.init=function(j,h,f,g,i){var e=c.extend(true,{},f,g);e.pointLabels=e.pointLabels||{};if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"&&!e.pointLabels.location){e.pointLabels.location="e"}this.plugins.pointLabels=new c.jqplot.PointLabels(e.pointLabels);this.plugins.pointLabels.setLabels.call(this)};c.jqplot.PointLabels.prototype.setLabels=function(){var f=this.plugins.pointLabels;var h;if(f.seriesLabelIndex!=null){h=f.seriesLabelIndex}else{if(this.renderer.constructor===c.jqplot.BarRenderer&&this.barDirection==="horizontal"){h=(this._plotData[0].length<3)?0:this._plotData[0].length-1}else{h=(this._plotData.length===0)?0:this._plotData[0].length-1}}f._labels=[];if(f.labels.length===0||f.labelsFromSeries){if(f.stackedValue){if(this._plotData.length&&this._plotData[0].length){for(var e=0;e<this._plotData.length;e++){f._labels.push(this._plotData[e][h])}}}else{var g=this.data;if(this.renderer.constructor===c.jqplot.BarRenderer&&this.waterfall){g=this._data}if(g.length&&g[0].length){for(var e=0;e<g.length;e++){f._labels.push(g[e][h])}}g=null}}else{if(f.labels.length){f._labels=f.labels}}};c.jqplot.PointLabels.prototype.xOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerWidth(true)-this.xpadding;break;case"n":h=-f.outerWidth(true)/2;break;case"ne":h=this.xpadding;break;case"e":h=this.xpadding;break;case"se":h=this.xpadding;break;case"s":h=-f.outerWidth(true)/2;break;case"sw":h=-f.outerWidth(true)-this.xpadding;break;case"w":h=-f.outerWidth(true)-this.xpadding;break;default:h=-f.outerWidth(true)-this.xpadding;break}return h};c.jqplot.PointLabels.prototype.yOffset=function(f,e,g){e=e||this.location;g=g||this.xpadding;var h;switch(e){case"nw":h=-f.outerHeight(true)-this.ypadding;break;case"n":h=-f.outerHeight(true)-this.ypadding;break;case"ne":h=-f.outerHeight(true)-this.ypadding;break;case"e":h=-f.outerHeight(true)/2;break;case"se":h=this.ypadding;break;case"s":h=this.ypadding;break;case"sw":h=this.ypadding;break;case"w":h=-f.outerHeight(true)/2;break;default:h=-f.outerHeight(true)-this.ypadding;break}return h};c.jqplot.PointLabels.draw=function(x,j,v){var t=this.plugins.pointLabels;t.setLabels.call(this);for(var w=0;w<t._elems.length;w++){t._elems[w].emptyForce()}t._elems.splice(0,t._elems.length);if(t.show){var r="_"+this._stackAxis+"axis";if(!t.formatString){t.formatString=this[r]._ticks[0].formatString;t.formatter=this[r]._ticks[0].formatter}var E=this._plotData;var D=this._prevPlotData;var A=this._xaxis;var q=this._yaxis;var z,f;for(var w=0,u=t._labels.length;w<u;w++){var o=t._labels[w];if(o==null||(t.hideZeros&&parseInt(o,10)==0)){continue}o=t.formatter(t.formatString,o);f=document.createElement("div");t._elems[w]=c(f);z=t._elems[w];z.addClass("jqplot-point-label jqplot-series-"+this.index+" jqplot-point-"+w);z.css("position","absolute");z.insertAfter(x.canvas);if(t.escapeHTML){z.text(o)}else{z.html(o)}var g=t.location;if((this.fillToZero&&E[w][1]<0)||(this.fillToZero&&this._type==="bar"&&this.barDirection==="horizontal"&&E[w][0]<0)||(this.waterfall&&parseInt(o,10))<0){g=b[d[g]]}var n=A.u2p(E[w][0])+t.xOffset(z,g);var h=q.u2p(E[w][1])+t.yOffset(z,g);if(this._stack&&!t.stackedValue){if(this.barDirection==="vertical"){h=(this._barPoints[w][0][1]+this._barPoints[w][1][1])/2+v._gridPadding.top-0.5*z.outerHeight(true)}else{n=(this._barPoints[w][2][0]+this._barPoints[w][0][0])/2+v._gridPadding.left-0.5*z.outerWidth(true)}}if(this.renderer.constructor==c.jqplot.BarRenderer){if(this.barDirection=="vertical"){n+=this._barNudge}else{h-=this._barNudge}}z.css("left",n);z.css("top",h);var k=n+z.width();var s=h+z.height();var C=t.edgeTolerance;var e=c(x.canvas).position().left;var y=c(x.canvas).position().top;var B=x.canvas.width+e;var m=x.canvas.height+y;if(n-C<e||h-C<y||k+C>B||s+C>m){z.remove()}z=null;f=null}}};c.jqplot.postSeriesInitHooks.push(c.jqplot.PointLabels.init);c.jqplot.postDrawSeriesHooks.push(c.jqplot.PointLabels.draw)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.js new file mode 100644 index 0000000..7650e30 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.js @@ -0,0 +1,728 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + $.jqplot.PyramidAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.PyramidAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.PyramidAxisRenderer.prototype.constructor = $.jqplot.PyramidAxisRenderer; + + // called with scope of axis + $.jqplot.PyramidAxisRenderer.prototype.init = function(options){ + // Group: Properties + // + // prop: position + // Position of axis. Values are: top, bottom , left, center, right. + // By default, x and x2 axes are bottom, y axis is center. + this.position = null; + // prop: drawBaseline + // True to draw the axis baseline. + this.drawBaseline = true; + // prop: baselineWidth + // width of the baseline in pixels. + this.baselineWidth = null; + // prop: baselineColor + // CSS color spec for the baseline. + this.baselineColor = null; + this.tickSpacingFactor = 25; + this._type = 'pyramid'; + this._splitAxis = false; + this._splitLength = null; + this.category = false; + this._autoFormatString = ''; + this._overrideFormatString = false; + + $.extend(true, this, options); + this.renderer.options = options; + + this.resetDataBounds = this.renderer.resetDataBounds; + this.resetDataBounds(); + + }; + + $.jqplot.PyramidAxisRenderer.prototype.resetDataBounds = function() { + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + var db = this._dataBounds; + db.min = null; + db.max = null; + var temp; + for (var i=0; i<this._series.length; i++) { + var s = this._series[i]; + var d = s._plotData; + + for (var j=0, l=d.length; j<l; j++) { + if (this.name.charAt(0) === 'x') { + temp = d[j][1]; + if ((temp !== null && temp < db.min) || db.min === null) { + db.min = temp; + } + if ((temp !== null && temp > db.max) || db.max === null) { + db.max = temp; + } + } + else { + temp = d[j][0]; + if ((temp !== null && temp < db.min) || db.min === null) { + db.min = temp; + } + if ((temp !== null && temp > db.max) || db.max === null) { + db.max = temp; + } + } + } + } + }; + + // called with scope of axis + $.jqplot.PyramidAxisRenderer.prototype.draw = function(ctx, plot) { + if (this.show) { + // populate the axis label and value properties. + // createTicks is a method on the renderer, but + // call it within the scope of the axis. + this.renderer.createTicks.call(this, plot); + // fill a div with axes labels in the right direction. + // Need to pregenerate each axis to get its bounds and + // position it and the labels correctly on the plot. + var dim=0; + var temp; + // Added for theming. + if (this._elem) { + // Memory Leaks patch + //this._elem.empty(); + this._elem.emptyForce(); + this._elem = null; + } + + this._elem = $(document.createElement('div')); + this._elem.addClass('jqplot-axis jqplot-'+this.name); + this._elem.css('position', 'absolute'); + + + if (this.name == 'xaxis' || this.name == 'x2axis') { + this._elem.width(this._plotDimensions.width); + } + else { + this._elem.height(this._plotDimensions.height); + } + + // create a _label object. + this.labelOptions.axis = this.name; + this._label = new this.labelRenderer(this.labelOptions); + if (this._label.show) { + var elem = this._label.draw(ctx, plot); + elem.appendTo(this._elem); + elem = null; + } + + var t = this._ticks; + var tick; + for (var i=0; i<t.length; i++) { + tick = t[i]; + if (tick.show && tick.showLabel && (!tick.isMinorTick)) { + this._elem.append(tick.draw(ctx, plot)); + } + } + tick = null; + t = null; + } + return this._elem; + }; + + // Note, primes can be found on http://primes.utm.edu/ + var _primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; + + + var _primesHash = {}; + + for (var i =0, l = _primes.length; i < l; i++) { + _primesHash[_primes[i]] = _primes[i]; + } + + // called with scope of axis + $.jqplot.PyramidAxisRenderer.prototype.createTicks = function(plot) { + // we're are operating on an axis here + var userTicks = this.ticks; + // databounds were set on axis initialization. + var db = this._dataBounds; + var dim; + var interval; + var min; + var max; + var range; + var pos1; + var pos2; + var tt; + var i; + var l; + var s; + // get a copy of user's settings for min/max. + var userMin = this.min; + var userMax = this.max; + var ut; + var t; + var threshold; + var tdim; + var scalefact; + var ret; + var tumin; + var tumax; + var maxVisibleTicks; + var val; + var skip = null; + var temp; + + // if we already have ticks, use them. + // ticks must be in order of increasing value. + + if (userTicks.length) { + // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed + for (i=0, l=userTicks.length; i<l; i++){ + ut = userTicks[i]; + t = new this.tickRenderer(this.tickOptions); + if ($.isArray(ut)) { + t.value = ut[0]; + t.label = ut[1]; + t.setTick(ut[0], this.name); + this._ticks.push(t); + } + + else if ($.isPlainObject(ut)) { + $.extend(true, t, ut); + t.axis = this.name; + this._ticks.push(t); + } + + else { + if (typeof ut === 'string') { + val = i + plot.defaultAxisStart; + } + else { + val = ut; + } + t.value = val; + t.label = ut; + t.axis = this.name; + this._ticks.push(t); + } + } + this.numberTicks = userTicks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this.numberTicks-1].value; + this.tickInterval = (this.max - this.min) / (this.numberTicks - 1); + + // use user specified tickInterval if there is one + if (this._options.tickInterval) { + // hide every tick except for ticks on interval + var ti = this._options.tickInterval; + for (i=0; i<this.numberTicks; i++) { + if (i%ti !== 0) { + // this._ticks[i].show = false; + this._ticks[i].isMinorTick = true; + } + } + } + + else { + // check if we have too many ticks + dim = (this.name.charAt(0) === 'x') ? this._plotDimensions.width : this._plotDimensions.height; + maxVisibleTicks = Math.round(2.0 + dim/this.tickSpacingFactor); + + if (this.numberTicks > maxVisibleTicks) { + // check for number of ticks we can skip + temp = this.numberTicks - 1; + for (i=2; i<temp; i++) { + if (temp % i === 0 && temp/i < maxVisibleTicks) { + skip = i-1; + break; + } + } + + if (skip !== null) { + var count = 1; + for (i=1, l=this._ticks.length; i<l; i++) { + if (count <= skip) { + this._ticks[i].show = false; + count += 1; + } + else { + count = 1; + } + } + } + } + } + + // if category style, add minor ticks in between + temp = []; + if (this.category) { + // turn off gridline and mark on first tick + this._ticks[0].showGridline = false; + this._ticks[0].showMark = false; + + for (i=this._ticks.length-1; i>0; i--) { + t = new this.tickRenderer(this.tickOptions); + t.value = this._ticks[i-1].value + this.tickInterval/2.0; + t.label = ''; + t.showLabel = false; + t.axis = this.name; + this._ticks[i].showGridline = false; + this._ticks[i].showMark = false; + this._ticks.splice(i, 0, t); + // temp.push(t); + } + + // merge in the new ticks + // for (i=1, l=temp.length; i<l; i++) { + // this._ticks.splice(i, 0, temp[i]); + // } + + // now add a tick at beginning and end + t = new this.tickRenderer(this.tickOptions); + t.value = this._ticks[0].value - this.tickInterval/2.0; + t.label = ''; + t.showLabel = false; + t.axis = this.name; + this._ticks.unshift(t); + + t = new this.tickRenderer(this.tickOptions); + t.value = this._ticks[this._ticks.length-1].value + this.tickInterval/2.0; + t.label = ''; + t.showLabel = false; + t.axis = this.name; + this._ticks.push(t); + + this.tickInterval = this.tickInterval / 2.0; + this.numberTicks = this._ticks.length; + this.min = this._ticks[0].value; + this.max = this._ticks[this._ticks.length-1].value; + } + } + + // we don't have any ticks yet, let's make some! + else { + if (this.name.charAt(0) === 'x') { + dim = this._plotDimensions.width; + // make sure x axis is symetric about 0. + var tempmax = Math.max(db.max, Math.abs(db.min)); + var tempmin = Math.min(db.min, -tempmax); + // min = ((this.min != null) ? this.min : tempmin); + // max = ((this.max != null) ? this.max : tempmax); + min = tempmin; + max = tempmax; + range = max - min; + + if (this.tickOptions == null || !this.tickOptions.formatString) { + this._overrideFormatString = true; + } + + threshold = 30; + tdim = Math.max(dim, threshold+1); + scalefact = (tdim-threshold)/300.0; + ret = $.jqplot.LinearTickGenerator(min, max, scalefact); + // calculate a padded max and min, points should be less than these + // so that they aren't too close to the edges of the plot. + // User can adjust how much padding is allowed with pad, padMin and PadMax options. + tumin = min + range*(this.padMin - 1); + tumax = max - range*(this.padMax - 1); + + if (min < tumin || max > tumax) { + tumin = min - range*(this.padMin - 1); + tumax = max + range*(this.padMax - 1); + ret = $.jqplot.LinearTickGenerator(tumin, tumax, scalefact); + } + + this.min = ret[0]; + this.max = ret[1]; + this.numberTicks = ret[2]; + this._autoFormatString = ret[3]; + this.tickInterval = ret[4]; + } + else { + dim = this._plotDimensions.height; + + // ticks will be on whole integers like 1, 2, 3, ... or 1, 4, 7, ... + min = db.min; + max = db.max; + s = this._series[0]; + this._ticks = []; + + range = max - min; + + // if range is a prime, will get only 2 ticks, expand range in that case. + if (_primesHash[range]) { + range += 1; + max += 1; + } + + this.max = max; + this.min = min; + + maxVisibleTicks = Math.round(2.0 + dim/this.tickSpacingFactor); + + if (range + 1 <= maxVisibleTicks) { + this.numberTicks = range + 1; + this.tickInterval = 1.0; + } + + else { + // figure out a round number of ticks to skip in every interval + // range / ti + 1 = nt + // ti = range / (nt - 1) + for (var i=maxVisibleTicks; i>1; i--) { + if (range/(i - 1) === Math.round(range/(i - 1))) { + this.numberTicks = i; + this.tickInterval = range/(i - 1); + break; + } + + } + } + } + + if (this._overrideFormatString && this._autoFormatString != '') { + this.tickOptions = this.tickOptions || {}; + this.tickOptions.formatString = this._autoFormatString; + } + + var labelval; + for (i=0; i<this.numberTicks; i++) { + this.tickOptions.axis = this.name; + labelval = this.min + this.tickInterval * i; + if (this.name.charAt(0) === 'x') { + labelval = Math.abs(labelval); + } + // this.tickOptions.label = String (labelval); + this.tickOptions.value = this.min + this.tickInterval * i; + t = new this.tickRenderer(this.tickOptions); + + t.label = t.prefix + t.formatter(t.formatString, labelval); + + this._ticks.push(t); + // for x axis, if y axis is in middle, add a symetrical 0 tick + if (this.name.charAt(0) === 'x' && plot.axes.yMidAxis.show && this.tickOptions.value === 0) { + this._splitAxis = true; + this._splitLength = plot.axes.yMidAxis.getWidth(); + // t.value = -this.max/2000.0; + t = new this.tickRenderer(this.tickOptions); + this._ticks.push(t); + t.value = this.max/2000.0; + } + } + t = null; + } + }; + + // called with scope of axis + $.jqplot.PyramidAxisRenderer.prototype.set = function() { + var dim = 0; + var temp; + var w = 0; + var h = 0; + var i; + var t; + var tick; + var lshow = (this._label == null) ? false : this._label.show; + if (this.show) { + t = this._ticks; + l = t.length; + for (i=0; i<l; i++) { + tick = t[i]; + if (!tick._breakTick && tick.show && tick.showLabel && !tick.isMinorTick) { + if (this.name.charAt(0) === 'x') { + temp = tick._elem.outerHeight(true); + } + else { + temp = tick._elem.outerWidth(true); + } + if (temp > dim) { + dim = temp; + } + } + } + + if (this.name === 'yMidAxis') { + for (i=0; i<l; i++) { + tick = t[i]; + if (tick._elem) { + temp = (dim - tick._elem.outerWidth(true))/2.0; + tick._elem.css('left', temp); + } + } + } + tick = null; + t = null; + + if (lshow) { + w = this._label._elem.outerWidth(true); + h = this._label._elem.outerHeight(true); + } + if (this.name === 'xaxis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); + } + else if (this.name === 'x2axis') { + dim = dim + h; + this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); + } + else if (this.name === 'yaxis') { + dim = dim + w; + this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + else if (this.name === 'yMidAxis') { + // don't include width of label at all in width of axis? + // dim = (dim > w) ? dim : w; + var temp = dim/2.0 - w/2.0; + this._elem.css({'width':dim+'px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css({width: w, left: temp, top: 0}); + } + } + else { + dim = dim + w; + this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); + if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { + this._label._elem.css('width', w+'px'); + } + } + } + }; + + $.jqplot.PyramidAxisRenderer.prototype.pack = function(pos, offsets) { + // Add defaults for repacking from resetTickValues function. + pos = pos || {}; + offsets = offsets || this._offsets; + + var ticks = this._ticks; + var max = this.max; + var min = this.min; + var offmax = offsets.max; + var offmin = offsets.min; + var lshow = (this._label == null) ? false : this._label.show; + + for (var p in pos) { + this._elem.css(p, pos[p]); + } + + this._offsets = offsets; + // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. + var pixellength = offmax - offmin; + var unitlength = max - min; + var sl = this._splitLength; + + // point to unit and unit to point conversions references to Plot DOM element top left corner. + if (this._splitAxis) { + pixellength -= this._splitLength; + + // don't know that this one is correct. + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + this.u2p = function(u){ + if (u <= 0) { + return (u - min) * pixellength / unitlength + offmin; + } + else { + return (u - min) * pixellength / unitlength + offmin + sl; + } + }; + + this.series_u2p = function(u){ + if (u <= 0) { + return (u - min) * pixellength / unitlength; + } + else { + return (u - min) * pixellength / unitlength + sl; + } + }; + + // don't know that this one is correct. + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + else { + this.p2u = function(p){ + return (p - offmin) * unitlength / pixellength + min; + }; + + this.u2p = function(u){ + return (u - min) * pixellength / unitlength + offmin; + }; + + if (this.name.charAt(0) === 'x'){ + this.series_u2p = function(u){ + return (u - min) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + min; + }; + } + + else { + this.series_u2p = function(u){ + return (u - max) * pixellength / unitlength; + }; + this.series_p2u = function(p){ + return p * unitlength / pixellength + max; + }; + } + } + + if (this.show) { + if (this.name.charAt(0) === 'x') { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel) { + var shim; + + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'xaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + if (temp * t.angle < 0) { + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + } + // position at start + else { + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + } + break; + case 'end': + shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + case 'start': + shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + break; + case 'middle': + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + default: + shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + break; + } + } + else { + shim = -t.getWidth()/2; + } + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('left', val); + t.pack(); + } + } + if (lshow) { + var w = this._label._elem.outerWidth(true); + this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px'); + if (this.name == 'xaxis') { + this._label._elem.css('bottom', '0px'); + } + else { + this._label._elem.css('top', '0px'); + } + this._label.pack(); + } + } + else { + for (var i=0; i<ticks.length; i++) { + var t = ticks[i]; + if (t.show && t.showLabel && !t.isMinorTick) { + var shim; + if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) { + // will need to adjust auto positioning based on which axis this is. + var temp = (this.name == 'yaxis') ? 1 : -1; + switch (t.labelPosition) { + case 'auto': + // position at end + case 'end': + if (temp * t.angle < 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'start': + if (t.angle > 0) { + shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; + } + else { + shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; + } + break; + case 'middle': + // if (t.angle > 0) { + // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; + // } + // else { + // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; + // } + shim = -t.getHeight()/2; + break; + default: + shim = -t.getHeight()/2; + break; + } + } + else { + shim = -t.getHeight()/2; + } + + var val = this.u2p(t.value) + shim + 'px'; + t._elem.css('top', val); + t.pack(); + } + } + if (lshow) { + var h = this._label._elem.outerHeight(true); + if (this.name !== 'yMidAxis') { + this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); + } + if (this.name == 'yaxis') { + this._label._elem.css('left', '0px'); + } + else if (this.name !== 'yMidAxis') { + this._label._elem.css('right', '0px'); + } + this._label.pack(); + } + } + } + + ticks = null; + }; +})(jQuery); diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js new file mode 100644 index 0000000..e559ddc --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(e){e.jqplot.PyramidAxisRenderer=function(){e.jqplot.LinearAxisRenderer.call(this)};e.jqplot.PyramidAxisRenderer.prototype=new e.jqplot.LinearAxisRenderer();e.jqplot.PyramidAxisRenderer.prototype.constructor=e.jqplot.PyramidAxisRenderer;e.jqplot.PyramidAxisRenderer.prototype.init=function(f){this.position=null;this.drawBaseline=true;this.baselineWidth=null;this.baselineColor=null;this.tickSpacingFactor=25;this._type="pyramid";this._splitAxis=false;this._splitLength=null;this.category=false;this._autoFormatString="";this._overrideFormatString=false;e.extend(true,this,f);this.renderer.options=f;this.resetDataBounds=this.renderer.resetDataBounds;this.resetDataBounds()};e.jqplot.PyramidAxisRenderer.prototype.resetDataBounds=function(){var h=this._dataBounds;h.min=null;h.max=null;var g;for(var m=0;m<this._series.length;m++){var n=this._series[m];var o=n._plotData;for(var k=0,f=o.length;k<f;k++){if(this.name.charAt(0)==="x"){g=o[k][1];if((g!==null&&g<h.min)||h.min===null){h.min=g}if((g!==null&&g>h.max)||h.max===null){h.max=g}}else{g=o[k][0];if((g!==null&&g<h.min)||h.min===null){h.min=g}if((g!==null&&g>h.max)||h.max===null){h.max=g}}}}};e.jqplot.PyramidAxisRenderer.prototype.draw=function(f,n){if(this.show){this.renderer.createTicks.call(this,n);var m=0;var g;if(this._elem){this._elem.emptyForce();this._elem=null}this._elem=e(document.createElement("div"));this._elem.addClass("jqplot-axis jqplot-"+this.name);this._elem.css("position","absolute");if(this.name=="xaxis"||this.name=="x2axis"){this._elem.width(this._plotDimensions.width)}else{this._elem.height(this._plotDimensions.height)}this.labelOptions.axis=this.name;this._label=new this.labelRenderer(this.labelOptions);if(this._label.show){var l=this._label.draw(f,n);l.appendTo(this._elem);l=null}var k=this._ticks;var j;for(var h=0;h<k.length;h++){j=k[h];if(j.show&&j.showLabel&&(!j.isMinorTick)){this._elem.append(j.draw(f,n))}}j=null;k=null}return this._elem};var b=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997];var d={};for(var c=0,a=b.length;c<a;c++){d[b[c]]=b[c]}e.jqplot.PyramidAxisRenderer.prototype.createTicks=function(D){var J=this.ticks;var M=this._dataBounds;var E;var K;var B;var G;var y;var n;var k;var h;var H;var C;var x;var L=this.min;var N=this.max;var q;var v;var m;var g;var j;var O;var A;var F;var r;var P;var z=null;var I;if(J.length){for(H=0,C=J.length;H<C;H++){q=J[H];v=new this.tickRenderer(this.tickOptions);if(e.isArray(q)){v.value=q[0];v.label=q[1];v.setTick(q[0],this.name);this._ticks.push(v)}else{if(e.isPlainObject(q)){e.extend(true,v,q);v.axis=this.name;this._ticks.push(v)}else{if(typeof q==="string"){P=H+D.defaultAxisStart}else{P=q}v.value=P;v.label=q;v.axis=this.name;this._ticks.push(v)}}}this.numberTicks=J.length;this.min=this._ticks[0].value;this.max=this._ticks[this.numberTicks-1].value;this.tickInterval=(this.max-this.min)/(this.numberTicks-1);if(this._options.tickInterval){var o=this._options.tickInterval;for(H=0;H<this.numberTicks;H++){if(H%o!==0){this._ticks[H].isMinorTick=true}}}else{E=(this.name.charAt(0)==="x")?this._plotDimensions.width:this._plotDimensions.height;r=Math.round(2+E/this.tickSpacingFactor);if(this.numberTicks>r){I=this.numberTicks-1;for(H=2;H<I;H++){if(I%H===0&&I/H<r){z=H-1;break}}if(z!==null){var p=1;for(H=1,C=this._ticks.length;H<C;H++){if(p<=z){this._ticks[H].show=false;p+=1}else{p=1}}}}}I=[];if(this.category){this._ticks[0].showGridline=false;this._ticks[0].showMark=false;for(H=this._ticks.length-1;H>0;H--){v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[H-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks[H].showGridline=false;this._ticks[H].showMark=false;this._ticks.splice(H,0,v)}v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[0].value-this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.unshift(v);v=new this.tickRenderer(this.tickOptions);v.value=this._ticks[this._ticks.length-1].value+this.tickInterval/2;v.label="";v.showLabel=false;v.axis=this.name;this._ticks.push(v);this.tickInterval=this.tickInterval/2;this.numberTicks=this._ticks.length;this.min=this._ticks[0].value;this.max=this._ticks[this._ticks.length-1].value}}else{if(this.name.charAt(0)==="x"){E=this._plotDimensions.width;var w=Math.max(M.max,Math.abs(M.min));var u=Math.min(M.min,-w);B=u;G=w;y=G-B;if(this.tickOptions==null||!this.tickOptions.formatString){this._overrideFormatString=true}m=30;g=Math.max(E,m+1);j=(g-m)/300;O=e.jqplot.LinearTickGenerator(B,G,j);A=B+y*(this.padMin-1);F=G-y*(this.padMax-1);if(B<A||G>F){A=B-y*(this.padMin-1);F=G+y*(this.padMax-1);O=e.jqplot.LinearTickGenerator(A,F,j)}this.min=O[0];this.max=O[1];this.numberTicks=O[2];this._autoFormatString=O[3];this.tickInterval=O[4]}else{E=this._plotDimensions.height;B=M.min;G=M.max;x=this._series[0];this._ticks=[];y=G-B;if(d[y]){y+=1;G+=1}this.max=G;this.min=B;r=Math.round(2+E/this.tickSpacingFactor);if(y+1<=r){this.numberTicks=y+1;this.tickInterval=1}else{for(var H=r;H>1;H--){if(y/(H-1)===Math.round(y/(H-1))){this.numberTicks=H;this.tickInterval=y/(H-1);break}}}}if(this._overrideFormatString&&this._autoFormatString!=""){this.tickOptions=this.tickOptions||{};this.tickOptions.formatString=this._autoFormatString}var f;for(H=0;H<this.numberTicks;H++){this.tickOptions.axis=this.name;f=this.min+this.tickInterval*H;if(this.name.charAt(0)==="x"){f=Math.abs(f)}this.tickOptions.value=this.min+this.tickInterval*H;v=new this.tickRenderer(this.tickOptions);v.label=v.prefix+v.formatter(v.formatString,f);this._ticks.push(v);if(this.name.charAt(0)==="x"&&D.axes.yMidAxis.show&&this.tickOptions.value===0){this._splitAxis=true;this._splitLength=D.axes.yMidAxis.getWidth();v=new this.tickRenderer(this.tickOptions);this._ticks.push(v);v.value=this.max/2000}}v=null}};e.jqplot.PyramidAxisRenderer.prototype.set=function(){var o=0;var j;var g=0;var n=0;var m;var l;var k;var f=(this._label==null)?false:this._label.show;if(this.show){l=this._ticks;a=l.length;for(m=0;m<a;m++){k=l[m];if(!k._breakTick&&k.show&&k.showLabel&&!k.isMinorTick){if(this.name.charAt(0)==="x"){j=k._elem.outerHeight(true)}else{j=k._elem.outerWidth(true)}if(j>o){o=j}}}if(this.name==="yMidAxis"){for(m=0;m<a;m++){k=l[m];if(k._elem){j=(o-k._elem.outerWidth(true))/2;k._elem.css("left",j)}}}k=null;l=null;if(f){g=this._label._elem.outerWidth(true);n=this._label._elem.outerHeight(true)}if(this.name==="xaxis"){o=o+n;this._elem.css({height:o+"px",left:"0px",bottom:"0px"})}else{if(this.name==="x2axis"){o=o+n;this._elem.css({height:o+"px",left:"0px",top:"0px"})}else{if(this.name==="yaxis"){o=o+g;this._elem.css({width:o+"px",left:"0px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css("width",g+"px")}}else{if(this.name==="yMidAxis"){var j=o/2-g/2;this._elem.css({width:o+"px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css({width:g,left:j,top:0})}}else{o=o+g;this._elem.css({width:o+"px",right:"0px",top:"0px"});if(f&&this._label.constructor==e.jqplot.AxisLabelRenderer){this._label._elem.css("width",g+"px")}}}}}}};e.jqplot.PyramidAxisRenderer.prototype.pack=function(j,g){j=j||{};g=g||this._offsets;var B=this._ticks;var v=this.max;var u=this.min;var o=g.max;var m=g.min;var r=(this._label==null)?false:this._label.show;for(var s in j){this._elem.css(s,j[s])}this._offsets=g;var k=o-m;var l=v-u;var z=this._splitLength;if(this._splitAxis){k-=this._splitLength;this.p2u=function(h){return(h-m)*l/k+u};this.u2p=function(h){if(h<=0){return(h-u)*k/l+m}else{return(h-u)*k/l+m+z}};this.series_u2p=function(h){if(h<=0){return(h-u)*k/l}else{return(h-u)*k/l+z}};this.series_p2u=function(h){return h*l/k+u}}else{this.p2u=function(h){return(h-m)*l/k+u};this.u2p=function(h){return(h-u)*k/l+m};if(this.name.charAt(0)==="x"){this.series_u2p=function(h){return(h-u)*k/l};this.series_p2u=function(h){return h*l/k+u}}else{this.series_u2p=function(h){return(h-v)*k/l};this.series_p2u=function(h){return h*l/k+v}}}if(this.show){if(this.name.charAt(0)==="x"){for(var x=0;x<B.length;x++){var q=B[x];if(q.show&&q.showLabel){var f;if(q.constructor==e.jqplot.CanvasAxisTickRenderer&&q.angle){var A=(this.name=="xaxis")?1:-1;switch(q.labelPosition){case"auto":if(A*q.angle<0){f=-q.getWidth()+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2}else{f=-q._textRenderer.height*Math.sin(q._textRenderer.angle)/2}break;case"end":f=-q.getWidth()+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break;case"start":f=-q._textRenderer.height*Math.sin(q._textRenderer.angle)/2;break;case"middle":f=-q.getWidth()/2+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break;default:f=-q.getWidth()/2+q._textRenderer.height*Math.sin(-q._textRenderer.angle)/2;break}}else{f=-q.getWidth()/2}var C=this.u2p(q.value)+f+"px";q._elem.css("left",C);q.pack()}}if(r){var n=this._label._elem.outerWidth(true);this._label._elem.css("left",m+k/2-n/2+"px");if(this.name=="xaxis"){this._label._elem.css("bottom","0px")}else{this._label._elem.css("top","0px")}this._label.pack()}}else{for(var x=0;x<B.length;x++){var q=B[x];if(q.show&&q.showLabel&&!q.isMinorTick){var f;if(q.constructor==e.jqplot.CanvasAxisTickRenderer&&q.angle){var A=(this.name=="yaxis")?1:-1;switch(q.labelPosition){case"auto":case"end":if(A*q.angle<0){f=-q._textRenderer.height*Math.cos(-q._textRenderer.angle)/2}else{f=-q.getHeight()+q._textRenderer.height*Math.cos(q._textRenderer.angle)/2}break;case"start":if(q.angle>0){f=-q._textRenderer.height*Math.cos(-q._textRenderer.angle)/2}else{f=-q.getHeight()+q._textRenderer.height*Math.cos(q._textRenderer.angle)/2}break;case"middle":f=-q.getHeight()/2;break;default:f=-q.getHeight()/2;break}}else{f=-q.getHeight()/2}var C=this.u2p(q.value)+f+"px";q._elem.css("top",C);q.pack()}}if(r){var y=this._label._elem.outerHeight(true);if(this.name!=="yMidAxis"){this._label._elem.css("top",o-k/2-y/2+"px")}if(this.name=="yaxis"){this._label._elem.css("left","0px")}else{if(this.name!=="yMidAxis"){this._label._elem.css("right","0px")}}this._label.pack()}}}B=null}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.js new file mode 100644 index 0000000..aeea423 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.js @@ -0,0 +1,429 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + // Class: $.jqplot.CanvasGridRenderer + // The default jqPlot grid renderer, creating a grid on a canvas element. + // The renderer has no additional options beyond the <Grid> class. + $.jqplot.PyramidGridRenderer = function(){ + $.jqplot.CanvasGridRenderer.call(this); + }; + + $.jqplot.PyramidGridRenderer.prototype = new $.jqplot.CanvasGridRenderer(); + $.jqplot.PyramidGridRenderer.prototype.constructor = $.jqplot.PyramidGridRenderer; + + // called with context of Grid object + $.jqplot.CanvasGridRenderer.prototype.init = function(options) { + this._ctx; + this.plotBands = { + show: false, + color: 'rgb(230, 219, 179)', + axis: 'y', + start: null, + interval: 10 + }; + $.extend(true, this, options); + // set the shadow renderer options + var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; + this.renderer.shadowRenderer.init(sopts); + }; + + $.jqplot.PyramidGridRenderer.prototype.draw = function() { + this._ctx = this._elem.get(0).getContext("2d"); + var ctx = this._ctx; + var axes = this._axes; + var xp = axes.xaxis.u2p; + var yp = axes.yMidAxis.u2p; + var xnudge = axes.xaxis.max/1000.0; + var xp0 = xp(0); + var xpn = xp(xnudge); + var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis','yMidAxis']; + // Add the grid onto the grid canvas. This is the bottom most layer. + ctx.save(); + ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); + ctx.fillStyle = this.backgroundColor || this.background; + + ctx.fillRect(this._left, this._top, this._width, this._height); + + if (this.plotBands.show) { + ctx.save(); + var pb = this.plotBands; + ctx.fillStyle = pb.color; + var axis; + var x, y, w, h; + // find axis to work with + if (pb.axis.charAt(0) === 'x') { + if (axes.xaxis.show) { + axis = axes.xaxis; + } + } + else if (pb.axis.charAt(0) === 'y') { + if (axes.yaxis.show) { + axis = axes.yaxis; + } + else if (axes.y2axis.show) { + axis = axes.y2axis; + } + else if (axes.yMidAxis.show) { + axis = axes.yMidAxis; + } + } + + if (axis !== undefined) { + // draw some rectangles + var start = pb.start; + if (start === null) { + start = axis.min; + } + for (var i = start; i < axis.max; i += 2 * pb.interval) { + if (axis.name.charAt(0) === 'y') { + x = this._left; + if ((i + pb.interval) < axis.max) { + y = axis.series_u2p(i + pb.interval) + this._top; + } + else { + y = axis.series_u2p(axis.max) + this._top; + } + w = this._right - this._left; + h = axis.series_u2p(start) - axis.series_u2p(start + pb.interval); + ctx.fillRect(x, y, w, h); + } + // else { + // y = 0; + // x = axis.series_u2p(i); + // h = this._height; + // w = axis.series_u2p(start + pb.interval) - axis.series_u2p(start); + // } + + } + } + ctx.restore(); + } + + ctx.save(); + ctx.lineJoin = 'miter'; + ctx.lineCap = 'butt'; + ctx.lineWidth = this.gridLineWidth; + ctx.strokeStyle = this.gridLineColor; + var b, e, s, m; + for (var i=5; i>0; i--) { + var name = ax[i-1]; + var axis = axes[name]; + var ticks = axis._ticks; + var numticks = ticks.length; + if (axis.show) { + if (axis.drawBaseline) { + var bopts = {}; + if (axis.baselineWidth !== null) { + bopts.lineWidth = axis.baselineWidth; + } + if (axis.baselineColor !== null) { + bopts.strokeStyle = axis.baselineColor; + } + switch (name) { + case 'xaxis': + if (axes.yMidAxis.show) { + drawLine (this._left, this._bottom, xp0, this._bottom, bopts); + drawLine (xpn, this._bottom, this._right, this._bottom, bopts); + } + else { + drawLine (this._left, this._bottom, this._right, this._bottom, bopts); + } + break; + case 'yaxis': + drawLine (this._left, this._bottom, this._left, this._top, bopts); + break; + case 'yMidAxis': + drawLine(xp0, this._bottom, xp0, this._top, bopts); + drawLine(xpn, this._bottom, xpn, this._top, bopts); + break; + case 'x2axis': + if (axes.yMidAxis.show) { + drawLine (this._left, this._top, xp0, this._top, bopts); + drawLine (xpn, this._top, this._right, this._top, bopts); + } + else { + drawLine (this._left, this._bottom, this._right, this._bottom, bopts); + } + break; + case 'y2axis': + drawLine (this._right, this._bottom, this._right, this._top, bopts); + break; + + } + } + for (var j=numticks; j>0; j--) { + var t = ticks[j-1]; + if (t.show) { + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (name) { + case 'xaxis': + // draw the grid line if we should + if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) { + drawLine(pos, this._top, pos, this._bottom); + } + + // draw the mark + if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._bottom; + e = this._bottom+s; + break; + case 'inside': + b = this._bottom-s; + e = this._bottom; + break; + case 'cross': + b = this._bottom-s; + e = this._bottom+s; + break; + default: + b = this._bottom; + e = this._bottom+s; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); + } + // draw the line + drawLine(pos, b, pos, e); + } + break; + case 'yaxis': + // draw the grid line + if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) { + drawLine(this._right, pos, this._left, pos); + } + + // draw the mark + if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._left-s; + e = this._left; + break; + case 'inside': + b = this._left; + e = this._left+s; + break; + case 'cross': + b = this._left-s; + e = this._left+s; + break; + default: + b = this._left-s; + e = this._left; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + break; + case 'yMidAxis': + // draw the grid line + if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) { + drawLine(this._left, pos, xp0, pos); + drawLine(xpn, pos, this._right, pos); + } + // draw the mark + if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + + b = xp0; + e = xp0 + s; + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + + b = xpn - s; + e = xpn; + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + break; + case 'x2axis': + // draw the grid line + if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) { + drawLine(pos, this._bottom, pos, this._top); + } + + // draw the mark + if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._top-s; + e = this._top; + break; + case 'inside': + b = this._top; + e = this._top+s; + break; + case 'cross': + b = this._top-s; + e = this._top+s; + break; + default: + b = this._top-s; + e = this._top; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); + } + drawLine(pos, b, pos, e); + } + break; + case 'y2axis': + // draw the grid line + if (t.showGridline && this.drawGridlines && (!t.isMinorTick || axis.showMinorTicks)) { + drawLine(this._left, pos, this._right, pos); + } + + // draw the mark + if (t.showMark && t.mark && (!t.isMinorTick || axis.showMinorTicks)) { + s = t.markSize; + m = t.mark; + var pos = Math.round(axis.u2p(t.value)) + 0.5; + switch (m) { + case 'outside': + b = this._right; + e = this._right+s; + break; + case 'inside': + b = this._right-s; + e = this._right; + break; + case 'cross': + b = this._right-s; + e = this._right+s; + break; + default: + b = this._right; + e = this._right+s; + break; + } + // draw the shadow + if (this.shadow) { + this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); + } + drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); + } + break; + default: + break; + } + } + } + t = null; + } + axis = null; + ticks = null; + } + + ctx.restore(); + + function drawLine(bx, by, ex, ey, opts) { + ctx.save(); + opts = opts || {}; + if (opts.lineWidth == null || opts.lineWidth != 0){ + $.extend(true, ctx, opts); + ctx.beginPath(); + ctx.moveTo(bx, by); + ctx.lineTo(ex, ey); + ctx.stroke(); + } + ctx.restore(); + } + + if (this.shadow) { + if (axes.yMidAxis.show) { + var points = [[this._left, this._bottom], [xp0, this._bottom]]; + this.renderer.shadowRenderer.draw(ctx, points); + var points = [[xpn, this._bottom], [this._right, this._bottom], [this._right, this._top]]; + this.renderer.shadowRenderer.draw(ctx, points); + var points = [[xp0, this._bottom], [xp0, this._top]]; + this.renderer.shadowRenderer.draw(ctx, points); + } + else { + var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; + this.renderer.shadowRenderer.draw(ctx, points); + } + } + // Now draw border around grid. Use axis border definitions. start at + // upper left and go clockwise. + if (this.borderWidth != 0 && this.drawBorder) { + if (axes.yMidAxis.show) { + drawLine (this._left, this._top, xp0, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); + drawLine (xpn, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); + drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); + drawLine (this._right, this._bottom, xpn, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); + drawLine (xp0, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); + drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); + drawLine (xp0, this._bottom, xp0, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); + drawLine (xpn, this._bottom, xpn, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); + } + else { + drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); + drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); + drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); + drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); + } + } + // ctx.lineWidth = this.borderWidth; + // ctx.strokeStyle = this.borderColor; + // ctx.strokeRect(this._left, this._top, this._width, this._height); + + ctx.restore(); + ctx = null; + axes = null; + }; +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.min.js new file mode 100644 index 0000000..e2837a6 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidGridRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(a){a.jqplot.PyramidGridRenderer=function(){a.jqplot.CanvasGridRenderer.call(this)};a.jqplot.PyramidGridRenderer.prototype=new a.jqplot.CanvasGridRenderer();a.jqplot.PyramidGridRenderer.prototype.constructor=a.jqplot.PyramidGridRenderer;a.jqplot.CanvasGridRenderer.prototype.init=function(c){this._ctx;this.plotBands={show:false,color:"rgb(230, 219, 179)",axis:"y",start:null,interval:10};a.extend(true,this,c);var b={lineJoin:"miter",lineCap:"round",fill:false,isarc:false,angle:this.shadowAngle,offset:this.shadowOffset,alpha:this.shadowAlpha,depth:this.shadowDepth,lineWidth:this.shadowWidth,closePath:false,strokeStyle:this.shadowColor};this.renderer.shadowRenderer.init(b)};a.jqplot.PyramidGridRenderer.prototype.draw=function(){this._ctx=this._elem.get(0).getContext("2d");var D=this._ctx;var G=this._axes;var q=G.xaxis.u2p;var J=G.yMidAxis.u2p;var l=G.xaxis.max/1000;var u=q(0);var f=q(l);var r=["xaxis","yaxis","x2axis","y2axis","yMidAxis"];D.save();D.clearRect(0,0,this._plotDimensions.width,this._plotDimensions.height);D.fillStyle=this.backgroundColor||this.background;D.fillRect(this._left,this._top,this._width,this._height);if(this.plotBands.show){D.save();var c=this.plotBands;D.fillStyle=c.color;var d;var o,n,p,I;if(c.axis.charAt(0)==="x"){if(G.xaxis.show){d=G.xaxis}}else{if(c.axis.charAt(0)==="y"){if(G.yaxis.show){d=G.yaxis}else{if(G.y2axis.show){d=G.y2axis}else{if(G.yMidAxis.show){d=G.yMidAxis}}}}}if(d!==undefined){var g=c.start;if(g===null){g=d.min}for(var H=g;H<d.max;H+=2*c.interval){if(d.name.charAt(0)==="y"){o=this._left;if((H+c.interval)<d.max){n=d.series_u2p(H+c.interval)+this._top}else{n=d.series_u2p(d.max)+this._top}p=this._right-this._left;I=d.series_u2p(g)-d.series_u2p(g+c.interval);D.fillRect(o,n,p,I)}}}D.restore()}D.save();D.lineJoin="miter";D.lineCap="butt";D.lineWidth=this.gridLineWidth;D.strokeStyle=this.gridLineColor;var L,K,A,C;for(var H=5;H>0;H--){var O=r[H-1];var d=G[O];var M=d._ticks;var B=M.length;if(d.show){if(d.drawBaseline){var N={};if(d.baselineWidth!==null){N.lineWidth=d.baselineWidth}if(d.baselineColor!==null){N.strokeStyle=d.baselineColor}switch(O){case"xaxis":if(G.yMidAxis.show){z(this._left,this._bottom,u,this._bottom,N);z(f,this._bottom,this._right,this._bottom,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"yaxis":z(this._left,this._bottom,this._left,this._top,N);break;case"yMidAxis":z(u,this._bottom,u,this._top,N);z(f,this._bottom,f,this._top,N);break;case"x2axis":if(G.yMidAxis.show){z(this._left,this._top,u,this._top,N);z(f,this._top,this._right,this._top,N)}else{z(this._left,this._bottom,this._right,this._bottom,N)}break;case"y2axis":z(this._right,this._bottom,this._right,this._top,N);break}}for(var E=B;E>0;E--){var v=M[E-1];if(v.show){var k=Math.round(d.u2p(v.value))+0.5;switch(O){case"xaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._top,k,this._bottom)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._bottom;K=this._bottom+A;break;case"inside":L=this._bottom-A;K=this._bottom;break;case"cross":L=this._bottom-A;K=this._bottom+A;break;default:L=this._bottom;K=this._bottom+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"yaxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._right,k,this._left,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._left-A;K=this._left;break;case"inside":L=this._left;K=this._left+A;break;case"cross":L=this._left-A;K=this._left+A;break;default:L=this._left-A;K=this._left;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;case"yMidAxis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,u,k);z(f,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;L=u;K=u+A;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor});L=f-A;K=f;if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;case"x2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(k,this._bottom,k,this._top)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._top-A;K=this._top;break;case"inside":L=this._top;K=this._top+A;break;case"cross":L=this._top-A;K=this._top+A;break;default:L=this._top-A;K=this._top;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[k,L],[k,K]],{lineCap:"butt",lineWidth:this.gridLineWidth,offset:this.gridLineWidth*0.75,depth:2,fill:false,closePath:false})}z(k,L,k,K)}break;case"y2axis":if(v.showGridline&&this.drawGridlines&&(!v.isMinorTick||d.showMinorTicks)){z(this._left,k,this._right,k)}if(v.showMark&&v.mark&&(!v.isMinorTick||d.showMinorTicks)){A=v.markSize;C=v.mark;var k=Math.round(d.u2p(v.value))+0.5;switch(C){case"outside":L=this._right;K=this._right+A;break;case"inside":L=this._right-A;K=this._right;break;case"cross":L=this._right-A;K=this._right+A;break;default:L=this._right;K=this._right+A;break}if(this.shadow){this.renderer.shadowRenderer.draw(D,[[L,k],[K,k]],{lineCap:"butt",lineWidth:this.gridLineWidth*1.5,offset:this.gridLineWidth*0.75,fill:false,closePath:false})}z(L,k,K,k,{strokeStyle:d.borderColor})}break;default:break}}}v=null}d=null;M=null}D.restore();function z(j,i,e,b,h){D.save();h=h||{};if(h.lineWidth==null||h.lineWidth!=0){a.extend(true,D,h);D.beginPath();D.moveTo(j,i);D.lineTo(e,b);D.stroke()}D.restore()}if(this.shadow){if(G.yMidAxis.show){var F=[[this._left,this._bottom],[u,this._bottom]];this.renderer.shadowRenderer.draw(D,F);var F=[[f,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F);var F=[[u,this._bottom],[u,this._top]];this.renderer.shadowRenderer.draw(D,F)}else{var F=[[this._left,this._bottom],[this._right,this._bottom],[this._right,this._top]];this.renderer.shadowRenderer.draw(D,F)}}if(this.borderWidth!=0&&this.drawBorder){if(G.yMidAxis.show){z(this._left,this._top,u,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(f,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,f,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(u,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(u,this._bottom,u,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth});z(f,this._bottom,f,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}else{z(this._left,this._top,this._right,this._top,{lineCap:"round",strokeStyle:G.x2axis.borderColor,lineWidth:G.x2axis.borderWidth});z(this._right,this._top,this._right,this._bottom,{lineCap:"round",strokeStyle:G.y2axis.borderColor,lineWidth:G.y2axis.borderWidth});z(this._right,this._bottom,this._left,this._bottom,{lineCap:"round",strokeStyle:G.xaxis.borderColor,lineWidth:G.xaxis.borderWidth});z(this._left,this._bottom,this._left,this._top,{lineCap:"round",strokeStyle:G.yaxis.borderColor,lineWidth:G.yaxis.borderWidth})}}D.restore();D=null;G=null}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.js new file mode 100644 index 0000000..f230d9f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.js @@ -0,0 +1,514 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + // Need to ensure pyramid axis and grid renderers are loaded. + // You should load these with script tags in the html head, that is more efficient + // as the browser will cache the request. + // Note, have to block with synchronous request in order to execute bar renderer code. + if ($.jqplot.PyramidAxisRenderer === undefined) { + $.ajax({ + url: $.jqplot.pluginLocation + 'jqplot.pyramidAxisRenderer.js', + dataType: "script", + async: false + }); + } + + if ($.jqplot.PyramidGridRenderer === undefined) { + $.ajax({ + url: $.jqplot.pluginLocation + 'jqplot.pyramidGridRenderer.js', + dataType: "script", + async: false + }); + } + + $.jqplot.PyramidRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.PyramidRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.PyramidRenderer.prototype.constructor = $.jqplot.PyramidRenderer; + + // called with scope of a series + $.jqplot.PyramidRenderer.prototype.init = function(options, plot) { + options = options || {}; + this._type = 'pyramid'; + // Group: Properties + // + // prop: barPadding + this.barPadding = 10; + this.barWidth = null; + // prop: fill + // True to fill the bars. + this.fill = true; + // prop: highlightMouseOver + // True to highlight slice when moused over. + // This must be false to enable highlightMouseDown to highlight when clicking on a slice. + this.highlightMouseOver = true; + // prop: highlightMouseDown + // True to highlight when a mouse button is pressed over a slice. + // This will be disabled if highlightMouseOver is true. + this.highlightMouseDown = false; + // prop: highlightColors + // an array of colors to use when highlighting a slice. + this.highlightColors = []; + // prop highlightThreshold + // Expand the highlightable region in the x direction. + // E.g. a value of 3 will highlight a bar when the mouse is + // within 3 pixels of the bar in the x direction. + this.highlightThreshold = 2; + // prop: synchronizeHighlight + // Index of another series to highlight when this series is highlighted. + // null or false to not synchronize. + this.synchronizeHighlight = false; + // prop: offsetBars + // False will center bars on their y value. + // True will push bars up by 1/2 bar width to fill between their y values. + // If true, there needs to be 1 more tick than there are bars. + this.offsetBars = false; + + // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver + if (options.highlightMouseDown && options.highlightMouseOver == null) { + options.highlightMouseOver = false; + } + + this.side = 'right'; + + $.extend(true, this, options); + + // if (this.fill === false) { + // this.shadow = false; + // } + + if (this.side === 'left') { + this._highlightThreshold = [[-this.highlightThreshold, 0], [-this.highlightThreshold, 0], [0,0], [0,0]]; + } + + else { + this._highlightThreshold = [[0,0], [0,0], [this.highlightThreshold, 0], [this.highlightThreshold, 0]]; + } + + this.renderer.options = options; + // index of the currenty highlighted point, if any + this._highlightedPoint = null; + // Array of actual data colors used for each data point. + this._dataColors = []; + this._barPoints = []; + this.fillAxis = 'y'; + this._primaryAxis = '_yaxis'; + this._xnudge = 0; + + // set the shape renderer options + var opts = {lineJoin:'miter', lineCap:'butt', fill:this.fill, fillRect:this.fill, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill, lineWidth: this.lineWidth}; + this.renderer.shapeRenderer.init(opts); + // set the shadow renderer options + var shadow_offset = options.shadowOffset; + // set the shadow renderer options + if (shadow_offset == null) { + // scale the shadowOffset to the width of the line. + if (this.lineWidth > 2.5) { + shadow_offset = 1.25 * (1 + (Math.atan((this.lineWidth/2.5))/0.785398163 - 1)*0.6); + // var shadow_offset = this.shadowOffset; + } + // for skinny lines, don't make such a big shadow. + else { + shadow_offset = 1.25 * Math.atan((this.lineWidth/2.5))/0.785398163; + } + } + var sopts = {lineJoin:'miter', lineCap:'butt', fill:this.fill, fillRect:this.fill, isarc:false, angle:this.shadowAngle, offset:shadow_offset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill, lineWidth: this.lineWidth}; + this.renderer.shadowRenderer.init(sopts); + + plot.postDrawHooks.addOnce(postPlotDraw); + plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); + + // if this is the left side of pyramid, set y values to negative. + if (this.side === 'left') { + for (var i=0, l=this.data.length; i<l; i++) { + this.data[i][1] = -Math.abs(this.data[i][1]); + } + } + }; + + // setGridData + // converts the user data values to grid coordinates and stores them + // in the gridData array. + // Called with scope of a series. + $.jqplot.PyramidRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var data = this._plotData; + var pdata = this._prevPlotData; + this.gridData = []; + this._prevGridData = []; + var l = data.length; + var adjust = false; + var i; + + // if any data values are < 0, consider this a negative series + for (i = 0; i < l; i++) { + if (data[i][1] < 0) { + this.side = 'left'; + } + } + + if (this._yaxis.name === 'yMidAxis' && this.side === 'right') { + this._xnudge = this._xaxis.max/2000.0; + adjust = true; + } + + for (i = 0; i < l; i++) { + // if not a line series or if no nulls in data, push the converted point onto the array. + if (data[i][0] != null && data[i][1] != null) { + this.gridData.push([xp(data[i][1]), yp(data[i][0])]); + } + // else if there is a null, preserve it. + else if (data[i][0] == null) { + this.gridData.push([xp(data[i][1]), null]); + } + else if (data[i][1] == null) { + this.gridData.push(null, [yp(data[i][0])]); + } + // finally, adjust x grid data if have to + if (data[i][1] === 0 && adjust) { + this.gridData[i][0] = xp(this._xnudge); + } + } + }; + + // makeGridData + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.PyramidRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var gd = []; + var l = data.length; + var adjust = false; + var i; + + // if any data values are < 0, consider this a negative series + for (i = 0; i < l; i++) { + if (data[i][1] < 0) { + this.side = 'left'; + } + } + + if (this._yaxis.name === 'yMidAxis' && this.side === 'right') { + this._xnudge = this._xaxis.max/2000.0; + adjust = true; + } + + for (i = 0; i < l; i++) { + // if not a line series or if no nulls in data, push the converted point onto the array. + if (data[i][0] != null && data[i][1] != null) { + gd.push([xp(data[i][1]), yp(data[i][0])]); + } + // else if there is a null, preserve it. + else if (data[i][0] == null) { + gd.push([xp(data[i][1]), null]); + } + else if (data[i][1] == null) { + gd.push([null, yp(data[i][0])]); + } + // finally, adjust x grid data if have to + if (data[i][1] === 0 && adjust) { + gd[i][0] = xp(this._xnudge); + } + } + + return gd; + }; + + $.jqplot.PyramidRenderer.prototype.setBarWidth = function() { + // need to know how many data values we have on the approprate axis and figure it out. + var i; + var nvals = 0; + var nseries = 0; + var paxis = this[this._primaryAxis]; + var s, series, pos; + nvals = paxis.max - paxis.min; + var nticks = paxis.numberTicks; + var nbins = (nticks-1)/2; + // so, now we have total number of axis values. + var temp = (this.barPadding === 0) ? 1.0 : 0; + if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { + this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding + temp; + } + else { + if (this.fill) { + this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding + temp; + } + else { + this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals; + } + } + }; + + $.jqplot.PyramidRenderer.prototype.draw = function(ctx, gridData, options) { + var i; + // Ughhh, have to make a copy of options b/c it may be modified later. + var opts = $.extend({}, options); + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy; + // clear out data colors. + this._dataColors = []; + this._barPoints = []; + + if (this.renderer.options.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + // var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); + // var nvals = temp[0]; + // var nseries = temp[1]; + // var pos = temp[2]; + var points = [], + w, + h; + + // this._barNudge = 0; + + if (showLine) { + var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); + var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); + var negativeColor = negativeColors.get(this.index); + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var positiveColor = opts.fillStyle; + var base; + var xstart = this._xaxis.series_u2p(this._xnudge); + var ystart = this._yaxis.series_u2p(this._yaxis.min); + var yend = this._yaxis.series_u2p(this._yaxis.max); + var bw = this.barWidth; + var bw2 = bw/2.0; + var points = []; + var yadj = this.offsetBars ? bw2 : 0; + + for (var i=0, l=gridData.length; i<l; i++) { + if (this.data[i][0] == null) { + continue; + } + base = gridData[i][1]; + // not stacked and first series in stack + + if (this._plotData[i][1] < 0) { + if (this.varyBarColor && !this._stack) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + } + else { + if (this.varyBarColor && !this._stack) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + if (this.fill) { + + if (this._plotData[i][1] >= 0) { + // xstart = this._xaxis.series_u2p(this._xnudge); + w = gridData[i][0] - xstart; + h = this.barWidth; + points = [xstart, base - bw2 - yadj, w, h]; + } + else { + // xstart = this._xaxis.series_u2p(0); + w = xstart - gridData[i][0]; + h = this.barWidth; + points = [gridData[i][0], base - bw2 - yadj, w, h]; + } + + this._barPoints.push([[points[0], points[1] + h], [points[0], points[1]], [points[0] + w, points[1]], [points[0] + w, points[1] + h]]); + + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, points); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + + else { + if (i === 0) { + points =[[xstart, ystart], [gridData[i][0], ystart], [gridData[i][0], gridData[i][1] - bw2 - yadj]]; + } + + else if (i < l-1) { + points = points.concat([[gridData[i-1][0], gridData[i-1][1] - bw2 - yadj], [gridData[i][0], gridData[i][1] + bw2 - yadj], [gridData[i][0], gridData[i][1] - bw2 - yadj]]); + } + + // finally, draw the line + else { + points = points.concat([[gridData[i-1][0], gridData[i-1][1] - bw2 - yadj], [gridData[i][0], gridData[i][1] + bw2 - yadj], [gridData[i][0], yend], [xstart, yend]]); + + if (shadow) { + this.renderer.shadowRenderer.draw(ctx, points); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + } + } + + if (this.highlightColors.length == 0) { + this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors); + } + + else if (typeof(this.highlightColors) == 'string') { + this.highlightColors = []; + for (var i=0; i<this._dataColors.length; i++) { + this.highlightColors.push(this.highlightColors); + } + } + + }; + + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = options.axesDefaults || {}; + options.grid = options.grid || {}; + options.legend = options.legend || {}; + options.seriesDefaults = options.seriesDefaults || {}; + // only set these if there is a pie series + var setopts = false; + if (options.seriesDefaults.renderer === $.jqplot.PyramidRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer === $.jqplot.PyramidRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.PyramidAxisRenderer; + options.grid.renderer = $.jqplot.PyramidGridRenderer; + options.seriesDefaults.pointLabels = {show: false}; + } + } + + // called within context of plot + // create a canvas which we can draw on. + // insert it before the eventCanvas, so eventCanvas will still capture events. + function postPlotDraw() { + // Memory Leaks patch + if (this.plugins.pyramidRenderer && this.plugins.pyramidRenderer.highlightCanvas) { + + this.plugins.pyramidRenderer.highlightCanvas.resetCanvas(); + this.plugins.pyramidRenderer.highlightCanvas = null; + } + + this.plugins.pyramidRenderer = {highlightedSeriesIndex:null}; + this.plugins.pyramidRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); + + this.eventCanvas._elem.before(this.plugins.pyramidRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pyramidRenderer-highlight-canvas', this._plotDimensions, this)); + this.plugins.pyramidRenderer.highlightCanvas.setContext(); + this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); + } + + function highlight (plot, sidx, pidx, points) { + var s = plot.series[sidx]; + var canvas = plot.plugins.pyramidRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); + s._highlightedPoint = pidx; + plot.plugins.pyramidRenderer.highlightedSeriesIndex = sidx; + var opts = {fillStyle: s.highlightColors[pidx], fillRect: false}; + s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); + if (s.synchronizeHighlight !== false && plot.series.length >= s.synchronizeHighlight && s.synchronizeHighlight !== sidx) { + s = plot.series[s.synchronizeHighlight]; + opts = {fillStyle: s.highlightColors[pidx], fillRect: false}; + s.renderer.shapeRenderer.draw(canvas._ctx, s._barPoints[pidx], opts); + } + canvas = null; + } + + function unhighlight (plot) { + var canvas = plot.plugins.pyramidRenderer.highlightCanvas; + canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); + for (var i=0; i<plot.series.length; i++) { + plot.series[i]._highlightedPoint = null; + } + plot.plugins.pyramidRenderer.highlightedSeriesIndex = null; + plot.target.trigger('jqplotDataUnhighlight'); + canvas = null; + } + + + function handleMove(ev, gridpos, datapos, neighbor, plot) { + if (neighbor) { + var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; + var evt1 = jQuery.Event('jqplotDataMouseOver'); + evt1.pageX = ev.pageX; + evt1.pageY = ev.pageY; + plot.target.trigger(evt1, ins); + if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pyramidRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { + var evt = jQuery.Event('jqplotDataHighlight'); + evt.which = ev.which; + evt.pageX = ev.pageX; + evt.pageY = ev.pageY; + plot.target.trigger(evt, ins); + highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); + } + } + else if (neighbor == null) { + unhighlight (plot); + } + } + + // Have to add hook here, becuase it needs called before series is inited. + $.jqplot.preInitHooks.push(preInit); + + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.min.js new file mode 100644 index 0000000..5833af5 --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.pyramidRenderer.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(c){if(c.jqplot.PyramidAxisRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidAxisRenderer.js",dataType:"script",async:false})}if(c.jqplot.PyramidGridRenderer===undefined){c.ajax({url:c.jqplot.pluginLocation+"jqplot.pyramidGridRenderer.js",dataType:"script",async:false})}c.jqplot.PyramidRenderer=function(){c.jqplot.LineRenderer.call(this)};c.jqplot.PyramidRenderer.prototype=new c.jqplot.LineRenderer();c.jqplot.PyramidRenderer.prototype.constructor=c.jqplot.PyramidRenderer;c.jqplot.PyramidRenderer.prototype.init=function(j,o){j=j||{};this._type="pyramid";this.barPadding=10;this.barWidth=null;this.fill=true;this.highlightMouseOver=true;this.highlightMouseDown=false;this.highlightColors=[];this.highlightThreshold=2;this.synchronizeHighlight=false;this.offsetBars=false;if(j.highlightMouseDown&&j.highlightMouseOver==null){j.highlightMouseOver=false}this.side="right";c.extend(true,this,j);if(this.side==="left"){this._highlightThreshold=[[-this.highlightThreshold,0],[-this.highlightThreshold,0],[0,0],[0,0]]}else{this._highlightThreshold=[[0,0],[0,0],[this.highlightThreshold,0],[this.highlightThreshold,0]]}this.renderer.options=j;this._highlightedPoint=null;this._dataColors=[];this._barPoints=[];this.fillAxis="y";this._primaryAxis="_yaxis";this._xnudge=0;var n={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,strokeStyle:this.color,fillStyle:this.color,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shapeRenderer.init(n);var m=j.shadowOffset;if(m==null){if(this.lineWidth>2.5){m=1.25*(1+(Math.atan((this.lineWidth/2.5))/0.785398163-1)*0.6)}else{m=1.25*Math.atan((this.lineWidth/2.5))/0.785398163}}var h={lineJoin:"miter",lineCap:"butt",fill:this.fill,fillRect:this.fill,isarc:false,angle:this.shadowAngle,offset:m,alpha:this.shadowAlpha,depth:this.shadowDepth,closePath:this.fill,lineWidth:this.lineWidth};this.renderer.shadowRenderer.init(h);o.postDrawHooks.addOnce(f);o.eventListenerHooks.addOnce("jqplotMouseMove",e);if(this.side==="left"){for(var k=0,g=this.data.length;k<g;k++){this.data[k][1]=-Math.abs(this.data[k][1])}}};c.jqplot.PyramidRenderer.prototype.setGridData=function(p){var j=this._xaxis.series_u2p;var o=this._yaxis.series_u2p;var k=this._plotData;var n=this._prevPlotData;this.gridData=[];this._prevGridData=[];var g=k.length;var m=false;var h;for(h=0;h<g;h++){if(k[h][1]<0){this.side="left"}}if(this._yaxis.name==="yMidAxis"&&this.side==="right"){this._xnudge=this._xaxis.max/2000;m=true}for(h=0;h<g;h++){if(k[h][0]!=null&&k[h][1]!=null){this.gridData.push([j(k[h][1]),o(k[h][0])])}else{if(k[h][0]==null){this.gridData.push([j(k[h][1]),null])}else{if(k[h][1]==null){this.gridData.push(null,[o(k[h][0])])}}}if(k[h][1]===0&&m){this.gridData[h][0]=j(this._xnudge)}}};c.jqplot.PyramidRenderer.prototype.makeGridData=function(m,p){var k=this._xaxis.series_u2p;var o=this._yaxis.series_u2p;var j=[];var g=m.length;var n=false;var h;for(h=0;h<g;h++){if(m[h][1]<0){this.side="left"}}if(this._yaxis.name==="yMidAxis"&&this.side==="right"){this._xnudge=this._xaxis.max/2000;n=true}for(h=0;h<g;h++){if(m[h][0]!=null&&m[h][1]!=null){j.push([k(m[h][1]),o(m[h][0])])}else{if(m[h][0]==null){j.push([k(m[h][1]),null])}else{if(m[h][1]==null){j.push([null,o(m[h][0])])}}}if(m[h][1]===0&&n){j[h][0]=k(this._xnudge)}}return j};c.jqplot.PyramidRenderer.prototype.setBarWidth=function(){var k;var g=0;var h=0;var m=this[this._primaryAxis];var q,l,o;g=m.max-m.min;var n=m.numberTicks;var j=(n-1)/2;var p=(this.barPadding===0)?1:0;if(m.name=="xaxis"||m.name=="x2axis"){this.barWidth=(m._offsets.max-m._offsets.min)/g-this.barPadding+p}else{if(this.fill){this.barWidth=(m._offsets.min-m._offsets.max)/g-this.barPadding+p}else{this.barWidth=(m._offsets.min-m._offsets.max)/g}}};c.jqplot.PyramidRenderer.prototype.draw=function(B,I,k){var E;var u=c.extend({},k);var p=(u.shadow!=undefined)?u.shadow:this.shadow;var K=(u.showLine!=undefined)?u.showLine:this.showLine;var C=(u.fill!=undefined)?u.fill:this.fill;var t=this._xaxis.series_u2p;var G=this._yaxis.series_u2p;var z,x;this._dataColors=[];this._barPoints=[];if(this.renderer.options.barWidth==null){this.renderer.setBarWidth.call(this)}var D=[],s,F;if(K){var q=new c.jqplot.ColorGenerator(this.negativeSeriesColors);var v=new c.jqplot.ColorGenerator(this.seriesColors);var J=q.get(this.index);if(!this.useNegativeColors){J=u.fillStyle}var o=u.fillStyle;var n;var L=this._xaxis.series_u2p(this._xnudge);var j=this._yaxis.series_u2p(this._yaxis.min);var m=this._yaxis.series_u2p(this._yaxis.max);var H=this.barWidth;var y=H/2;var D=[];var r=this.offsetBars?y:0;for(var E=0,A=I.length;E<A;E++){if(this.data[E][0]==null){continue}n=I[E][1];if(this._plotData[E][1]<0){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){u.fillStyle=q.next()}else{u.fillStyle=v.next()}}}else{if(this.varyBarColor&&!this._stack){u.fillStyle=v.next()}else{u.fillStyle=o}}if(this.fill){if(this._plotData[E][1]>=0){s=I[E][0]-L;F=this.barWidth;D=[L,n-y-r,s,F]}else{s=L-I[E][0];F=this.barWidth;D=[I[E][0],n-y-r,s,F]}this._barPoints.push([[D[0],D[1]+F],[D[0],D[1]],[D[0]+s,D[1]],[D[0]+s,D[1]+F]]);if(p){this.renderer.shadowRenderer.draw(B,D)}var g=u.fillStyle||this.color;this._dataColors.push(g);this.renderer.shapeRenderer.draw(B,D,u)}else{if(E===0){D=[[L,j],[I[E][0],j],[I[E][0],I[E][1]-y-r]]}else{if(E<A-1){D=D.concat([[I[E-1][0],I[E-1][1]-y-r],[I[E][0],I[E][1]+y-r],[I[E][0],I[E][1]-y-r]])}else{D=D.concat([[I[E-1][0],I[E-1][1]-y-r],[I[E][0],I[E][1]+y-r],[I[E][0],m],[L,m]]);if(p){this.renderer.shadowRenderer.draw(B,D)}var g=u.fillStyle||this.color;this._dataColors.push(g);this.renderer.shapeRenderer.draw(B,D,u)}}}}}if(this.highlightColors.length==0){this.highlightColors=c.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){this.highlightColors=[];for(var E=0;E<this._dataColors.length;E++){this.highlightColors.push(this.highlightColors)}}}};function b(l,k,h){h=h||{};h.axesDefaults=h.axesDefaults||{};h.grid=h.grid||{};h.legend=h.legend||{};h.seriesDefaults=h.seriesDefaults||{};var g=false;if(h.seriesDefaults.renderer===c.jqplot.PyramidRenderer){g=true}else{if(h.series){for(var j=0;j<h.series.length;j++){if(h.series[j].renderer===c.jqplot.PyramidRenderer){g=true}}}}if(g){h.axesDefaults.renderer=c.jqplot.PyramidAxisRenderer;h.grid.renderer=c.jqplot.PyramidGridRenderer;h.seriesDefaults.pointLabels={show:false}}}function f(){if(this.plugins.pyramidRenderer&&this.plugins.pyramidRenderer.highlightCanvas){this.plugins.pyramidRenderer.highlightCanvas.resetCanvas();this.plugins.pyramidRenderer.highlightCanvas=null}this.plugins.pyramidRenderer={highlightedSeriesIndex:null};this.plugins.pyramidRenderer.highlightCanvas=new c.jqplot.GenericCanvas();this.eventCanvas._elem.before(this.plugins.pyramidRenderer.highlightCanvas.createElement(this._gridPadding,"jqplot-pyramidRenderer-highlight-canvas",this._plotDimensions,this));this.plugins.pyramidRenderer.highlightCanvas.setContext();this.eventCanvas._elem.bind("mouseleave",{plot:this},function(g){d(g.data.plot)})}function a(m,l,j,i){var h=m.series[l];var g=m.plugins.pyramidRenderer.highlightCanvas;g._ctx.clearRect(0,0,g._ctx.canvas.width,g._ctx.canvas.height);h._highlightedPoint=j;m.plugins.pyramidRenderer.highlightedSeriesIndex=l;var k={fillStyle:h.highlightColors[j],fillRect:false};h.renderer.shapeRenderer.draw(g._ctx,i,k);if(h.synchronizeHighlight!==false&&m.series.length>=h.synchronizeHighlight&&h.synchronizeHighlight!==l){h=m.series[h.synchronizeHighlight];k={fillStyle:h.highlightColors[j],fillRect:false};h.renderer.shapeRenderer.draw(g._ctx,h._barPoints[j],k)}g=null}function d(j){var g=j.plugins.pyramidRenderer.highlightCanvas;g._ctx.clearRect(0,0,g._ctx.canvas.width,g._ctx.canvas.height);for(var h=0;h<j.series.length;h++){j.series[h]._highlightedPoint=null}j.plugins.pyramidRenderer.highlightedSeriesIndex=null;j.target.trigger("jqplotDataUnhighlight");g=null}function e(k,j,n,m,l){if(m){var i=[m.seriesIndex,m.pointIndex,m.data];var h=jQuery.Event("jqplotDataMouseOver");h.pageX=k.pageX;h.pageY=k.pageY;l.target.trigger(h,i);if(l.series[i[0]].highlightMouseOver&&!(i[0]==l.plugins.pyramidRenderer.highlightedSeriesIndex&&i[1]==l.series[i[0]]._highlightedPoint)){var g=jQuery.Event("jqplotDataHighlight");g.which=k.which;g.pageX=k.pageX;g.pageY=k.pageY;l.target.trigger(g,i);a(l,m.seriesIndex,m.pointIndex,m.points)}}else{if(m==null){d(l)}}}c.jqplot.preInitHooks.push(b)})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.js new file mode 100644 index 0000000..666498a --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.js @@ -0,0 +1,223 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.8 + * Revision: 1250 + * + * Copyright (c) 2009-2013 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + + /** + * Class: $.jqplot.Trendline + * Plugin which will automatically compute and draw trendlines for plotted data. + */ + $.jqplot.Trendline = function() { + // Group: Properties + + // prop: show + // Wether or not to show the trend line. + this.show = $.jqplot.config.enablePlugins; + // prop: color + // CSS color spec for the trend line. + // By default this wil be the same color as the primary line. + this.color = '#666666'; + // prop: renderer + // Renderer to use to draw the trend line. + // The data series that is plotted may not be rendered as a line. + // Therefore, we use our own line renderer here to draw a trend line. + this.renderer = new $.jqplot.LineRenderer(); + // prop: rendererOptions + // Options to pass to the line renderer. + // By default, markers are not shown on trend lines. + this.rendererOptions = {marker:{show:false}}; + // prop: label + // Label for the trend line to use in the legend. + this.label = ''; + // prop: type + // Either 'exponential', 'exp', or 'linear'. + this.type = 'linear'; + // prop: shadow + // true or false, whether or not to show the shadow. + this.shadow = true; + // prop: markerRenderer + // Renderer to use to draw markers on the line. + // I think this is wrong. + this.markerRenderer = {show:false}; + // prop: lineWidth + // Width of the trend line. + this.lineWidth = 1.5; + // prop: shadowAngle + // Angle of the shadow on the trend line. + this.shadowAngle = 45; + // prop: shadowOffset + // pixel offset for each stroke of the shadow. + this.shadowOffset = 1.0; + // prop: shadowAlpha + // Alpha transparency of the shadow. + this.shadowAlpha = 0.07; + // prop: shadowDepth + // number of strokes to make of the shadow. + this.shadowDepth = 3; + this.isTrendline = true; + + }; + + $.jqplot.postSeriesInitHooks.push(parseTrendLineOptions); + $.jqplot.postDrawSeriesHooks.push(drawTrendline); + $.jqplot.addLegendRowHooks.push(addTrendlineLegend); + + // called witin scope of the legend object + // current series passed in + // must return null or an object {label:label, color:color} + function addTrendlineLegend(series) { + var ret = null; + if (series.trendline && series.trendline.show) { + var lt = series.trendline.label.toString(); + if (lt) { + ret = {label:lt, color:series.trendline.color}; + } + } + return ret; + } + + // called within scope of a series + function parseTrendLineOptions (target, data, seriesDefaults, options, plot) { + if (this._type && (this._type === 'line' || this._type == 'bar')) { + this.trendline = new $.jqplot.Trendline(); + options = options || {}; + $.extend(true, this.trendline, {color:this.color}, seriesDefaults.trendline, options.trendline); + this.trendline.renderer.init.call(this.trendline, null); + } + } + + // called within scope of series object + function drawTrendline(sctx, options) { + // if we have options, merge trendline options in with precedence + options = $.extend(true, {}, this.trendline, options); + + if (this.trendline && options.show) { + var fit; + // this.renderer.setGridData.call(this); + var data = options.data || this.data; + fit = fitData(data, this.trendline.type); + var gridData = options.gridData || this.renderer.makeGridData.call(this, fit.data); + this.trendline.renderer.draw.call(this.trendline, sctx, gridData, {showLine:true, shadow:this.trendline.shadow}); + } + } + + function regression(x, y, typ) { + var type = (typ == null) ? 'linear' : typ; + var N = x.length; + var slope; + var intercept; + var SX = 0; + var SY = 0; + var SXX = 0; + var SXY = 0; + var SYY = 0; + var Y = []; + var X = []; + + if (type == 'linear') { + X = x; + Y = y; + } + else if (type == 'exp' || type == 'exponential') { + for ( var i=0; i<y.length; i++) { + // ignore points <= 0, log undefined. + if (y[i] <= 0) { + N--; + } + else { + X.push(x[i]); + Y.push(Math.log(y[i])); + } + } + } + + for ( var i = 0; i < N; i++) { + SX = SX + X[i]; + SY = SY + Y[i]; + SXY = SXY + X[i]* Y[i]; + SXX = SXX + X[i]* X[i]; + SYY = SYY + Y[i]* Y[i]; + } + + slope = (N*SXY - SX*SY)/(N*SXX - SX*SX); + intercept = (SY - slope*SX)/N; + + return [slope, intercept]; + } + + function linearRegression(X,Y) { + var ret; + ret = regression(X,Y,'linear'); + return [ret[0],ret[1]]; + } + + function expRegression(X,Y) { + var ret; + var x = X; + var y = Y; + ret = regression(x, y,'exp'); + var base = Math.exp(ret[0]); + var coeff = Math.exp(ret[1]); + return [base, coeff]; + } + + function fitData(data, typ) { + var type = (typ == null) ? 'linear' : typ; + var ret; + var res; + var x = []; + var y = []; + var ypred = []; + + for (i=0; i<data.length; i++){ + if (data[i] != null && data[i][0] != null && data[i][1] != null) { + x.push(data[i][0]); + y.push(data[i][1]); + } + } + + if (type == 'linear') { + ret = linearRegression(x,y); + for ( var i=0; i<x.length; i++){ + res = ret[0]*x[i] + ret[1]; + ypred.push([x[i], res]); + } + } + else if (type == 'exp' || type == 'exponential') { + ret = expRegression(x,y); + for ( var i=0; i<x.length; i++){ + res = ret[1]*Math.pow(ret[0],x[i]); + ypred.push([x[i], res]); + } + } + return {data: ypred, slope: ret[0], intercept: ret[1]}; + } + +})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.min.js b/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.min.js new file mode 100644 index 0000000..5867e2f --- /dev/null +++ b/AvocadoEdition/plugin/jqplot/plugins/jqplot.trendline.min.js @@ -0,0 +1,3 @@ +/* jqPlot 1.0.8r1250 | (c) 2009-2013 Chris Leonello | jplot.com + jsDate | (c) 2010-2013 Chris Leonello + */(function(f){f.jqplot.Trendline=function(){this.show=f.jqplot.config.enablePlugins;this.color="#666666";this.renderer=new f.jqplot.LineRenderer();this.rendererOptions={marker:{show:false}};this.label="";this.type="linear";this.shadow=true;this.markerRenderer={show:false};this.lineWidth=1.5;this.shadowAngle=45;this.shadowOffset=1;this.shadowAlpha=0.07;this.shadowDepth=3;this.isTrendline=true};f.jqplot.postSeriesInitHooks.push(e);f.jqplot.postDrawSeriesHooks.push(g);f.jqplot.addLegendRowHooks.push(a);function a(k){var j=null;if(k.trendline&&k.trendline.show){var i=k.trendline.label.toString();if(i){j={label:i,color:k.trendline.color}}}return j}function e(m,k,j,i,l){if(this._type&&(this._type==="line"||this._type=="bar")){this.trendline=new f.jqplot.Trendline();i=i||{};f.extend(true,this.trendline,{color:this.color},j.trendline,i.trendline);this.trendline.renderer.init.call(this.trendline,null)}}function g(m,i){i=f.extend(true,{},this.trendline,i);if(this.trendline&&i.show){var k;var l=i.data||this.data;k=c(l,this.trendline.type);var j=i.gridData||this.renderer.makeGridData.call(this,k.data);this.trendline.renderer.draw.call(this.trendline,m,j,{showLine:true,shadow:this.trendline.shadow})}}function b(w,v,n){var u=(n==null)?"linear":n;var s=w.length;var t;var z;var o=0;var m=0;var r=0;var q=0;var l=0;var j=[];var k=[];if(u=="linear"){k=w;j=v}else{if(u=="exp"||u=="exponential"){for(var p=0;p<v.length;p++){if(v[p]<=0){s--}else{k.push(w[p]);j.push(Math.log(v[p]))}}}}for(var p=0;p<s;p++){o=o+k[p];m=m+j[p];q=q+k[p]*j[p];r=r+k[p]*k[p];l=l+j[p]*j[p]}t=(s*q-o*m)/(s*r-o*o);z=(m-t*o)/s;return[t,z]}function h(k,j){var i;i=b(k,j,"linear");return[i[0],i[1]]}function d(o,m){var k;var i=o;var n=m;k=b(i,n,"exp");var l=Math.exp(k[0]);var j=Math.exp(k[1]);return[l,j]}function c(l,j){var p=(j==null)?"linear":j;var n;var o;var r=[];var q=[];var m=[];for(k=0;k<l.length;k++){if(l[k]!=null&&l[k][0]!=null&&l[k][1]!=null){r.push(l[k][0]);q.push(l[k][1])}}if(p=="linear"){n=h(r,q);for(var k=0;k<r.length;k++){o=n[0]*r[k]+n[1];m.push([r[k],o])}}else{if(p=="exp"||p=="exponential"){n=d(r,q);for(var k=0;k<r.length;k++){o=n[1]*Math.pow(n[0],r[k]);m.push([r[k],o])}}}return{data:m,slope:n[0],intercept:n[1]}}})(jQuery); \ No newline at end of file diff --git a/AvocadoEdition/plugin/jquery-ui/datepicker.php b/AvocadoEdition/plugin/jquery-ui/datepicker.php new file mode 100644 index 0000000..71f3df6 --- /dev/null +++ b/AvocadoEdition/plugin/jquery-ui/datepicker.php @@ -0,0 +1,30 @@ +<?php +if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 + +add_stylesheet('<link type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/themes/base/jquery-ui.css" rel="stylesheet" />', 0); +add_stylesheet('<link type="text/css" href="'.G5_PLUGIN_URL.'/jquery-ui/style.css">', 0); +?> + +<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.min.js"></script> +<script> +jQuery(function($){ + $.datepicker.regional["ko"] = { + closeText: "닫기", + prevText: "이전달", + nextText: "다음달", + currentText: "오늘", + monthNames: ["1월(JAN)","2월(FEB)","3월(MAR)","4월(APR)","5월(MAY)","6월(JUN)", "7월(JUL)","8월(AUG)","9월(SEP)","10월(OCT)","11월(NOV)","12월(DEC)"], + monthNamesShort: ["1월","2월","3월","4월","5월","6월", "7월","8월","9월","10월","11월","12월"], + dayNames: ["일","월","화","수","목","금","토"], + dayNamesShort: ["일","월","화","수","목","금","토"], + dayNamesMin: ["일","월","화","수","목","금","토"], + weekHeader: "Wk", + dateFormat: "yymmdd", + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "" + }; + $.datepicker.setDefaults($.datepicker.regional["ko"]); +}); +</script> \ No newline at end of file diff --git a/AvocadoEdition/plugin/jquery-ui/style.css b/AvocadoEdition/plugin/jquery-ui/style.css new file mode 100644 index 0000000..528a547 --- /dev/null +++ b/AvocadoEdition/plugin/jquery-ui/style.css @@ -0,0 +1,6 @@ +@charset "utf-8"; + +.ui-datepicker { font:12px dotum; } +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 70px;} +.ui-datepicker-trigger { margin:0 0 -5px 2px; } \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/_common.php b/AvocadoEdition/plugin/kcaptcha/_common.php new file mode 100644 index 0000000..bad54a5 --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/_common.php @@ -0,0 +1,3 @@ +<?php +include_once('../../common.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/captcha.lib.php b/AvocadoEdition/plugin/kcaptcha/captcha.lib.php new file mode 100644 index 0000000..ea2179e --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/captcha.lib.php @@ -0,0 +1,3 @@ +<?php +require(dirname(__FILE__).'/kcaptcha.lib.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/fonts/palatino_linotype_bold.png b/AvocadoEdition/plugin/kcaptcha/fonts/palatino_linotype_bold.png new file mode 100644 index 0000000000000000000000000000000000000000..76e653ad71afa37e9655c3f3934c5f1bb0a683dc GIT binary patch literal 15512 zcmcgzhc{f^*Cx8CA<<hz3lSxH3!?WHB!&or$YAs~dWhbm_ZDqLAEHGsiQb|!1fz^L zhQZ9|eZR7Pf5ErbU3cAe*1GqebM`)G@BN(TiPG0qBPV4f#lgWL*HC|Dh=W5wd-tqL zOn7(i$e?e)!C}YIc%^9UlXIA>Q_V8yS<t11-ynql*ZdDb=+uV~4}A`J?1FJc7~A^a ziPNZYKP0>Ng!MXFm<nJ0iQ(!ZcV0#f=Oh`Gt#wqRDsKH3t~alPe|ArCaS;*|3TyPA zPIW#h`b3zd@jk<(Kq96RCJksoccE9WS7q2Hc2Q_AZ<G1)3Zrsele(4`H8{>inKZm- zX3(_rG_C1#2gzCx)pTH20CvXlJKM;*;%{tiz&5{AE#5vPNO=@SdsR>3Y3;yZ?j2ao ziFIerHiVd(m$eNzYOh$?u~J0sJnf<P_o%ow>hxz>leP1e`E|0G>T@19Exjpj*Rd4d zo+;f9k=BCP%x*VpF*+Oi0@Tn4E$5#|{nHNLy|vV3NH>{Zsz`Wd<x18o^q<!osrn;g z`Uva)xaxw0!ixU0!J0l-`2Vrx>T})mg~i1YYRbE=7Rzvb$FsP11QFxD&Q5uW+ur!s zr#ck)jxfLw;7?#y%_(vne9u(=Z};z}fxd4xM3MyULw|>U0xeow@3+_eh5kFPI_rbO z!x|Y<-#<%BOrHNVr5N3_59aTddpFLu<P<v{Sc2~rQWgF}mW=#Q?8nw58}B&K;tNs> zX#kFMgOsE3Cj8bUs9Hu|=RgQ(;jKRUQ^Z{oOog{8=&IGf2WN!Y{`1X&2$4BVv*Vxx zrOI8$Ir#~W$slJIIQfoHZ=-fM@uUYnQ~CGTC$p}Ps=1||Y$DEH;a|!hE9X#enXlVB zMNf0P68eytipTQ=b}551%^&iF%ojTif<Tzl5u52>6k}h!i~%z7RYCbo$DP1+f!}V& zWms@pPTz1EOAvEhU{^l$!@r{iu`_(qUtU~X<mNRN`3$$0BtUTQ@9pOG=>%Op(524( z$oO_6!4v$0cOgM#-sSR`jwaGdEh=Wo26MwOu%o;|`5UlUUeG`O%nZ<$Du1ANg|)I@ zNR`SIpY01pBa)>TcQPTgP{fU~$89;3FVtpjO;w`_qp@H}gc2n<j@w=ImsFlGu|Q)+ zKNdGW_f7VY9t-gf4(cu4d0$%h=9y@y@QDn5tJ$T~bq6GNqkk7G(=E1+T^|{yGZR#( z`Wvc%<vZ>INiStfvg~+@J82$1%;7k!4esjeM?N0=CfWOJd?J$N>ok^I&}FsoDbdbt zu}nsTG5G`vw5_@&+D-YIp6y>Bk3|Z<i+0Dg_}~jS4zREmo7VR-%PVS(6dl;IWs)f6 zqTumd?%|t|;!_XWsqAstR8qDW(Dhve`grHtz#ZR<T4d^d1}9j1a^!u@+@}|Pxc_9< z5ujuDotavfv?8pcA{!0;{c$wNxo=u+2YWZay&@*wWIX1&gJ*CQjQOA<3Seu0<mINo zVdSooCx;VXu~rI@X+VF&)ulMtAS4w_uFV!lN^zwO^fj^1SWWt`9#H+A8A>L31CeF9 z?Toszp&!6}m|b0nu-5KtE9c#jM>EoR5^dv-=B7}(YJNRBwo)&FnUUrsvoX!Da`F1w z4IGc@-<B=O=iG<B_=5}@Tnmh`L$q=9vGg)Q$0nRTEDE!@O)~=Hnvy@Ft-2Z9-S}ot z^Qz#`pKgD&7}6T26w=%jinEhYBf;KU%eCUnI@W7i%L+5W^*T*>CUi&0-Ih_j9?iOG zs<N*NZJ#Xcu(iUHoF!EQWYM?0BqExULxlZ46Nsk}fi#S4lf|-&x}RJvM5j>ee1n~y zHlHhj6{<5))2MCL!YtccU+8XhHYgN(I~-ep%`%u2qQKb~$ASDVP;Ux5<@ouHeV}?F z`)@m1A<{tc5iGu=*m=EdR`v)nx<WFs>g{rmM_SgM(H@7YSXWqt;sK@#ijWQ6CmVgE zS#ivj5J6wxR<Gl*HKx`T)v{_vNpCO)LwVa(>RKx{{c=)X%H(YaMldvQ-ButwB96Ix zrM(w3P`D<XpT!;a+pZX`C#*l&pFSxRy?Rt=33&JC<>OPeP2ZSX7vofq+32k{nW<}P zjRsB(HteH*YV#Yo)e7qO0@jn0j>p{j`8-fRoE_CSaV4qPl2OB_>#5Gf0g_W)g=z*m zuzXr^bIqP$CHbKLg3Lxh<XSK<>CVcy?^X!Ao9JmtNT={Z4IXdbiW{L=dilDhDj43I zJ$20cd(CmIey)9_8{Cd?T({1t7sw0V#P!O1H$ltV!(h_)O*l1q-TbUwVQ`OKb(Ry} zsz$8Z|L4nb_Qb$kOVOI!wz9_T(t*#oO|<R?MPbrBVe>KzvBsLcX!|~XA#8f^%Xb|i zhbZCN3T;Q&+8G?<_A;k1YtAtLD2cW7p%fAqa-(JMrCE%As?P9Lr}aQDC!T1sfL8>D z`(a^MdDzW-0Y7Xrw(&?*wLF7VctrQ%ys_^pz7+l7Pk631z0H^0haO$yLa}(=ZRElH z61<zTb*~alVjo~o^e6GqT`XO3&tab9Gb4@0No`E0+Hr8q{7lldTkB`1+Hy(_{$Gpy zT4z)+wOuZjMqxE+`IFRn%3!@Jdp*%y#Zu#qvUb{XAztxP@RG1NYftRQKnVuuK#>gh zj${5NGaJek38U_L`EpG+zHg(=Pi-md{Zw7M?y)f|yi{P|*Zl4UxuNcukyvFqUhf+I zuY!!oFlYT#zIuNsF2u7I7n;xeM?37X@qEq0@dF*CKpf03GXNy^Pb`eYb@aErSfLhI zo@0neit=Q_nYY%b#oMUDhppQo{k1=?<a4NYCcjIah^WfM%8AY5pWa_tP<JONe?cct z!DZ5NzVJ<Q?pt|z)*AQW9$&WP7lRXypj+!Qr||Rhxn!Ye?k#a%O-qRyo&}FBq02pr zYZWBQ*eT1wW|iKil718I$D_nM&!b*zZ4#N9FnH_xC4D6J_*Pm_XCvKsw21x%s$r71 zDIl0H{Z?w1P=$|2B%_6ou<rKd@Lxt+@<;|+@?J?YW)DEW5QW@73vZ@CU1)Kb_HVxT zCnmCJs`hWTgRg`;&jDIGv`uY*7^4weT>>Mf#EXxc1&D`Xk*i6b)dqSA7cC5KCDeW< zfNZ6Wxz*xL-$#+6pA|v5agK^ZYcb(`#716>B{q*e3rg1fau#=2Uk4hc;=?SgKC9}@ zv%VoLCClZW=@*R90Q$%(Wqj?lqHBnk`39cqA!hdAlCyN0CVRiaCmgm}W<z)vQYr9= z0H(sR%Hwx_)SAHgY>l5)*ac64!^7CQSylpNPaRQv>Hdea2DcMWmL%X2H1+Zp9F#Yr zUqJ5je5OwkN+P?14O9hS9c-E9VdKwnz26?))+_8R_Hp)$D;jj_UH&zhxVSZPV~`}h zc{m2UAX%qybynF3Vlb_JB$p?(KduG>b<BurSC}f41OZao(WQCTr1h46!4~cJgTRv; z=1F=9cx<pOy6%b)(4QCa=rig4usUD$x07@7O#ho<#g_dp;AJ_Uzr8XD?&#=H8FfFs zu0@|w-d>50wunDgO_eTD1~+cx3Dd$6^ZU+*7N<Kr4th(1sc;0H%yL&ZLp*DLKfp^l zpzAM&BZsR5CH2~A#>`ahifjyuv{|PlLB9WJQzY(yy1f8aI+c@0?epATK@?Vdx4}~D zfO)^wTB7Ijgseu`7Gc!R_*KKqO1(Yve<XzJ$M>IgX_aGup`b(ENK_|YKv-q@@?AuK ztI?3;nsS+{uvY#<afk8fM}9#UHP?rwE*SR;x%d4X#S??j$VDbj7zZshfWVZ(a^!qf zN7dgpkmb_5dk19q*tBhq1L^Wb(TpiD(ub!k12%#r$f<)=Xn)1rAZ8oDciGY490xHT zW2<cD{T$Q<AF_)cKqq;HBHTY=7jR{rvhx7Pi&jH=c&+G&0xl&oxWSri&V`T_uC2jJ zKG*Fn;Y!dOs;PH%o032gf<nu~L{{F^i{poL65WkqF*Xc<eAs4F2JdoDB%gIq$nV+G zW{~eyi9$YSSEo=3SYUQdVpis;{wlA-@W_@NVP)JEl~=E9w)XaXVBYa-i~YB`Rusq% zde|yV8(x1ytE&n>w=!i3t0b#*4>kMD{FLMhOk=txCW`&R>SOsG-CX*l#5CRKV0{EG zby}L+SJ+oNSo^B$@BzAbo;d6`ICI1HP35QMpWywRo3^=LO#5Dgp{*6}aE!#Rd`!*p zI2llsG&E1lrM2aJ2kP<+VU`F{IJH>1-j)L_rm<MGiLJ<R{t5`lMSJ|YKvems_c<vB zUFoB}wXU#A$^l}h;4Hz7bc`(G1aoP5^$ZywigDxsF;+fT$4rPW-zttWM*9IX@@qG! zR#J*=+jOK~7$E|m?sp^q=ySzSS9<Rxe?O<_1KF`gud<g_lbB|_C-3*H*6@h<UPsbB zeg2$AIqAj04`)q9Gd0(t#i*WGxO66!_?K3dTfg|vU21cN9rLa(EGN>&JbQUZMm0@b zxy>CEgK`n&{@OQk6-bX}5~pQxme#v1u1+U06A+)0*|So3EqKgE)jnAMCfy;jvig&> z+tI?38X;oF!is3gL$4MpK$p3xUvKfqaBsd8vomBgoDZ;A{30-`W`1^X=K&z8-bT>j zW1{TD=Jq3c&6|LDF<PyhfaQL0zVkTj*z22fvgtf)zgy4`nEUn@M6kZR7YJzl_G))3 zLc4DIs+!x`Xp}>^=NIu+E~zrF!+49_>CyMRP1`}AU9n?(IC=tYU|7SX<LO(zje_KG z0Em{Rf_Om+hNHB6&(UT?1d2yi?0`q`Q=jOInktF~+AavfA!aEN`XWs$S6&B<hTNtI z0{?1Qbk2db(gRm0_WY(_qekP`Ccg$MkGwpRoc;T=ZC=*mPnm!K6Tvk-t*0t!(UY9L z3|~OTVu9I25NE8U?)%`86-ONo(uPm;$%c<34W|TRH$4=1300`K^scdXVTC!{Pzqrx z<gN3HRF~Z20E2<^_`?MK70)-c%sR_BzX`+T%FZ(26Xbs!EsYF;Gqq^gJ;<knOUXR$ zgG#ycC7Z=5C2wAZKH!K)&zko#7M%25N(bWOs9Cvp_LL(If-`;%mDN(uX9i7>refr! zR*|6A!*R+Ad%NC(&g{>#ld}bWtAi?-u6}5|mBu%BKPo*hNf+s8>W#lI`Ew|V>$h1U z%Y7_q^JaphHmR=)ZOuD(#RbIuENxrk_heb7SLeYgsT+KR_K}8k^Zro3JW+_vVmQNW zyKmwbg#P;#`&h-g5_ugLs&h&b#FIjd#bBw1qFI<(i&`5VltvEqLXq(B`*J)vP+~t; zsG`1oM7r!xS!F}JmdRj}mv)OwdBsSfKN%CdlL$_`R^rBK4cBadjE;If4C;n?S{Sf% zfJY3(^GR-*I)d+`JL~PCI(YY_Yf1$7MFNvH##q|4;a)r9quWY7j7IX?GRXBE5_lJw z1*n*kw5OA0w{Cp+HXRpv`Q;h}Sety*l0&EhD)UMAT4}9Ptc$Txy&*?DK+9}?pJ^5@ z*>y$(06EV_{<S}V5EsozTl)Z=0#5MfRV)0TbfQplt{}r^M*PFauuZDXTyYf~ZD4S; z+C4Y^2XEL@qt;*^>8j2249*p+&+K-dK$7(0zN}nyZ660}GRzo8Q~-N+>*dQ%@tumg z`}Jr?{tTfs<mGE2a<5G4)_O~QM?{?*F6-KNi^<Ate`mx4(^b)c^=WwKG`!{g%Z!R+ zBbL2neT3(25M8>x-?Mp6d^?HqfC<$`?+U$QBB;l(wJopuJoarkML{R#(HK2s_z(Bp z+}A-PwX&0i7@v3L4gwiV<N~h^4R6ONzkO8<ko5Ew8TgWnxALJwBax2}&#B@_PBBpt zl!Y>RfV^(%#4B_!lmj(#zyTJ%bF#X-9u&_^Pg>dunT@(!>J>pFPzo{LG2@%Y!d<sA zpY0h>t*_JP__Jtsq|~gSMx^BqZaBrdorPbC^qY!Pfy4fZkYUN#mT%3GHv0>o-nHW& zmR^NW?mr7<ep+<hWU&82mtybFOYqW+B&9;%w)aR(;DDPSyxGz{b^=8&^KO>bijOJX z{Ne+eDqXdl#O?wRfg(4wo-Z{~<b~B<t*PWArstxai-~?fk}odeVDsLOj6Qt>OQUb` z1@-!Q3lRXZx<F4B)90V%3Hw`y=0EJp58YKz42p!0SXMdR6i2%mZs9%^tHt}@1Y>}p zq;sFViCTx0L7DLSD)K{n>2RK$6Kkhd0ra+VI9h*xOoL$}tPi|hJQgWYyw;fVX7V^5 zSgC5BqyiWTDSI;11SPZ5VSXIcoYrvwLTa}<<E=j>kDhXkMh)nP6%k+ezSCdkHfAO+ z)|4t|DbFx4p(<7Ut-{bDqmpyfda4)+jtQKma26hOcx-o3)b=RIbm>K9>ZveSTOr#b z$;21-xwt5HQr&|?4!giu0|~C@B^(a^h_pViO)70}nW-zX=7~0nir@;@q+gxviH+R) zX5)lgSq()=to9Txqjabst#O>6A;qhcrzF!UjfGb`<cHm^Hnln2cBN0Y#yu-l`z?UU z;;|a`9<?0uZPgA5Yn><R+gM-Z^>oyl&7Vfyl7se$x15@^O+|kLho9G&v2s2O`XC20 ztk2;d=UL5`wk(cryjI?>)h5a|5Gx{mOf(vT7}t1faaWGb7_pWH#LeD+|33F!wFO@V z#Y+c0F0+f*5Ac))Vw#p~t9YiaCL^vEg6Er7bP7i!!wc6G8sj|=&008e4IP=z{r4Bk z8Ah+BW^H)N*tc4CpS|g1;W&%~XFG>|P+t0KEDOVJmu9IgfbV&}0jL2GF?sN+Go1-l z#;B@Psl%0}rj_Y><;AJyo7@Wff#w~TiZwVKG117Zr8sf;q^9X;@(G@i2#0qz2WYCk z3=vBk71_w7yhH~4^`MO+;$gU(Kz*6hwN<4MI>4KBa!rB#*XiV;evbHwA)XC0eKU!t zP3(r$*L*PF>=`hOzztzy$3LyQaKC$zJh<uw@7z-t7V_x2I)o5Ct-bNXP>Z-$Rn@xp z{7_y%QNVH!gNz%!NYkd_+%iqMKO}&cBs#3!NY&Qp9y|l9!^8;RTvq**5v?ZKl=N!( zX8TKdZ*|W%vj^cA)~m9n5pVf-zE7AfvaCuf8&^2xSlalfh@E~u%S|X#HDg+0eLX+O z%V#*4)syyODi@a_j&T!QrZKF$*R2kdEY6zaAz5Sg7WCvPWu`Cp8Ofoa5|oe?H3G51 zS<2T=7!`+|E3FpqtMKnhEtUX74F#q_OQ{lk{D$cfj0I!sn}NyaZT)`uE!xZ~<Hv3y z#fu!;v#1Q8Zr!dOky)30es9ewPm9q8s9df=u3>qSh{1WRns#L@#Awh_X|q!1>;4Pg zfd=uCfNj?0xHHajNcI#6`BG8#Ohu0=Ud|()dMofL%Lf5(MvgVq&^1i_@kN2T2@5~* z9`C9NARU$%FiCiSQfeu$hLdZpKzeCIWOU6x8LcRKI3tt_twEr3MW?of(r=>e!xWqH z^}RjBcs1qP)VsKTJjv-qsw|!XzK&kRddQg8=Vj_=C2xDAHD))-E^SHb$A6iQwF9f4 zp9uQBmUUR0UwWZB5`L}$hx^5rz^dR`L!-@-Q4LyxfLFG8tjih<drh6WRoJTiBKEzB ze*Mb0Hf1{xjmxt74S67rT<s@2tuWoY@-9oUPKwN|w!TJ9B_iIeS=gpEWM*2a@u5Yy zhScMB!;Y#7j`(RgQ+f4EQ;^agXjy&QF6dBJ*Gx9Y$Lp6dt=Xf##e#2fpOVMwy>eY& z^%pw!$<Qs1zB?EK$BO5b#YQs%4;bMUX5VjE7O7s_Lp9@0d!b^q+iyRRqjpta>D>+) zP#V@7>7@amntJAHImTv_1?xB<L~6b@rGb1QRfe^b#d&^cwRD$>h^`*1(Mj&8Dej07 z!EFIMS*9NYJOb%WIRiP%>T+pbRZf<DxkC)Fk-ED~P_W5V9nh(sd6O7`N1x?WMqF(= z=vZVcMLut*ugyR+=odXty`!cJkeC%t*EL81ac&n*+r891)$)F4uWdTW-e_m{+udlk z4%!eHezbZf`gK}ku~>K@5-PCA=hhIh<G~|82OjXr7{L1gkVA%>S<-Dy>n+6|{xJ6R zc64upvq~R<$)X?B3L}Fa-tJh?3hX$}w`ER!c58Cs1GiV@iJhV1SbXT-gUhun`gZBZ z1K=Xr%8{9)6b9dA?<=B)KVY(E9!d@TGNvgZpBPO*3RCT4_9qyMOa0WQ&lC`0Ph~P2 zJ5c(*&CYlQ47Az3!AQQP$Mm&EETG?Veor34Dy8qR3)>JUGvxV?!n8L`6(bSXn;zq7 zl#Ba?j^`)JU)8=_FQ1RiNO&;d#+8$4$ZJ=SsY}N(gg7coU?hmMfy^4q{L_U$czZp+ zD3z0E<d=QyTjA2CoVGLZFZu~Rg(|mPYAIL3vWr>!>W!G1f4qpT;Nu&lhb)W}*HfV5 zXrq6z8nTrZe)SVH8nI`|&o9zR7U9`v@f=2kZa0qC{V`&`;AWzYWb}r~{%SJv&h$y( z4FN{b@}>Lzu7a>KDsMIkvXsXqZ$lxy1sNjTV<O>JYB_9Do+~py+P1K<+x6LRNS~Cw zGZ)t}AM7KZpWD!xtrJ|EekB_R8TWo9P(IxoTbq4y1}<})BmWrBmv9nn&eqGQ%~NZH zi14zx7F-#P8H<sRn7JP=_B^sapDbF)0>zsN0jJbg#$f;-5?^}0wv4ZrcKV`aWWLgi zERHuiv~PM=PU~+LKgn+dn##-f%lyJH>m^|d{a)>)-174QFoVS?Qd22wjsv_!8KTx6 zr%g#}vUwM7-yLz<5euOkbiOSF;RXE0-V&^T`1@TmXinw_nEVnK;ud9n@}t`YHwcdH z(hjP+(O5UYqOQ9G)Wbzj#MUJOWIG9D?{JHDoB+y8yY&R~ywekfU^duPMFPll3LfZj zn|+4>1nc3x#oUB;VeUe|itmRx&KvnpH25f*ZkBb!ze1Yp)!1u3i#PJ0ubYGV?hsvB zU#3godKCt1y6a-0urqGOwY8TJjKyz{<j-EiSv|4mtMU%Us&?|_O6+~jLtLKih<tuK zXb{x7pCF!hwqppmj#5z24AQ+iYq>Q~U7eSal`&>@hK($Nm0A;BcktGvzTQg@^maXM z*8R{YaARJ6tA@E5)&?zkY%S64$G*C6n6NbBS-HA)vZH4gmoyn6fMgdrmDe?eHbRK) z%8qwrbR?+ZCWVlwfR7(VA7NG!>a)10OUBw4+^j0&hrP*8#Q*$EOUe#!)+dXJp%{Pe zYPWCj5Thp9fgiy%QF@r@jY(GUcHBWc7`YOKxA`E+K+aUTdW(L-#($6I$rLx)*P7y{ zgAjPnXJy?fd~9Bttr1`-F3Ijr5sEtlWh42^(+R_Ewv=t7#Robz$AMu_2T4RO($H^Z zL`^}|ugc^yp;o9p`2?qFOwuvSDNuCkv^EygH6vE^ET^}0lm?&Zb9zWu|FBZ->$Sp8 zRtm*V^HK51-?|0~TSy+)`ofx;3Y+--eeC<+2m)&yM7F=bKXwcIi0F%pu=d3P(?59Q zedx$}3qEX8RC{`|<CRd^@X5WxWNdI{%jSFt0+w2CKK^~IvMcg+k41aJ_1yR-<AE0R zTrN^{S^h8LihR9x)}0L&`*uRW<NYg*sE6eZ@PPP&0KpsV;{(A5v@<QY{;YOcNL|78 zQ`9vE>rRfM0Apps2ae?hJM?hpgROcQ0{XvyyAoX=zg+{XMXa*Z$6)EKZQ*L&LAZf5 z_Cj4{dA<>LVR0o_*K)mx(F}^Q)L$g08)j!UxjrNLrJ(96em={-S=e(FS;P5`6FzLI zEza=7JBS<IMQI}qj?9#|t9=e26O#Uv>;0I2?Wfs8dsmj&;%=)ery_o4+SeRsTPw<h z*=WO8)^kafHh_E}sVUQk{>wEaxNbS}U5)^~Dm)jQNO4O8&uUBuBa=hn!I^=GfS1c| zoNnf^cg5ivZP9bh%xmRPgOi8r<&w1({Nb4*1Ao7F@5LlMKzAxUk>s3VcvzaiV}~^? zgATonqu<`aSa2UHXn5*tqs`yj-f$FJ<)bO~_F4Opg>7W&9x5KF>2NOI!26eYN^Iv~ z^!_FA4uyj~U6u$ABItb85iso)D>0P)C~MSb#m2=2F^<#R+-%7ysU$ald=T<3jj%uL zV|&g9=~>rid(pc^>JxW-n=Iy?U@H!vq1#}1Dv^N*ntn!8sr;MHH!tKbh8`)4b_K15 z2ktZyPkB{UfD7mlg@nUuHclU$xwv+Vp15BDp_S}RGH!rDiozQ(YdVpXnxY`AY=syF z+6$PDJd?@^QD=GtTOl03+Q}>GGQ74!9(Da>u(YkjLMRc?AS|B+nhs;WC!j4>*%{`v z{v4)S)9>S2a}kBS0|8+=5}pO;J1An7hlj#{26_hVCPkMAZ>}Qc^0OaArKDD&h*u|2 z-vqS^6a3*A8mOB<@l5uI*t}?H!`y5EV~ZG8&TmyR$AX*8FEDN5Z~pf23}3NK-2rRw z^KV^rn0CSOt<()qUL%UR1EQ@TL4)~0_&4@B8(TpS$X@ADe;8Tj{FL*)nr-j;;^bp? zMb~q?*qHNC%^(c1=|FtFg;mp8zgBp&&fpcYucK$U58RqT!z_0$V)L8^O=t9Ls%^h_ zcFaJ5Lz1kNtV#xo8ytkhe&)?B#KB=U`iBd!<JC+(w%&O=2n`{+GgBU6AZ2;gUvY@@ z6L4$*h^XK>5vVUPlKs2<#`u1Yr8~vW>-#1goT1eT!ir42kBq&A;wdwaYRLKCzfAEL z6b%3*K?v)Agd5--mP&bqi<j-wYEfe<3^tdI7`YDZ@UOT|<GNGvZA!Ox+y(eE+(WGm z%9yZX*5yM9^pM?EBtm|FtwT8j{(SFRE+`>2Wg$j6R?Nn3TpV&^Ilvb$;p%(KRmn=w z%5=;ua3f`^wgb~f>}h`TS$ri=7)WPo8gB^rs>Jp__+i4S3svkzWa%0A8lTo<^(6zt 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/fonts/perpetua_bold.png b/AvocadoEdition/plugin/kcaptcha/fonts/perpetua_bold.png new file mode 100644 index 0000000000000000000000000000000000000000..861ea50ec92712f3168b5e1dfee67d932021e25d GIT binary patch literal 12899 zcmb`uXIK+K+xQF8dsC1us1)g-^deoQiAa+gsz?nTDWUfwO0R+_2uKTr(2*7;bdU~# zAiV?#5Fn8J@p;~J&U-$e^JT7?y>@1I=Po<<J-<nKsjp2#$wo;)KtS{SnZ_#u0+QP| zbuDtzo3bP4E|`Ge9>H@B)z^Uq`-KL{oUqVMmHX!ocNd)<4I;W56O>p}1ImcWKNwdq z`;dP)oxi_fdvEudh*mhDJ4;}r&a7Kn;#Ezmu4_aL9VFJ|wrxOtmR9mvL;Mr<=cKpX zbZKQy1V1>F3pLMj^c=gaHpf*KS6Lf$g<Y3lp60J&h;F~PHV82FyS^~~(~NsOxt-Av zypiktt@~chU{}yVu5(c?gd)ibKO{BUc<lTO!_|wDK+H@4=5Wo=(e=wg73bFL?Mi)E z>7(GG_N8eL8dkjhx1S%vvM0+@mbisPUu`DToG#98KgsII%l3Q)(<zpIW--%0U2RwN zmd)86;a9OK3jguyd|_kPG1~b~4?~-ALcRogL~^<7ySt?p?!~&vS8CY)_fKrGJiQ%5 zhsiF^dGpyNS2j*_8Lk`CA(2!((e!HM|1J8|xb7+t{9mn`>+x$*#G3!>1`YcM0+j!& z&30ea@PGRL8)f`1MdJVNJ@D-1?f=z&tQA@Me?KdlzEpzocFg~3r=))t_<!Cd`fc+6 zr$>jBp@^oZr(Z>@lk@0P${otq(du5cP#kV=<-sBfzsBwaejqf!cA+Qm(-B7FD3)+| zFPV#r12kY%?y`m;z$<9O-PSeeCtFNGzvJ7XlTo0{=>sp$z?eTTK2g*WDyG3rJqg4J zWfT-$CsjO^<V{D4;qS;dIEGp5W3~THiAb(~xjmWcgR)Pbp%4g!P;tmD4#nq1G~?B= zpx`iU4to+PHu<A|F_uQnetMRt9YgQ1jEK8NtROM&s7>5coG3C;MOo$}-u}bt1P*`? z<~+BAIqR8o8VYW{<=+>rQS2D;T7SnG$a@)#z+#y!+xO`HqQ)G$HB%|oN?BV}ia4d{ zbsQqW<px@t2P=EQAqS24>jyO>!Kte|h4sJ9mLxM)cWl<G0|LwoPXf8l-=AQgTPh%% z-y)P3Y)yV~exi2fK44k6_fI7C^Sb4e1GF=Biroo3eg~A`FEDjOg1F_;kf)%$c1#JK z!6UxzKO|wIQZ@F{?TEI7;<hcT&6eT5)%e^Mc}Q?Nhz!~&D6cG4j%_npZ>xDMGTJtj zxD`6*w(40lhH$iB$8f4$?Mt?I$P4C-Ns}z!pKZ~L6~n;$j{D-GLp)J=gbTPU_mx|s zDtbWa?K1mqP|C~L0eukFWK}oo3S;k7T&OtqJt510D=uLCD9HR|2pxUp0(n2DOYV34 z^$vO3KRsic&;ot52%XW=6;86?`#kq5r(*(-A(z^DCB@_0Ftko|VVrT5i*$O>NnOzE z_ii}>7w{yac$c`OanECo?W9(ceFn~Whu?5kzv1)UBvzoJ=Yv3qU;J9g<R8CbPhgPp zy$nZ-N2bhjm%dslj}!p@4=}iSy#3Fk!EtR)_B|y@yhWs4u&_Y^x(mjf@yZV6&2Cz& z`<)pjf@psxAS0-WGj>!9v{^t0?VU6?%A!EUfTrkbKQ)DZ@o}Fvn2#7^^lSSe3?yPW zpwy=-gZ7_kRoJ=_>Ut2Xrr)a$iQhffjabBw=FrQJq8KzHrqpIgRmU#F0Sa5wwuPG> zM8(H5*7xGYLWw_6W5VifT>%N2MFxav^vG5N?Gl>$4+<HdXERFVvw&Pu0TQcd5zbMO z);dzA`)%X}^*LtzS_^*M8Z(=mS5fBai^qG4hJ8qw)1NZN9a#7By4!YuvPpO<&$_oV z<Z}ikQ`iu*S)sXRi|AlBeW!7W<v(dLP1i^$K$~Ak4{Dre=NA5%cYZ3o_Lhs&qFV^7 z;ve`QO$)Cl5pQ`&l{n<@AbP&$ae~hY>^m1}lQvw2Q*ctb4yp8cah@FOwnKS3M+|{< z1>G~vz0JdWADbnQBwu&|Z6im=q)aHCNWPU2Yvy0f^?f}sGa2sF<E%Z~qX6K4d=tGt z6u;fDDCg|Iv054+MK~uvj3!Q#NB)eRAun7g-FPn)oTdR#O1<@wxF1*WT6NrQ7!JKM zbT*QTWnGk|t<L-W7R(11<rY*lzRf{n!?IxI^oO|JnCfO01HEF_IxaQi?T2S?<t!eP zXfoXrW!UeP(ta6zk62M7XV~oIm(S5qd!W;25fEEtln0o8$B8qeUx{32qBYUoJjxZ> zk=*U~3_Fr+siF03!G;Q+a9y!e_5>&>pLJBE%V$f&!#4mQZ|$s2IJI)>>vR16oJ=aI z=7+^c^Ee6uPX-N)X4pdY+l4pXJq1lC!EO%(&Nj;^6P-M#&4mTjFp{7}^CzkdJ<F|a zvKE;sce8@3*N)+$;403`x_7shD`T|D>o0FpPsTB*J$ATJE72cS*MsQ!`8N^RhQDpy zHmjXw)TcI*i-gKlSE7eBD+<t9yh+>@Bo+H+)oO*L;Pa7UjeR<i%GTk~H$|Fu3Pod| zVIyUZG^7Rug+y+da}QALcU3?UD|y-N!PMu<hbrM>QhU_>RZuYx9L=Et(IwFVRk?*o z4M-uPxD6_1j-#KEyAn7Ms{G#NRe)WS_p0qhORc0`BWeSn7-7*cgGph}1EOXxAev8f zQEtD-U8=G(LP)6Y+_j>1WpMmUw`q76X=gb2p`YWc__fGTISk)$=NqhSZz#~JaZU74 z4`q^>|I37uM`MVzCR8w*o|mC1l2^Z-$T>u+;Ipr@eBm?&gA6bdi6XG+rSQ4=kodx^ z)wTqtVLPq?zfLZDSyhQ%zcb~Tm3cVyJcxr|0GBwXYFU1*AoEi`6F#4T=RF7wqYhz^ zfxA6Bqd=ZYLSN7`A;`kG`HS3XR%X^@d5#2`linHcA^W<6IS)p!fCz4t{n35y4qs9s zlnNS_)_f=hn@b4*uKyWC^GZmKtkJC;_Xe#zFBn@esbE1u!BYMNH+B<mpEx|vtVW*x zfo$X2-rZfKmx4CHOKpx7Uwch5+Bjz?y=DjFF5aT=tp63h`#4_&x|XKrltbO$bp+$l z$V#qj+;i;~BR#a&r7U=Ms#9S04*si{{Z|)<Ox4$<oE)ZO^K7hr4c0z?;7=6p9L<bz zz@3LB1yfV4eZhsXKYe!e)tzUck2LD>+RGcKbeDMnyKM4?f+zY}pQUR0m`k&M$FT6c z%Y~aoR?wnG_&2G)XV*t3Pgg5?&eS9c$NT0XI=1<BDOKTwxRCJ8wBONnsK2J+_-Kor zE2X@I-|i9&t6x(wu;AEJy<M?Yr-CBK`ii#~!&yS8#=}h}929{p3cB(Hg~<K{N8kN4 z#EnX3{r3+>MjJ6Rbt!px-BcY6`32sTU!&eA`@p#MLe3dHf;L<x+$cM#{kNLihlrsi zS&n((&?Kzci1QYN*q<REYF>%);zX!8J&`F!4c@VQb1mY*Tr-Sgf7f!Vte=DWDCVtp ze);W`2%7t?7&bf<!pQ%~By%)b+$e~%x!5k>+*mq)yy#l&E5hCE>=lS776}AReLKAI z+I`};hY}O;z^SpDIz^cWUH|dNYWX7|gE~qO`l6r&OD2=|fx#&_jN`l#j}@Gt%-QXp zxkh9Ic{g0L6qtOTN%p+j-1Ne#6%9~0VTmq+vJZlIiwb9rbr*lG!?l4n`Z&VF;BLek z(vCAb4JkfPt-sJ*zt4w16J7{FTY(mBp^oc*x1pg{RS*GaOwxksT~WH%>1#cWs&|tK zSP%+O)*lK)7gj5S{?^9}(5R%O{PENB@FuP>eJ_-}80SGC-r6}QRCm)*Tt)PNexkJ2 z3eg?vMXuJmjD}HYcM){<o;yI5GJSer4y}i`dZ}j}WZ842EVSoV;EtD>+mYf6@)#He z7$`B-_5@HUK9<8kikr?IhNpqsuNw8y5nl=kd&i??aY!%N*|t33>j<$a7v=nVa}UB) zRNeD3xOF}&Xxj!-Tfa0CYNl+_y1_g$;_gQc=anp=35oo2Aw?VYhcJ|EP==i8L0*~2 zkSBjx1HYdGR9q#M3RNoI{DXG^bKp0>ejg4$Yd*c+anp_kHydc-K}<8>7CcvFhCK1% zaI%1Fsp7wH<^M<=0UBGSnVEKXEY|qoOI29j8Uxd8Qse!aO01+4S}*_X%~ip-y^JvD zDFfxXa^+&-)-Fn&TIo~$5E~{C#=M{l%^b$AAW}TuC^jc8yzV8O2oKH6#0+j$|M1(@ zx>;Hk>dPboaxoXqwl_<&UC`#&-ACLOtpN*o{rbJ2NfkJ8mQ9?{PjFk^!FAUvsA~sA zSAT>eo<)y>;^;^F3Bqz!q@xCq7u5kr_*VcFIN4kwE6w_}OY8z+y0I+5B`50Eyls=Z z*MT77I^G;PM=;|}Afj5EwA)3awAWH27l^C?7A3I}pD{7S4<fQ?%y*x-XfY$q*DKok zj=YsUjZfnHAN^x7q}pq1^x1fskaJP3RgpGj+?%lYr3g$g6AORbco0?8da*a>Sau~8 zx>Ia(id*p2Nh+{4{h<gW@&mH!GRz3px${&`>{jA!CcXbW86I@3D8QkQU(0#2a9&C0 zwcA%-&Boa2=M0LXwhiPArq{>a^J2DbpRazuU$eX8CJt?N@ch{nH{?IaKh*rSUPwNg zGq1dByli><-R4I6@R1DU+Bj$<Jj}g_5B1I^e{!+ttA|jHRM*fR5((RZwO-9k(>`%$ zUmrh3@9hJ0y5Q@gHKvuz^?D1n9NFBAog@V4-G$eX1`)l9d+VX-x05E2$3jLgZTQ9B z*|2c-*q%XL^5-qx%9BWDq_<gwE7|kPMoV||cc?-qfrgyckEvm$XXZjO2F)MYXGC;f z>dp~bK2aTi)Rzqe*X=EV`*43bp3ss}qnDXsanTrAm&nrouL-vWHBnQ2oaqo6h-AG0 zXHw$Iu~$K}oeEZ13UYOlg%2(H>0_UMugGxhA!zDJxCobZ-+IhUDOymT+EJpfFE?pO zTJcQwk#y)_96b6j(Zp;f^rvIWj?zW|*IJ`M`EzzVzz*9XA(~y=kw=Ib@oJjivA+6| z0W%K7tpQN3fO;^<l^B^ZKL>BM<Uf>QuK$sPly^Y0{mCj9E=0D9`+q0tPm#mv0=Z}9 z)deO)_sz6^i8X(5{>lu+)~P-NQ$>5{RTjSXSjYrrCy-gLy?0|Vt+}K$aql&PMVm*g zafph+PDi45^yd|1gRMq9b3y)@Ip?%B1&Y7imRvEuCHH2xsEG4fVeocZj0N<pn<TPu z;ea742TCiUAUT@l@S3gw!&){<zJ8)^nU^&QiNBghZ`xroT%w^i5A|~FgxyR=``kYS zIX-|WIB$E#d8@H?JZsvIN8??IBMwyOn+>R(&^E>kZHi`7-}X(#g?i?LRYOBvMO{}- zA9?p+t$E9S^0s9$9q+)S>oE0kM^XVomY>?4jyxR0vi<#D7T_H5!_vYHJg8v`EY}|w zj?E+4MdO)~`}QWuRf%1#33p8BI@I6dxsk{=_rhGTtmw{!#Ad}(4Oqvx??_za8scxM zpY!YG9cL#Nu~d<Q-%a$l<>Yr$1@1q4S<p|p6J!}RL}~FzTJ{ZjGpmycFY%h8eyt;A zqA_xmXSD<CuU2`Cp#gbx_*$vHwY4m>iEE^iD<R6SBxI)|;j?7j%yI9->__K=OjK=p z{oWw;v-@}Dwb5ADuXRns0ZdNlNojD(0JPUOWf(o)(jH@DoYDW`e9l;k2fS58=LI~a z{|T9*0J-;|c@9GJmBGS;8zR>!3Om{4g$<gV)4Y_me%7!4@ZYTdXJli>WJ5APFq8Qj zBpoYII~ujU;tG5#iC#XQez+(pRYmoq+V4m6jZw$<Fa}7AB99#lYBsNxYSTr-L=@GB zbM|#qe@zaUMe+_&dXbfJHtsSOX_~!%6H1>wyuXF&v2jJQ(7iVcYhzQY-6;|TD13Nb zWs#V;nG*_b004gH7ScFGh0!s{dj*Xi_LbsYg&|Gi7M?b|zE0SI6bcR&UJz1xQ(8MF zD%sqETy$7iH*^8Z{7q1wx?z)<>Og3r@V37|`Le$m4n&phY~A1g^()Ybuys*Xp`u0F zBiOeI5wwjnuJW`O7OmCX%$seh4AZj-HWQ80G6sDY)eRl2>DLa@)czCz_GXU*|NhG$ zq!a3{&!Ds!;;U>A>`dE@x4LY?uAMDbjbD6Ya<OCo)8DD9<H7XnQDeDm!R8mV^bsJ~ zZCtme<8zMB)a;9wiZArvI?R&$6ze<bnrk#t@)hy;WHzEWsZ@e}dcf4G!1Ud=5RoF| zceBCH!qx);W0QDkvv!O7ipDq1NMmctTcTXmMvdAaLkW-D%LDzPitJuR!4KYRu_)Nx z0W2N=P&^*hxW%+^IWi`Y#8V${%2IAJZt>;VKKeyd6=#aGY3QT(*2{;u0(t{IRK!?d zgVvuYVuh?HP{c&tVVBVqKahXMY4Xo-&95AHg1m~^ruvqh$kLcmCkfaYkc+uo8a;R% zgt)A;j2)quUqX{AA{oNGIMex1W6?bF$KM4<A8_fsOzvNr(s|n!T}~kfcB~hcH>LnE zck#V06kIZL<QMi>{to4LJO}s>cp0CsL5e%n6XnJ2O+M5SHnpZU8qy;-jiMzH<ppz6 zB1&BMsHd5qVEQ?&nDW+ShZSOBZm>8gM4R0(NI<~><$z3Ck1}%*Y-@hI86ceZgrR)z z607<$c|T=*s)hzYS4FI}ixPcvtAJ@RI5FZdC=?Quv5-1eT`>DZa9(Vh`QpReZ+1Va z+dgXZr<@uR4FVj~2=I?i<_o~lc%Mghg64W|m_f{$!}h7QujoOX{s8mv-v<J;F&FN4 z4oY9t)8t2w?^O+@ZgkwaE^H{_lEJ}I^=_(1V=8#ff}>#inXwLLtI0oOCdM~WYStrX z-dUPUEFwekSV2?!3uRK0y5(Y#&^5ke3m;_AWyb&>*=IbqQ+)K!<#ppB`h$Op4|~UM zLv(p!!`+D~>;C(_S$xv!=no!nF5xilgd$@uS+nT%?Dk$I=H}_|Zu5qmrE3l;<2sLv ztpJ>Z+BtWc8fbB~t)K61b|i14{DvN&gu>a^C2wa(wO&FNSKrFBb;YmU6Yy_RNP0UD zD5OVXKdeF+SxboueHw+|wAou*y*kIkq}r<Qzc%#{Zl5+pfxkwlPby#0FY`EZz76U& zVKd|Gd=@V*tjzTw16w1_a!H}%?<rh;!eAxUgDv=S{dD1_f5pi18?Hwocd4An5a`&j zK0pe;{cWlqKNa%Cv88`90zhi1hRH~U3zLd)`2u&cJ2bBenVi=A#iFk)S^U8kL22T! zt2YAo-K3s)?v@80^7?Uu7n#!*>izsuW6HNyob|U{ht3TrK2m~~;<{Nu9(<_-%tQag zq^bDM9%VtjWfNpjPbItNLGz*WzF^SFUZw9F$mhFlbh(_ltxvnw`PNC9hDNd!y8BgA zbtcV-+g=`no*C8)o0Xrq_FQ#jSoaRcOCh0xjOQKtv)Utzchv6RsnjguyZ_M<lqY>6 zl`1Xy>hZv(?;f0&KROjKF3B<dw1E_$xcixg&v!$l2Jd(OXR(yRbfZyj>)LDag$vJ1 zMJfy!deTVh&cfa}7-<)@{W`y{Kl0fk!@hb8^%K3?hVYz9PF__Y&NF9;%q<&$;bp%O zi&Q>hjaA*xy}ALRr>rckA-~QcQmYp|nB3_1SqVi{U`D#Xd+5!2&?c-{UR>v}Z4YPR zE^8yVJXmbDl5Q7Pm014vwF0W_p(EYj^KL&q@M9lgjr+^g(c}XrY46Lg*oN(QGqH7X zFGaq|)O(VhV7E+k&8HsMyI8Zm;Sw4pj=QYO?=UEo(alK8Zh%>+=-oBZjovX&oG#CC zmf0(+*@li3JX}amy*+BzzB1Ymo=B?imu$gB+N~?IaT52}6wW*{QGF?l!l%D@>!SA4 z?fyPb={1SGGT7rgxSm>7g1>C756_uojnbSsGxvDqF*Tr*vXQ_+0zTqmZ-d}uc=%th ze9u<c9NMs9`XciM-JDza<E^7?e^H{IK(>$T6r|8_CYFcIK2$!LRa?m0RijC87Z^7y z?;pCiAwR5OV2mYfI#uw4{g(d@X%yqCU;Y7fk{PVgDYA4_l_(G1tSUg{A2dyE<myd= zDrlRD`!Bj=zWBi7(|Fwc^_#B{4~5~3w_)@T28rzGd;_gp+)k~SizW@s8rGAJ?tS$8 zwE!8d{^7`pg<O|8QY7k;5hO8({pHxVx3=}idoUR{FppaOEhg?iFzc-I|J0<pNufvL zf*p_pUv~$#MYba^&4wBw7IJ&W+n$c?TikzH?UwE>voG(#xOx*4w1V#0j}P*Lh4lCd z9uK%atH&KSsIYh*`TDt)=+@*0+v@Y8&Q-YeGCZs8-Yblw2b|bt?_7tm&A$1Fu;|Y3 z_C!)%8bpi|;i*HiJUE-Hx?S)XqwA>ITuv0h!DUzREiO_I!Y%{xK9yUz3H-IM4rtE` zb3J~%$=)rqxd_&b#|U+++ybrRWi(*Fi!MSf<=QuUXR>dZ(u&}h3AuXvF^(&UTQd;` zw?NtzH`$k~l&)G7-(S67*W-^ubk<BskKxPPON2#;%uvhLV!qcW_`hlHPU?Sgft=^L z__m2NnZJCZU5{4*pesXPQ8etD3$Uerkme4bR2HR$*SJ_N(mCJ)Vce(-`<)JS-#gpw zf>n8Sn>1W=#Kd(NA4a<h{6huU(JvK-Ov_d2Oso20P`~(`ct8)7yfA0dtfcGXy{OQh z6wGh76!x)WcX+;P{xrhh3$kXYmXB-e<|Y8$x)M3mS$S^B1&wt3J!>Whft&{bFEEe) zAQ$*VQ<@nsy41JGtO>$mcDZwHBx2}hbZ{6)P-C4Zp~^sJOS>-$T}IOkWSN<1CA$(V z@jQLF64zbc(bivg?Uj^-hW<?EUKv~vTx`o0^a3oi2`GM3xe{9u!Ywufw?kaz3sb*8 zk7qvFeqB?l0=NA%_q73jn~6q>eEKO?@MoR!_^~;=EDxil`lu6WR-y3*CTIVFiB*0R zbuX_6lDeAJZh@-z5wueZqr94irK$-Y;TE|T!-^L^bhqcnj9y6``hY}Za&j1=!Jso( zdCnb;GhpU26%G?Xeg{#^@MyKfS?~=9YDH^IS-tgzNN)<neNAh9*$JxDd1;q&Zh*C4 zjPQJsS>X(^FE^^VG-N)>PD$A2t5M!av%sN54;}!{?s55sI|bDgK=c&8AOr1?V_YLz z*YxM=YGf|Ia+&R#>KpK1=Bsw*Ffd_xOcmGYu1@CX*_a`2L~YwvG+ORP3QB4UXlyr# zAdLOo6?9-e5yJ7(*E#9lEsHni+-~Wgvnhj%D5A2zGm{oOL%QlT$+1BjN$KoRFHZ?- z8H(#)sFlkG6%rihp$I4}{yCEbwi^?k#<;wMY-<1WG$JWY=C18Zh`akfuRiG9c_j(A z_^?0^8V6=T=Dg%TSvrP!$JwT<j$R$<`+5wGxW16i;f&x`*Cozo4)AhGzwoKW+AkyJ zAQ%ebFIQ(A&V@1g%jR(<JM$1J(tNK^^fP>Uov6{`QY-Z@1<m;lD3nr46?vFuE2)#N zqQdy{>8acdB=kUVQMVV-Hw<0O_1Sk+lMf@~-?^rg$s_3<p%n+BtWf1Cd7+;UGUtg+ z%@0<!+HHD_9b|yOD+^rfYj8tc&m(MSW-trj)gpJ_Dg0r<Qd<-_*nBv29n$l#pra+m z30U+RCsiZjHOQ@!R&^g~%*1#HW#IM{`5^Q9*jC3hkJhf(!2?OU<~BVS;H6U}whD0y z;+BcOR)Egwl&6cZ<{#^J1%YqN+yo>G%-~WdVd^(I-j;|);mAJ;>C^r}oxc0@ZVY|B z&@Mn#y|rE7>f*$aus&IyjLy;a#HrwKileJL1$FOf&tp|EQ@-*`+}$=3^nQ`0ew1$9 zPlR%~Z4QTqxNp3Q)2AhQ@AV_Q!k4*AL|o1s663QN?S&iX;ukn@N3D13lgO1YzC&2| zb&_+uzxk_~a>JXnr8<Ry9KatbRAzPHrdGI~smZ&}4ER=>P#|69n$EcuWo%cw#+EIu zP_OgQv-D#0`dWGtRfO4;nCRPYc=qS{0tQyS>C<WpA4D@;)gW!I40S4RNhjiH7Rl<} z_}(npra#d@^bg;vi(REpF|231GQFC30J`#oh8BV-uNVMxrP1M7I+`~Lnu~qzVDw{E zflJau5HPsC@aM4CH75Ewb^l$$J5Rypi6r{Ads2j-X<ZFw9g<ARPj$84#$_yUT0s5r z&a(2V$RJB@ys*dF@>tZpv!883(76`wUWzaH{$hlqSzAk*>tvx5PFV9sVV@%q#q?(p zc%8*I6^--r9jeLg6WLQZ@o8jf0!<p$K1l3SP=@oE8JR=5UbjiIpCzG+=B$s0^ALe1 z4rA^SkiDbyv$8-$FDKC1=wnsQHAPiQ!g|+kn$u!_GNpMZE~SizvJcFpN1zKZo4Ijy zeEVm0Z9{vnB1(Rf8?E3K4q0#^K`#E2&ikuuY+ZdR-4XESG>L=or$)#hqy)Go6-WY= zg)}#n6Bd`_M``R+?WV+72zInq$12e!>0qA@S5g#Ib+bpeV&TyzSouHx-cc_{xQKD( zDtM99Y+JE;KveLN?tP{^c!qPO2alF(_podC{a8dkzk^3hI4f`9?xLCsF6{IDJ&p5y zx=z}$2_lP+()r1QGeLy>!t<t~U2AFX&3>fM{Hh5E7`gtj0E{l?k9EeK_-UWOQ8Z35 zKQR>G+qK9`x*56ot`?oy`-mPKV@X)U{^wXO0ue9XEhV+W3wL~1E&W*~!f96ZAW*FT zShznD;OsgdAb?|TR#Ace{B3Y+rhM`{X-OK7UnG*YWUQzph=1&Cw}CW#_%GXgoA8qO z{yq!nc%$(w-6M>4KHqgZ?Py@?MsRe0aLb%<ZN5*<(hhwV-)j-fUW0bF`+Ij9rhLDd z{y^uO1orB(<Ug%;oDdBVr807_qg<DWMbQ0`FI4IF({*?8XEEem-orG1L66q6IYKFb z=20K`=iL@PFaw+lV0Lwxk$|fsVX#e3thiZ|oB!1~F_wE(18v{~^558~kEt5nzppny zW4WflA2RmKZAzOWN^g|ONj~w@bK!$$uWw5@F;%BZFdVq`H=*k?>8Cdo;#|>7fC70% zG%OI+>&>}D99&HH#RtEV=B|9;Z7E1Dm0`Esy`O(Z(WC5X)1Q!NrTmP40^EOPo@jd4 z-~T4YkK%hDnot+Qx{+kdtdG6-8w>4>Sh9Gi@vZD$d_tN;TUrIhrp<$)0nTHh9EE5| zp`Jtic@USW4TAUjuOODTKMlA|>fu!SL!)X*2I%hY?&I$M;~58EdUy-6+gH9rXREL4 z8G0a`LQ%#GerE=ldkpnmvA2^r3YL`s8lOe|z8Ytf<_GX?@m2%gMfS<{RF6w<ACrQ? z2lJ18*RDcoO@o$s^d8<G)gOA+witxqmYPqChG8`}a44Qm4Kw;jc~a3|eXTl=GcTN% ze(rCcDuZp%%CvuRZ!gf)fULLq0kc2Xzi3lfn6<0Ut_i!c*7)Ut=B`Bb=~KICJJ-_K zlPBfsQa##3X0lEo*LGMwuQ3IUsw5gVrI9_z!%@bwp-^dgP})n=FeaeN`0Ljk4WAyE zkX3!@e2P&j_W?CZ7gLa1DD_U?VJ8M3T7J&&Zc(rJ<i5aLwJB5SAqxn(HFGAgaRuU@ zIRKw`X3XMiuobnEN6TyKMo(_^e){JjQ@pOYVw{jl*S#U%w%)6=BV}!sXUEEbSHC|5 z^E2OUKgfgz>ORFjstLtYEiRXs*jRIj>t>}+i=8V2x?Vlw=4OvZy`1e#*aTMD5^$mC zjUKwXy0&!Tnb0*1YxQp->7o5+2EaSmHiDb$es`=7((q*G=q))|ikWUm5kO^aIg7(| z1<}u1X7*NAUrKc$o`O|7n*iftnOAZ}Ww}1lD3Og_J1xSQD#;WT=6JVAK|{RhvOVWV z=#!jdl@qJ#0vKc9X8gX7QH*_kuq{61jhUoXeO^6xXSCsZ0F8uKA-;5kyCYLYc<`(M ze2z3{2sp_+DcCJ*p2dr^4)cAP;JvvU1L^JRFW$Lh;jZ()1-w%7*UY+}JcJEDS{O*l zv4M%$hw*riuDSj0?e6ONlZl1XRo>0v1267s^s5}sD8i5C$@GE={q2hnj|dmo;q&Ht zP6N)-sy{g`m&Tn{);o2{7v%TOeL^o~ry){+HSOrHU(^%HtNQNjU<nn73AX}VYg`jg zgHXuh@$V$KTFNB1ms&a3g?5^gyb#&eJ0C+sJ9My(A^~!bs0ZLVy8@sOe-%q?q^2CA zBFAL#9N;KAg=qi7BxT(*RbDTY)YQFR+L9W`+&2iuZzpZXAzJa01&Y&d_e7#6w|x&j z58dq5wxf`vn^yc<4mX>Z@|J+YTii%_8zWnVOVCg(9<R{-1ds8!C@r!)8V!Y<C^(W> zo;!c@(wqA{r=aVF?a>1cZ1OCAt1*hT(r?_omff{VY+SMjM%{8kTs#4d93ufy*xjpU z=Xvzb^7ngxQ8SF^-1bMVlgo&sE+dl%CRvD{%uT`JzEAF;eX=q!*K=_WNehp&EtXn2 zo*&8VL!eCx9;FnBBQz1Z*w=+7!Tey_J7B%sY^Lzwv$BlkdQj%Vv;f$idPq&eqioZg z5<ic!``M9&uNF2_GHP<D6g*27EK$9Z<Vj`8OiEJfwRIe4>;3Nb?h#*f`#X>7^~!b0 z*Qsqm8ECypEVE&le&SV5UX6b_ZSbh;cuSD9WDR(2S8S|(QH&Qon&3>Hp8|icD6{$2 z-10R`PDdw0Az0qM=tuG{2b26@5QK_E8}9n4wYrjakG*(3#MZy-Ij7zFp7F$be!*Ph zFnQ2h!$4toVHJzQ_8AG`4NQi(`j+DG?q_csfy_{_xOtH-Kw;3#EPqxHtl&9bd+mao zll0mB!hB~&|84-mPq(;X>(I=LeIyNN`5;K*(#9&kS!|lLb)(lMG|`QqtMVrEc0V7l zH~$R?f*=2U$s4BnE7)&efyzjcUFKku_DTM9k8|k5q_j@|GTjzBx)NPav9S_wCv5x$ z@BRyqi<&vj8h~A74;e6W<hOVhk5Ph%aoB8_Es2YQ!dbguO;k|Py#rsM-fyp?CiqpN zf=59|oNIJW&a7#;c^`eGo$yP`)ry}5D-*rc386G_d0Z&_vibI0bFNLjZmH|qRbkJs zO<YhjFa;_#jy7UUdZC9XxtDRxBR|Z}afiuBBmumcMe^m?3AP&@ctOBFp)P=F!G~s^ zWxBQ4<9U;WcA*7bx&mvVXba)R&KPh>G4JEPjk%)aIohW);<wZB-1Ka}{Zd+lTbJc; z(S7_DmVo%J6>F0;;_lrDY*&3YsVqHnobUI5`(Dc3kCef%1z~2b*a!E0&woU@mTFjC zGcCBnW&CZJjy}^0<!AYSKem4nOMm+Z=iPw79nwzZ<9G#zdfBORCKf9F*trblLZ0AJ zsJ(R!)nE=3?d|JfsNH01@;UPDSf^u-z3zD{eIfXe<t71nD*|vd$6ttizbVaQy|X+{ z{06RY7BGIF<E03*MY(_4g`dSDnY?<dw5=kbcS49uak1>p(?qi1YOxHpmqWRCSnf5N zzw$7)1-MIob^#)0{4HAQB;WaOeVFs^NQG0`)6&l=<S$*_1@CvegNBoT^^7-yr9IyP z$({Dw<`Nv~<liXH1xuf*@XvlJ**Ty92L+^G=gEk(E<}}RXu1Yle=ZbXxSd3{+pF#( zUas{ldF^m!Kc~K5s^uWERPRX&m6ludS|k(8SVnGFrB~LH=H;DRt}nm(y2r<)SXn;& zutu$C8Pu-*cI;$-R@#wVmB9%iC(X9*Gvk#xu)k%Q{tL8wZ$Q-J*ZTMqCpV)F)bXCi z?rUnp8@G==w;H6G@k`CRXrP~ot43Y~mvNG$!O>OF5LX&AruyM;W<(Q%Gv;dQ@3Y4) zT-lX%7W5W%Bh99My_m@&@nyHNo|<z}Z)vyceZq_Mb|hk7_s-!Rb>`5+K*3%l&M0ro zg3SJn%3#qma?=8Bk2N=4MO%ihU_^sB&k$clFuzb*5G-IvM=O3Ij@)mUOB6)=r$WTY ztC35f%_=p~T<>6^3hK$Qo*GiQNvrxoRl**)06%s!X>ERY7BuJHOl`V+PtgPf2|9Qm zwV8#GviG;OE2?TOf8O3G=<43Xy-*{H8p}FP-V6+HxEhMwk$y2gj>;*pm9d?k&b8{? zxgG?bM$LVs1MbI9xp&JBS1YG#z6J{cJAl8&BT|$j?X<v(L79(HZh+AA3!*$$@TpHC z;UC$eQ7QIOAeXGeVnj#s90m2}bqf^1($<4;?iyw6gt~23^0}XU6{dDhDDH}1#JcX! zNTXO5zGT>4$b<dASf+v#gY&l7>#s+cVp*JSf_FKC>%G?Z9#Y<>UM@z?Nz*Xq(ZBMP ziRpE-Wj*zY0CK;!??UpI;0o|qf793RfP@sdWJO~B?MPl|0E7X@=aGG4=f{q({U{3B ze1fC?BjNrD_6?d?|7^um>%7&bMU8dGD&IGwW(E16h*ef>X`$iQw;V5-QN(K?_oQ@J z`3Ra`o+^or*4=VhLRfCt9aMa>b*v9>KuJs=HLT|!LD<$WVaF&wQ6-;=zn}QlA&-h$ zmz(1u?oqG(>`h-$CWhX?gB7!nMdrVGPHt{+7U{r(=QqBFgdf7Tr`9=JU%gx!uVL$! z49N6V(;V5uW|P74H)^L&0jgk0Myei1!uqt&vKqOSUqp-OWZ!7fKAYUAeZyen|DDtm zJJIKnwe~Pm$>oKj4zQZFFw1m)x`l*Czd-}w@=j&2Q3ND7Xq!8G_H79N+b^>|MyiE4 zvXteHJM*xAhGF%syLQBX!yfkfjUfXew2RWBG+8a}gIY9p+1{_oDiLxXZXS|uxV)+J zu6=y=!!w^{w;#QIxYy|t*v@J3_(_?}v20VtHe0zM*<L?_!L!OoN_uWWHWt1o!JI5{ zN53rgkdK>vOt)orYXqI(A|BPM08~ik`a-URIe%F?MLTc_LMb(x6*CtZIQN&tvMAnp zWZG{qwl2GrRggrJ=M^}$is{FQR4^D;=Vvfdeg3j(o-e7#$*(lV^;y2jfd%I)#D;;O zfM~wnVw+X}*XOE!ORlIwM%PVP*c@f%RM_c5TGs-W&6q#)LME}&9bjW_xovpHdYj^r zPyWYXd=f3@4HpwY`f!3&9md@KSBv>}n&Q)cj17N6VA(b2;zXm*S64nL?S<S<b|ps~ z?ZI>P8`xL-_YHW)#gYoXA$!e4YLI)d3DS{&{U=(}goW1r!|0fKv7S@Z_*_;5*pT2z z&x2QFuKZ-eiwSE9u;bU85&Yp|1U9hYouGH;w*O(3<6~!W%K_msTC_>B-~J02YvhWc zyjOsWA9GYrYZ8OI{Z`y9znoxYOODtMA9%3@dUPKqUMSX`Gv2(f+M=@?LAe*vZ#7@F z|KiAlvlXY4(O<zc5&5z}`bF!vOpDZglikkk!3_KY%4AoBhjh@|g08+jU9EZ!u2Wc{ z1kt~7;xp}-WbU;;@s{nA_#d#@PTDJ&x9F@3(I;Zwseqy77v6w=9Wg*=DHIdo$j@Ez z!9?d9_js5k&Q!}Sx}$KY;QKL}|0badrfI2wvY2W{MOSFTZU2FgfZN@>#1cnbN&OmE zc*NmM*e!mw8~YsX$6P<*HsCNZ92Nw%>&!ZYIv0HYH-ugPFLG|+dzU`1c&70GlGEX? zww*{kE=$Gw+x4$g<wLoZ;BM^*ZN_N5$M-R?fa@a)P)O*7D#Je_DN%wD0*p%YEdB9T z!{EP=_pQaSgq17-#34v!aV_YKfq5b7XrP@+Q&RWoBBAK&Sz~)#=kh;ddlBW(EqdsJ zw*WI~dN#)Whw;8Q<Pl6FV|T5y7#1(H1;Lakp>FF>&2KZw)_?F@{OIQ;Mc=uD_h@ji z`i~ODDOoOga!<l3h}u`q%$LpISM(*QOZ^8ACoBP6JoZ5Js-U}UdQ#qQiWEKh89Lj4 z&d1mk`+#2<a4B)<2*SBMRxl*@lBRHoyHUwv3J+$a`HK0<E)JytmA(~i{6OvGf24hH zulSr~(R&U>1d4PGDI!@WrS(z+sGjF}<@&8WTJ05W_6n9rY;;3T*wJN6Gb4(LYu2)= zJX07Yc}(aQI#<7`EFZz#E>ySmHqum%V4x$|?{S?NdJNCBa$71Btqs8qw8#aP?imr_ zVd78Q_ML~{U~u%vzLx|>s2V~Ruc$P!TPO{Dm3Q2oO@BlF009W_$kl_LUvh-$eGIgC zu6M4?XIu{Ka&eb%=U23?>*%>p+Bt&Ep5z62{VO-5TTc=WBex==X5l{NZ*Ft_+@r}7 zPxc=}dQktfS~f7Ask&x`?R!3yHD0EIg+)wMVMUGH(2j^7BF08N=g{OV<OC%wCfY$b zvS3Ek;<4FQkxKCkK4jJ1pVw}%Rm(Rsc*1{Rv8;=(SD|VCpUJ8H)o6|37q``tQ~W9y zpdrcOqTNpHO~Cvw(XYwtDKkuyIab_yUNjC5{Ku}FI!jk>!jRJHhyQHkjzc8-xHXxw z@@8H$g$?6>PXnyg>C@Ah*0_Ir?!uq6{Qo)=fW)cV1l@3q{|xLu#s9x&2GDrI;)sMf Vx~j>Po5Ldn&o%WmYSe5a{|}oi%54Au literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/fonts/times_bold.png b/AvocadoEdition/plugin/kcaptcha/fonts/times_bold.png new file mode 100644 index 0000000000000000000000000000000000000000..4048121076aa56d2840395ed5389bbf5b865fa45 GIT binary patch literal 13965 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/img/dot.gif b/AvocadoEdition/plugin/kcaptcha/img/dot.gif new file mode 100644 index 0000000000000000000000000000000000000000..35d42e808f0a8017b8d52a06be2f8fec0b466a66 GIT binary patch literal 43 scmZ?wbhEHbWMp7uXkcLY|NlP&1B2pE7Dgb&paUX6G7L;iE{qJ;0LZEa`2YX_ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/img/reload.gif b/AvocadoEdition/plugin/kcaptcha/img/reload.gif new file mode 100644 index 0000000000000000000000000000000000000000..439b6db920c675f17632be89ff0e2337443586ac GIT binary patch literal 616 zcmZ?wbhEHb6lV})c*el+;@PtsH*PFjwk*D&?EnA&PaZw0YVVo8V9C=bPbSY<&^~$k z&6~GUN~%trK2zM(o>Wxv^zq}0)~*{jZq8Y{V&1Zq5ANT;ckkZ*Lr0Q|E1UZ#KYsYA zwzIEw!qlTDPR?JkI=`-Y#-gQ*R<7B-|KQp47tWr$kWo>)Z0&~rS@UKuUfwrj&Z>=@ z*KXOCSy?w_?!xNM-sF<1yqc!#H*VB-PdIe!_@jppA3S(a*4#0F`Kp4tmJQo>q?T2m zJbm`?@e>IJWk9*YhSo<99(GNgdH&+1qQ<tiiPIQ{8c_Vn0(P<vhy=w61N+ei#-`?$ z*0yGr&aUpBUM5BshDnpBOr6?4aoVhDGiLEB2+DI=iq4rZm4lsm^%_3j>C306ujV&$ zu~==TJZ0`=rPXXIlT6hPa7^AiNsn2Td#c82;}aVhSb3O*ry24y%UzziX3bPq9cJD8 zlN>k?2u<adU>12XnO)j$n)zz+&y!gh6rEHu11=^v@YYY7<k_?!fuWhlv29J&#%6I- zPm`dQ=&y^J*Z54WP$^(&KFr0v%posoWx>*A)Aa0*rARt7oSkh^{7OWCgTWdA*%H=* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/img/sound.gif b/AvocadoEdition/plugin/kcaptcha/img/sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..5adcb1e8b91b59e615f638d3a0d9e63c7c72e137 GIT binary patch literal 144 zcmZ?wbhEHb6lV})Sj52a;@PwKg0dSoZY*22?EnA&3^1VhlLgGw0g)iJ49uY#yYB2$ zIpz6UfaS&6>isj-s~%+JJ(ZZVQhZI?>AfE`vP*i4i~i+l$DU{B5UZRac~QfMsdIOl n$Isb{%R{DJUaFiM8};U-wp{$#ZTeEG5<BjH*ikcqfx#L8`ad|} literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha.js b/AvocadoEdition/plugin/kcaptcha/kcaptcha.js new file mode 100644 index 0000000..536dccd --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha.js @@ -0,0 +1,107 @@ +$(function(){ + var mp3_url = ""; + + $(document).on( "click", "#captcha_reload", function(){ + $.ajax({ + type: 'POST', + url: g5_captcha_url+'/kcaptcha_session.php', + cache: false, + async: false, + success: function(text) { + $('#captcha_img').attr('src', g5_captcha_url+'/kcaptcha_image.php?t=' + (new Date).getTime()); + } + }); + + $.ajax({ + type: 'POST', + url: g5_captcha_url+'/kcaptcha_mp3.php', + cache: false, + async: false, + success: function(url) { + if (url) { + mp3_url = url + "?t="+new Date().getTime(); + $("#captcha_audio").attr("src", mp3_url); + } + } + }); + }); + + $(document).on( "click", "#captcha_mp3", function(){ + $("body").css("cursor", "wait"); + + $.ajax({ + type: 'POST', + url: g5_captcha_url+'/kcaptcha_mp3.php', + cache: false, + async: false, + success: function(url) { + if (url) { + mp3_url = url + "?t="+new Date().getTime(); + } + } + }); + + var html5use = false; + var html5audio = document.createElement("audio"); + if (html5audio.canPlayType && html5audio.canPlayType("audio/mpeg")) { + var wav = new Audio(mp3_url); + wav.id = "mp3_audio"; + wav.autoplay = true; + wav.controls = false; + wav.autobuffer = false; + wav.loop = false; + + if ($("#mp3_audio").length) $("#mp3_audio").remove(); + $("#captcha_mp3").after(wav); + + html5use = true; + } + + if (!html5use) { + var object = '<object id="mp3_object" classid="clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95" height="0" width="0" style="width:0; height:0;">'; + object += '<param name="AutoStart" value="1" />'; + object += '<param name="Volume" value="0" />'; + object += '<param name="PlayCount" value="1" />'; + object += '<param name="FileName" value="' + mp3_url + '" />'; + object += '<embed id="mp3_embed" src="' + mp3_url + '" autoplay="true" hidden="true" volume="100" type="audio/x-wav" style="display:inline;" />'; + object += '</object>'; + if ($("#mp3_object").length) + $("#mp3_object").remove(); + $("#captcha_mp3").after(object); + } + + $("body").css("cursor", "default"); + return false; + + }).css('cursor', 'pointer'); + + $("#captcha_reload").trigger("click"); +}); + +// 출력된 캡챠이미지의 키값과 입력한 키값이 같은지 비교한다. +function chk_captcha() +{ + var captcha_result = false; + var captcha_key = document.getElementById('captcha_key'); + $.ajax({ + type: 'POST', + url: g5_captcha_url+'/kcaptcha_result.php', + data: { + 'captcha_key': captcha_key.value + }, + cache: false, + async: false, + success: function(text) { + captcha_result = text; + } + }); + + if (!captcha_result) { + alert('자동등록방지 입력 글자가 틀렸거나 입력 횟수가 넘었습니다.\n\n새로고침을 클릭하여 다시 입력해 주십시오.'); + captcha_key.select(); + captcha_key.focus(); + return false; + } + + return true; +} \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha.lib.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha.lib.php new file mode 100644 index 0000000..8d345d9 --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha.lib.php @@ -0,0 +1,285 @@ +<?php + +# KCAPTCHA PROJECT VERSION 1.2.6 + +# Automatic test to tell computers and humans apart + +# Copyright by Kruglov Sergei, 2006, 2007, 2008 +# www.captcha.ru, www.kruglov.ru + +# System requirements: PHP 4.0.6+ w/ GD + +# KCAPTCHA is a free software. You can freely use it for building own site or software. +# If you use this software as a part of own sofware, you must leave copyright notices intact or add KCAPTCHA copyright notices to own. +# As a default configuration, KCAPTCHA has a small credits text at bottom of CAPTCHA image. +# You can remove it, but I would be pleased if you left it. ;) + +# See kcaptcha_config.php for customization + +class KCAPTCHA{ + + // generates keystring and image + function image(){ + require(dirname(__FILE__).'/kcaptcha_config.php'); + + $fonts=array(); + $fontsdir_absolute=dirname(__FILE__).'/'.$fontsdir; + if ($handle = opendir($fontsdir_absolute)) { + while (false !== ($file = readdir($handle))) { + if (preg_match('/\.png$/i', $file)) { + $fonts[]=$fontsdir_absolute.'/'.$file; + } + } + closedir($handle); + } + + $alphabet_length=strlen($alphabet); + + + $font_file=$fonts[mt_rand(0, count($fonts)-1)]; + $font=imagecreatefrompng($font_file); + imagealphablending($font, true); + $fontfile_width=imagesx($font); + $fontfile_height=imagesy($font)-1; + $font_metrics=array(); + $symbol=0; + $reading_symbol=false; + + // loading font + for($i=0;$i<$fontfile_width && $symbol<$alphabet_length;$i++){ + $transparent = (imagecolorat($font, $i, 0) >> 24) == 127; + + if(!$reading_symbol && !$transparent){ + $font_metrics[$alphabet{$symbol}]=array('start'=>$i); + $reading_symbol=true; + continue; + } + + if($reading_symbol && $transparent){ + $font_metrics[$alphabet{$symbol}]['end']=$i; + $reading_symbol=false; + $symbol++; + continue; + } + } + + $img=imagecreatetruecolor($width, $height); + imagealphablending($img, true); + $white=imagecolorallocate($img, 255, 255, 255); + $black=imagecolorallocate($img, 0, 0, 0); + + imagefilledrectangle($img, 0, 0, $width-1, $height-1, $white); + + // draw text + $x=1; + $odd=mt_rand(0,1); + if($odd==0) $odd=-1; + for($i=0;$i<$length;$i++){ + $m=$font_metrics[$this->keystring{$i}]; + + $y=(($i%2)*$fluctuation_amplitude - $fluctuation_amplitude/2)*$odd + + mt_rand(-round($fluctuation_amplitude/3), round($fluctuation_amplitude/3)) + + ($height-$fontfile_height)/2; + + if($no_spaces){ + $shift=0; + if($i>0){ + $shift=10000; + for($sy=3;$sy<$fontfile_height-10;$sy+=1){ + for($sx=$m['start']-1;$sx<$m['end'];$sx+=1){ + $rgb=imagecolorat($font, $sx, $sy); + $opacity=$rgb>>24; + if($opacity<127){ + $left=$sx-$m['start']+$x; + $py=$sy+$y; + if($py>$height) break; + for($px=min($left,$width-1);$px>$left-200 && $px>=0;$px-=1){ + $color=imagecolorat($img, $px, $py) & 0xff; + if($color+$opacity<170){ // 170 - threshold + if($shift>$left-$px){ + $shift=$left-$px; + } + break; + } + } + break; + } + } + } + if($shift==10000){ + $shift=mt_rand(4,6); + } + + } + }else{ + $shift=1; + } + imagecopy($img, $font, $x-$shift, $y, $m['start'], 1, $m['end']-$m['start'], $fontfile_height); + $x+=$m['end']-$m['start']-$shift; + } + + //noise + $white=imagecolorallocate($font, 255, 255, 255); + $black=imagecolorallocate($font, 0, 0, 0); + for($i=0;$i<(($height-30)*$x)*$white_noise_density;$i++){ + imagesetpixel($img, mt_rand(0, $x-1), mt_rand(10, $height-15), $white); + } + for($i=0;$i<(($height-30)*$x)*$black_noise_density;$i++){ + imagesetpixel($img, mt_rand(0, $x-1), mt_rand(10, $height-15), $black); + } + + $center=$x/2; + + // credits. To remove, see configuration file + $img2=imagecreatetruecolor($width, $height+($show_credits?12:0)); + $foreground=imagecolorallocate($img2, $foreground_color[0], $foreground_color[1], $foreground_color[2]); + $background=imagecolorallocate($img2, $background_color[0], $background_color[1], $background_color[2]); + imagefilledrectangle($img2, 0, 0, $width-1, $height-1, $background); + imagefilledrectangle($img2, 0, $height, $width-1, $height+12, $foreground); + $credits=empty($credits)?$_SERVER['HTTP_HOST']:$credits; + imagestring($img2, 2, $width/2-imagefontwidth(2)*strlen($credits)/2, $height-2, $credits, $background); + + // periods + $rand1=mt_rand(750000,1200000)/10000000; + $rand2=mt_rand(750000,1200000)/10000000; + $rand3=mt_rand(750000,1200000)/10000000; + $rand4=mt_rand(750000,1200000)/10000000; + // phases + $rand5=mt_rand(0,31415926)/10000000; + $rand6=mt_rand(0,31415926)/10000000; + $rand7=mt_rand(0,31415926)/10000000; + $rand8=mt_rand(0,31415926)/10000000; + // amplitudes + $rand9=mt_rand(330,420)/110; + $rand10=mt_rand(330,450)/110; + + //wave distortion + + for($x=0;$x<$width;$x++){ + for($y=0;$y<$height;$y++){ + if ($wave) { + $sx=$x+(sin($x*$rand1+$rand5)+sin($y*$rand3+$rand6))*$rand9-$width/2+$center+1; + $sy=$y+(sin($x*$rand2+$rand7)+sin($y*$rand4+$rand8))*$rand10; + } + else { + $sx=$x-$width/2+$center+1; + $sy=$y+(sin($x*$rand2+$rand7)+sin($y*$rand4+$rand8))*1.5; + } + + if($sx<0 || $sy<0 || $sx>=$width-1 || $sy>=$height-1){ + continue; + }else{ + $color=imagecolorat($img, $sx, $sy) & 0xFF; + $color_x=imagecolorat($img, $sx+1, $sy) & 0xFF; + $color_y=imagecolorat($img, $sx, $sy+1) & 0xFF; + $color_xy=imagecolorat($img, $sx+1, $sy+1) & 0xFF; + } + + if($color==255 && $color_x==255 && $color_y==255 && $color_xy==255){ + continue; + }else if($color==0 && $color_x==0 && $color_y==0 && $color_xy==0){ + $newred=$foreground_color[0]; + $newgreen=$foreground_color[1]; + $newblue=$foreground_color[2]; + }else{ + $frsx=$sx-floor($sx); + $frsy=$sy-floor($sy); + $frsx1=1-$frsx; + $frsy1=1-$frsy; + + $newcolor=( + $color*$frsx1*$frsy1+ + $color_x*$frsx*$frsy1+ + $color_y*$frsx1*$frsy+ + $color_xy*$frsx*$frsy); + + if($newcolor>255) $newcolor=255; + $newcolor=$newcolor/255; + $newcolor0=1-$newcolor; + + $newred=$newcolor0*$foreground_color[0]+$newcolor*$background_color[0]; + $newgreen=$newcolor0*$foreground_color[1]+$newcolor*$background_color[1]; + $newblue=$newcolor0*$foreground_color[2]+$newcolor*$background_color[2]; + } + + imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newred, $newgreen, $newblue)); + } + } + + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Cache-Control: post-check=0, pre-check=0', FALSE); + header('Pragma: no-cache'); + + if(function_exists("imagejpeg")){ + header("Content-Type: image/jpeg"); + imagejpeg($img2, null, $jpeg_quality); + }else if(function_exists("imagegif")){ + header("Content-Type: image/gif"); + imagegif($img2); + }else if(function_exists("imagepng")){ + header("Content-Type: image/x-png"); + imagepng($img2); + } + } + + // returns keystring + function getKeyString(){ + return $this->keystring; + } + + function setKeyString($str){ + $this->keystring = $str; + } +} + + +// 캡챠 HTML 코드 출력 +function captcha_html($class="captcha") +{ + if(is_mobile()) + $class .= ' m_captcha'; + + $html .= "\n".'<script>var g5_captcha_url = "'.G5_CAPTCHA_URL.'";</script>'; + //$html .= "\n".'<script>var g5_captcha_path = "'.G5_CAPTCHA_PATH.'";</script>'; + $html .= "\n".'<script src="'.G5_CAPTCHA_URL.'/kcaptcha.js"></script>'; + $html .= "\n".'<fieldset id="captcha" class="'.$class.'">'; + $html .= "\n".'<legend><label for="captcha_key">자동등록방지</label></legend>'; + if (is_mobile()) $html .= '<audio src="#" id="captcha_audio" controls></audio>'; + //$html .= "\n".'<img src="#" alt="" id="captcha_img">'; + $html .= "\n".'<img src="javascript:void(0);" alt="" id="captcha_img">'; + if (!is_mobile()) $html .= "\n".'<button type="button" id="captcha_mp3"><span></span>숫자음성듣기</button>'; + $html .= "\n".'<button type="button" id="captcha_reload"><span></span>새로고침</button>'; + $html .= '<input type="text" name="captcha_key" id="captcha_key" required class="captcha_box required" size="6" maxlength="6">'; + $html .= "\n".'<span id="captcha_info">자동등록방지 숫자를 순서대로 입력하세요.</span>'; + $html .= "\n".'</fieldset>'; + return $html; +} + + +// 캡챠 사용시 자바스크립트에서 입력된 캡챠를 검사함 +function chk_captcha_js() +{ +// return "if (!chk_captcha()) return false;\n"; + +} + + +// 세션에 저장된 캡챠값과 $_POST 로 넘어온 캡챠값을 비교 +function chk_captcha() +{ + /*$captcha_count = (int)get_session('ss_captcha_count'); + if ($captcha_count > 5) { + return false; + } + + if (!isset($_POST['captcha_key'])) return false; + if (!trim($_POST['captcha_key'])) return false; + if ($_POST['captcha_key'] != get_session('ss_captcha_key')) { + $_SESSION['ss_captcha_count'] = $captcha_count + 1; + return false; + } + return true;*/ + return true; +} +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha_config.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha_config.php new file mode 100644 index 0000000..90354d0 --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha_config.php @@ -0,0 +1,52 @@ +<?php + +# KCAPTCHA configuration file + +$alphabet = "0123456789abcdefghijklmnopqrstuvwxyz"; # do not change without changing font files! + +# symbols used to draw CAPTCHA +$allowed_symbols = "0123456789"; #digits +//$allowed_symbols = "0123456789abcdef"; #digits // 스캔 방지를 위하여 abcdef 추가 151029 15:00 +//$allowed_symbols = "abcdeghkmnpqsuvxyz"; #digits +//$allowed_symbols = "23456789abcdeghkmnpqsuvxyz"; #alphabet without similar symbols (o=0, 1=l, i=j, t=f) + +# folder with fonts +$fontsdir = 'fonts'; + +# CAPTCHA string length +//$length = mt_rand(5,6); # random 5 or 6 +$length = 6; + +# CAPTCHA image size (you do not need to change it, whis parameters is optimal) +$width = 160; +$height = 60; + +# symbol's vertical fluctuation amplitude divided by 2 +//$fluctuation_amplitude = 5; +//$fluctuation_amplitude = 11; // 파동&진폭 151028 14:00 +$fluctuation_amplitude = 5; // 파동&진폭 원래대로 151029 15:00 + +#noise +//$white_noise_density=0; // no white noise +$white_noise_density=1/6; +//$black_noise_density=0; // no black noise +$black_noise_density=1/20; + +# increase safety by prevention of spaces between symbols +$no_spaces = false; + +# show credits +$show_credits = false; # set to false to remove credits line. Credits adds 12 pixels to image height +$credits = 'www.captcha.ru'; # if empty, HTTP_HOST will be shown + +# CAPTCHA image colors (RGB, 0-255) +$foreground_color = array(0, 0, 0); +$background_color = array(255, 255, 255); +//$foreground_color = array(mt_rand(0,100), mt_rand(0,100), mt_rand(0,100)); +//$background_color = array(mt_rand(200,255), mt_rand(200,255), mt_rand(200,255)); + +# JPEG quality of CAPTCHA image (bigger is better quality, but larger file size) +$jpeg_quality = 90; + +$wave = true; +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha_image.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha_image.php new file mode 100644 index 0000000..80de84c --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha_image.php @@ -0,0 +1,9 @@ +<?php +include_once("_common.php"); +include_once('captcha.lib.php'); + +$captcha = new KCAPTCHA(); +$captcha->setKeyString(get_session("ss_captcha_key")); +$captcha->getKeyString(); +$captcha->image(); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha_mp3.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha_mp3.php new file mode 100644 index 0000000..10cae73 --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha_mp3.php @@ -0,0 +1,44 @@ +<?php +include_once("_common.php"); + +function make_mp3() +{ + global $config; + + $number = get_session("ss_captcha_key"); + + if ($number == "") return; + if ($number == get_session("ss_captcha_save")) return; + + $mp3s = array(); + for($i=0;$i<strlen($number);$i++){ + $file = G5_CAPTCHA_PATH.'/mp3/'.$config['cf_captcha_mp3'].'/'.$number[$i].'.mp3'; + $mp3s[] = $file; + } + + $ip = sprintf("%u", ip2long($_SERVER['REMOTE_ADDR'])); + $mp3_file = 'data/cache/kcaptcha-'.$ip.'_'.G5_SERVER_TIME.'.mp3'; + + $contents = ''; + foreach ($mp3s as $mp3) { + $contents .= file_get_contents($mp3); + } + + file_put_contents(G5_PATH.'/'.$mp3_file, $contents); + + // 지난 캡챠 파일 삭제 + if (rand(0,99) == 0) { + foreach (glob(G5_PATH.'/data/cache/kcaptcha-*.mp3') as $file) { + if (filemtime($file) + 86400 < G5_SERVER_TIME) { + @unlink($file); + } + } + } + + set_session("ss_captcha_save", $number); + + return G5_URL.'/'.$mp3_file; +} + +echo make_mp3(); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha_result.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha_result.php new file mode 100644 index 0000000..3975afe --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha_result.php @@ -0,0 +1,13 @@ +<? +// 캡챠 세션값과 비교하여 맞는지? 틀린지? 결과값을 출력합니다. +include_once("_common.php"); +//header("Content-Type: text/html; charset=$g4[charset]"); + +$count = (int)get_session("ss_captcha_count"); +if ($count >= 5) { // 설정값 이상이면 자동등록방지 입력 문자가 맞아도 오류 처리 + echo false; +} else { + set_session("ss_captcha_count", $count + 1); + echo (get_session("ss_captcha_key") == $_POST['captcha_key']) ? true : false; +} +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/kcaptcha_session.php b/AvocadoEdition/plugin/kcaptcha/kcaptcha_session.php new file mode 100644 index 0000000..657f088 --- /dev/null +++ b/AvocadoEdition/plugin/kcaptcha/kcaptcha_session.php @@ -0,0 +1,18 @@ +<?php +include_once("_common.php"); +include_once(dirname(__FILE__).'/kcaptcha_config.php'); +include_once('captcha.lib.php'); + +while(true){ + $keystring=''; + for($i=0;$i<$length;$i++){ + $keystring.=$allowed_symbols{mt_rand(0,strlen($allowed_symbols)-1)}; + } + if(!preg_match('/cp|cb|ck|c6|c9|rn|rm|mm|co|do|cl|db|qp|qb|dp|ww/', $keystring)) break; +} + +set_session("ss_captcha_count", 0); +set_session("ss_captcha_key", $keystring); +$captcha = new KCAPTCHA(); +$captcha->setKeyString(get_session("ss_captcha_key")); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/0.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/0.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..a51bd81e114b9d6dd47e28bba688b1ef873479d6 GIT binary patch literal 13259 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 Gf&T?R6l9_R literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/1.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..8bb5448b6f8da52042bfdf0ecf3e5599f425fc5d GIT binary patch literal 13259 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 Hv%voXsp5r% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/2.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..0fc093579f297b3b78bf6aec010538eca2a0707f GIT binary patch literal 13259 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 Fe*m3tjHv(s literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/3.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..bcf0d27f0261953ce8a929f62db982ce5ec76dc0 GIT binary patch literal 13259 zcmeI2cT|(hyYJr=LIMFoXaNC3?~sImfT#%s3^8DUfD}tY2Ngq8z?Kkt?@d&?fPjdI zsOSz=nn<yLqEZF6Wz%%qxv<ag{Bi#{Yu$72I`^;NtTlP&&17cYJfHP_XWnPVj$#Y} zwh}yuX~!gN6+l~=$*{ryXOT>|`p=@1^?|J-cq`+W?lw+aR%j~|aCl>;^+AWN;&xl> zgZB3Ss__l>2exXqFSlzBxw*M*neFxf)5gJi%gAkI+fZL$tUbpVd*~z^YkeyCv~Os* zZ|GJ###ZG&cXN<o^RMET`FHxa2mbAWe|zBH9{8X0z~+z4t<J$U8Xd4uF5m)f!wxe5 zk)|khrFsD5DxuE5%>_1xX9|WBP>B~O+5=}mE%|SMH3jlJvO%6^J8J}fV&OPq4A83& zIdR~p{#OM_77GJvQ`zL@Vu5a<rXB64Houu2{A2UX=KamBRAG2=>+{+`!2d|6d*kUp zt&b*l9unGXU>+}v)%AqI?~O%$quu^;X-=Cap_3^;-F2srX5aknmcNUAZt;1Or<`c! zG5h}RD8)e4cgzh!>xJRsACtE41vi(A$3*r{-VVxH@_Ev2vXrX9ah@G7WP5?Dnpi0f zT32(g9}9d)h%H?!0$oAwJ{Md0%IK151as2v+W3+E!c{gKQziSedb16E4_fQ_e^|cp zAUC*ORJo`DTk-LdYwg~Iq4Ny3V5|>kIno=Wr>ZKe%`C_ICr;c^RFj8lCD)l$eyZtu z`f>9|HXtprR;t_&af@a!A(PnS5;T$6v+80q%XW+mA71+&ordQ`-gWW?by0PzCqTA% z_y9Laosv6?Klr6gNnZV~$E1uxq(OB>@K`JP{r~B>|D8TfW{tIS2))3^W>%&kM;b-< zFS`$*&<WF{s&8v_c?F;C4~a&o7+3yOjWN4d=QB_OCmTc>ROF60$;~P1+OS~`cL)+4 z8!NfG^<`e(L5C<g-5bTL@;UuQ-oWWe9F=944A(RsdCi3*tXBfEPCb<&4Suh_9(OOZ zXzYR{S@DPq!Pfzb&2N_-9SG17T}_u!ZQ^Tr770&(kEF@CGH&8;>y_KhM!T3(!qAEY zEQi{WCE6S&D};fo>Qhju7+Gx4FQFMuk_qL&kVe7~!`Is?7L0qA5vt79ymTl95;bfh zT9-S@RPE0ho7yW=XY*a%rQwv{t0{7Gy5lw>-Hf$jWhy^1n&E8Sk2<wQC^JG;Y+>2X zNxYKW{y;~uI{}%fh{pL?eJJVS*@EFIl2A36P@=*g<jBLS_KxUv1bbat-fg4|NHy`E zN+?BCKbsZ22}`s3vx?{fZ}!=^BM}#rbs<USxaVZ+->4I1_#DEH19KvB!fxs{&E~vB zxvz-=(=bf0LV!Anwi|3sH$@*s|E6Sy01||Efnwx4ejiHire+PRb^7Uvsqvt}Ildv$ zgq>1>PhOlhA0L!E)y<cck~daqd5A0HM8wci)Cw`Yi;1Zae|##tI)(zRXi_J3u{CCl z=Iw-0z`CJd=F=UggZl>y`xR#`HNBd~%uu$=ribJzR8~z(ex32YY<ctaPb%KmqGRY+ zMg7v#bTpU6m1k5-1FO7_WL8Gi+m?)KX*G-M_3_c9Lk4I`6}~1!jJqCk)Fu1-^&o{L ztKT^q`^$z+hl$M!``p||7G5qb`KEy8wI}SJi~E06^0%$z<U*jpKpd`AI8_|!3_Wl7 ztMWXqO#aysALB9b-GIy_q&yCDLU@}HIb-dzvK@a*L(UcbxNQxUocTvX>{p8oHFc zR$uVUlkt=$w^5|KM?9o8q$+dtd*^V1;fwv&`fd^`ww=}jdtVAed!U!@Gl5;gqI}Fs zwcYwHo<3Evo6rKOVWW1`V){r^#5NL*SN3}UglOlJH&8q(Om60w%yD6>6Nh?{u6gT6 zd@5xY)Kt$nzA-F**EKH8EgncLb<9gG>~A8Ekg$CrB*x9`h}s&foF)gbEop6+6F!sI z7Rce|L9Fj(G|9zXZHIed-x+m2)O{`<J8>fw)1de6UO!cDz?Sl<qWy@;<AiF}*MvC^ zBBUn{Q`lwaFb+W_=bvkeoCF-7svE|Dj%Zqy(!~&IJ%zR9KYT>b-z`u6=nM5IEV)fA z(~iz!1WGiIu!`YO;zbLqEZrB4B8Tila0L|4>chbxL$js|DNLZwOO}_U)02FO9as^I z*tijrUS%H>!7IbJ-I5_5JHb13hv;~uzBI*ID!)2cL&8Z{Oy!FQQi=@3XDm{kG(0|c z(3TrD(M!h!8{VmrU$+UlNvu^U^+TefotWNtv8Rk^H0qXy*vocyTN<k0qtj<@mEW~; zY-F|+uxi0S9c)1wxnXX6Fr9!n9V349?aNd}r<;D@`Sdg0B?47*h2cc#pqAthi;`!| z4EKCbM7`>#+${ZZ8Q$|3aw~f<bIN-O;*6@MpK=>!H2|ss8A1365q%ER`yti}JS}*< z+dWhr9$S%iAL~wVk+ptFtpat5fe8KG7lyByxTrn%&F?%8zh9+(fY`%|xczKrp&vPh zR3vRx=4`2}^p-d;35~=utx4r)UG*@xgLPZ8pifzh!Ss35l?jEgv94$K9+^2I-<S5= zc_)Qo=Sz+xk|quPmo^LsuYc_JPyChC(J?Uh=$(8fD^t@3Rl|HDl5pm+Ih3pnmqCqa zUwM|?Yv7sOP)RnyNE7DnLbY09B^ynjon0%{r!L%+9CMpJ+-I&O=Y=voQ1pF|X!D;x zLgZ)nd2u+QZR@Kont&F0gwXLwl;M?&F>}#qNrFH9gd@(0E1E%<&%7>eo9T|7zVqA% zJzW05KCFg{qrkTbaU|C2wlw4(?c`#;rJ*fCxF}uZ)>F<_LW5lLKquq_8ErcW7$$hk zz-^S4*Y@nmL0d+O%T`#Py|!<M6$>1$1kqRI+=l6p`EgF3)XX%8Ifw&pri<%PaQ>xe zx+2v<^t>Ng|4+m27Z$O6C@Dd?TT=aGCU_~L5f$tB=BnEGBwp<icP7aA(Y**z6b?<% zK}zld6=VDQeD<MajtAztQ(l6=zUeYpv)F3C_buJhCvE~kf%a-1!P$-M4Eo(fx9aSU zX+xhRt0bJGU(%JmSpzwBdMW8L`tpO>+@o}8mWVafUf`EVAjnH}3wgZsm31`bl8U_J zsNyO*MfX19g?8wZ6pEdx&o5P8FZ3Qa^pe%7Y>E^uQe~9WrQOT@Gb%$X|4g2pi#q@d zoiA%B6(p#@Nw{X4PR|WrH}JO<kPf{3Y8BY7<)N@4GHiT_p!)H&t3uMX;eDLe%xc|V z*3YBQW=I~s!POo=>iWG>sKABOry+7dgDiiYzj<ZR{L6Qf77S`$1rC#?wjH>TdL1~1 zXKAQNJ8u(8lvvAF8icq<Gn}mNvbG3`q+Zk)^G1*zGZuLDZ0(IwJJSNeLPvV^c^KtL z<3N`q@!O+MvSZRc$7-UV91NM&%UcmrI6m-}$!-3#Q65@$u)9XhgmZCyYH{yd7Yl^( zGa+@q5;%Z0rjy|;u*je-2wpeRhvX_Y8EcoD3`CT#FpYW7h<KP?&y|7WdNgs>E~D9$ z^faS1v49}vt;uND4!yFZ)_`0g$kBzLcbu;t0gc#QsnJm*PLn{OVlTKgfO7S~!EIdQ zNj|^=ugFHS(YZk`rmRG~wk(n0p#R0$-GdP#D}Pb?aCqRkfaBIqRaXYbS`kN(_O~dd z+6sRgE!->lz9i1J_w8KC6Ahl}OysFxM*<YwSbcq+I|{LK2E{4_x4T_@y!0+na|~X_ zX5rJg`}c_YnfWtWLR^Kk{Y|2ckN}%_L`zuB#35AXm-Ftwy(dRy&Erf8L_3)V_Y*`^ zp|N~&X&{@grUnmYaSyi!#P)kFiX*!jQ~L9)ZWp<N`}Y3J&u=AUy`jhgK_<!q!#1%p z*=<6l5^D`ggM9N&Czp!59Dg$!%`J?ut)T<re%l(tXpRn7un${VPk#3Qmf=rv*9-9+ z4J1Kr_P+nHs6Pb7+gPV%rjbIujmO>z?}CS-C?ZO{l2$FCV=j%r6oPwXoqruCmfX5a zr?|HKajHSFMrI+Z_P`DK^0L~zv$wl)=7$HSTsJ%zAjyOGewYs$gOHAlIUhBKV&Txn zUEbqP#aKyj0?XeZNq~!-qvwIFWGj!IVOx7Oqz(Ah1>Eu$^-J>6gz7rI?+vI4@;&;I zGyl!FsTTnC;y8)5DKLzCaM3qSKQo=8`}zQ`1spf{T^em+L$iX^C91n|YiNLfDjE~^ zVQ_NXEc9uV1?D(JSi<6$&fuoZT%Ng;#9htW1J1YWY}LKlsQ@IEH6!UPi^Mg*HeRC- zah#1$y8-L~A<=>jZT0Zv+*n~36!j*EkqbP*sN)tV3vN|&7HZbQanE7m$`Rk43x4Z8 z(haTL8EWs8f9*IkmD>9ZB!DO~Trkhq(Iwq^L=7uJf0;r}jFgw8z2=al{WhW2jJ0fq zA-+X_r<1jNroX!xt>h$8?6?-fIjx%4;4@>>0S1Wz-Oq+VgP{B+oPUt7Q-k^EH+Lq~ zSk}*-yA<zae3v(R+ZcNPqS(_cpSYmtU<s$lbHV^Jgv|8z9HNDxnIn0k5Y5=2a=3k> z4e=7r#zYPZhw4M54&j9LVV<QOmuvHAEsHOr-?Gwp67C0)p>Osr`TTL=?!d>NyPRyY zWonn(_Sns=fER`czm4C~bdiM!E)&Y+bo4k7ySsA5%G`RmNbXl@z}u!5iiFbf<mwK+ zAZm(_#tg^LHDEKj1MGzDkg3<bY__*W?+s*v2ezevdLjThLw3RHRe~eKM?eRcs#e5{ z>xNWoDwduU>D32(gaxG#1w$N`rOHkgGevkhQ9M<QMEQhU`+vH^(OEEf1Dm<r@wx2i zigGs`O~8ul)dB|vpcb5W{drEArYi*Fb{O+Z(MYK#ldihUtmTpMNJzO99;qOY&PVbH z73JTs>u+_HB_gl>{d%GDT)oX4T@yh!Cy^LX9M?|H-m;6XvrTANZ0w4XLymhi)48j5 zZ0jkPO!Ow5{J03RO$`ux&^~RsNWAI0^!ty^#Yb=JLHhvMNJsk3&z-SFZb&wp<GsOY zKV447B~HzbD?TCjCepic0X{T00(2lfWuE`!TutPj*^6(_<Y%qjluN@EYTy<?AQGw* zq<)0BE{3aIFB$78sQA9Qd3EQ7CYj}G#J)X(3I&{Tsib5`NkXAl+274vn<0bJ4xuzR zeSxqTYDfS}vv{qSVL`v`ng%u-%pSeQcp?b@r06~vQgHSz!iy8{@O5CiE!P23>AP;w ze&_BNbLivUXA@ShzIk*}^I$gUXfZ2ieM$sh0kHr{%E|Xd#p~`os|`Ke`4Wk8dloYU za7K|sK)`szSlfE#pi97rTIyW`g$U$NVTYNXk~{Ke?q}v}!F~QpZ4^zSOk3C<BfJ_s zd(}IWK7Oa|qWrH9XV!eaX#lo{cUU;g&??H2I@T?PyOMeeOC)hS@A2I+4zfbK??(1z zgwae>U5icWtjE>H-SWr}+Pl8iAX(F3S>a|lEEmF=Kme$1LW^l*pY$1*E?KaS^dw7# z`O}e27pW2L04QH#S^N$cINWW43t`==&<6E(cEmm4k}`2Ku%;L+4vxIrVV2OW&m{(u z0@|*?7=;!`_gdJB_zZwfJTkjyzW8|jnBJ-4oz52bT8EYD9Ax@qv^@=_uD<$yAiqC` zGf_yS3dT1#Kg$827@>Wel>w1ErQ*7#zk=}*_d(oV|HPPN+k9+M?1py~s2mEDd8*LY z$!XGgJ=jY*TkP24)iT=b4Lgayg6;EXlmF-;c?$!mrahS?V(E@}0TqaOr!vY<5xOi- z5;v7a8hijlc?ocnSV<6<<U5S$-jn46s-Qt^x>pFX9b>DjV>o9`hNz!;&*+oA!NuP^ z&y9R9diJc9^U;aZNSCyl<dpn=J9fC0E*0P1QEm&ny17}?1|U&7o4?eo1z$@HcM1zc zcE4NS+$8+%ER2#Z!b^K=g%f54ep#*Hl9GOkd7oB^TYpND!mqM;;-#*cSc4rL7DP=n z2KX|K#)xAiUH6C_P82KKgXl9MEee-nDlN#pdpoxY%>hC^2OO2Rf<A4vL26q;9~lJR zA?h9gF4NR`vWo<etcBy@a=5d+<erw(QohbZNnpKludXZP@jW&dPTa7E%6~5JYrgCd z@US@e<>Y}XC))FC)qU7!gusnE-*unY6?lx(M+IE17Z&$rTP18IcvxO0IQ?7u=H}3Y zrybow)pQ$7|7&DhlYHe#?lmofqj)G{QI_B}Yx_q4J56)tD_hid3Ip_YPILFPLE|Cu zP?rp=0#!)BL90+PhIz*lOh-I3B%>)4)iDzzG^9N3b@QZB>?Cttm6W_x*tD1#{>1Uv zCB1Pn?0i78{x#=fqv}hotxn6#?Ax`=&2STX@p*&a$+zpOp0|t>IatK!;l`c@{wRN% ziuDEdaKUig+DM;tuaN*+Dvk0ENnANDP~pTT$pbQKiWq_uqs*~YuDDxy;nSC9v(p#y zre8hs+wnl{@u$3&iSnR6<;lJV{nj^jOu8y8mh@stWAO+B^Z`JT6Y}Fp)%Xj522jf1 zk-DFM6eJp}PVEC~G1DE{*>NIiP3_OIe;aKRA|pE+<eu(41pqGP-}xV>fvuPV?c{P2 z*-5<C{sCV5%<ZhMTN^iEZ+7EeFDsu4Z>a8(awUBkwh8oYU89w=QAAbPA7mqoKe=!Y zU@awd6Mh7ipZ~P?$Pkv=)gpjsSyAYRlfLJeSA)_e+`Nsmq^-DoG2QFQbvNd6Q1^|v z6|0psV=b1Kd0rSzihu6wuRDVNqW^W|i9*Jvq&|=UK=C+FRNP2l;7PjgR3|ibHyt2^ zt5bUVuGShCvoO=2<BiQFDcW${SY2CP-EVWeX!BQ*eG0TRJ?s7nS(O+c+bH|Dyw=8z z;m=d6HJhvGXMm#sU=R_rfiv%zBo!kSGu*oOH3w)iOafd|+~mA4LofmQlEnF$^}Z#q zx_4fS-Z*wUAR;zUFCD!fg;Y^9GCbS(=@7eUxnQSI;oIL$LW+P8gmgvoin1>Sj9!!C zOPE@OPg6@-D?0txh4vnmQez+!GndRodfgwllfR$2Ve`W^!Ob?iZALu==tL9N7Vmvp zI4ysrC}hPwZSy@~2!O8cz@x$mlDXT2Tv9vFDLGz>_F^35*BPIp(?qE3y}`bVAUmYi z<DvHH(Q0vYab#@nJ9Qb5D+C>ZgTbBWf8bS6_e3XRLuv~uANZo!c$+fW$SS5{THG%& zE=}}i^>mcsCC|J@>2?z9h_0xK0#}p^`1cM`l#sE$#6W&*^%WHj^CTgX3%C0+9TX$| zZSN43Vi@y9MKQ>C*~p!Op*sfHT+wk6R%2hZW}#y~1hy$3sD8e1JkAJ(k)y>twyoOw zBR~xrW!)>5*ef9v4@cU{AbdzVF>H*=Y}eefEJK}90p#+NJiG``5xZZ~0xNP7pMj%_ z`sbqW?vli$7?R5I4pl><ZMWXEJS->DL@?ea+^roxCIYT92kZ70j_HEJ)I?&NvC<v5 zRMaYabt6R^t?kIAk-Ho4@<GtcA2o=h{oO%4%c1$z2Zt{urrH!>9WmFO-U&^)|K)Ma zQ9(lpi7)Q<E{mG;*4$9V+*E}-$j`$-C=AEapu0}-fl7BO%GnR6-8K;eqafR5VN6(l zmui1F;pXX!F0dOKgW}tSLes{|<eyx+8zo?>nXjKQG7|~#HZu%dMA#$!g&teZ9CWJC zp9igl6<2<iaQzY3UoDB|uUOy2EFF!U=zjo@*Qdrv#Ycg-6qurfXozlt5j8{&Dm|Gh zVrYuxWkHODczK|zroQGQ$oeB!pOLTkhj!&Wtr;{2&Xv5Y-DCai;mgp#SW4+n)JK#E z&%BwLl+ONkt&E&>O)_Sh&7Ho>$M(Uq{21+JoH?uI%i8b@#0=vn`{P>_`PJ}S2*$og z<`=ClEBfbZtTFT9If4geVb?}-_tAck`TC-eoCGeHiFlk{Ne`2Fyhj9SZ<Z<tK?(~E z$-_vL6hhpBXo7+qeVJsvS{ZdE+R~(SUI}MYNaOuB-&&I|%~_TiWmh&)t_Xb;y}UQJ z?E9gYNO_i<Vu>XZwKWSrN=;Gky0xzQXcR>iksG11;1GQxR3sBj)&9}x<EJ<?=EQE< zuy^peMay&bUD3PuQ&Z|MJ;#d<HA$dQd31`?TEkfU%e;Il@zSp1o(<Oa1ZnBxuBmjj zNOo^x42khD#(JAj^49y1{Nt3nQJpRo<~O$p(Za)s;#==S4(WcpsRud$NuFJbWpdHv z{cohyaEs#EIbzq!gTge5nRT~}ct>8$;I2k_q<oK{P(?HQay<(2f^$uu);E(YC)=MJ zRiTjD0AaDRb0eoS7ReP6-vJ@{!9a;|1cX9bgZ6SZIf<Ol9us*^SsP0gHIVh%D|n9} zd_T;+4{3Mx`lwn_W+j;YD_jQeI^XkSJg@#&8}>~J30DdXUda(1J1Bx80NQ3J#6X1@ zn5uN2dXQ;LMYSDF1LmGU)pM5`q~Y{i+!KF5>eUCAL%|=!SKU)ulGEcvAt?_=m_433 za(_9v-ug1lj}8+R9X>RIPhrlg@B?8~`T={U52=iuq)o&@)w^^7VFC)4k%6SRwCQ3{ zGT@YlpDU&JxeSKo?@o^VJIJt$do!c#z%Kb6^3O&ko|}C_n^3Ce7<O@Si+W3#p1KfJ zM+;wFQ=__$fMqmw=PF>pXm%a|DS|`xKZ;k?osvPqMR+!EqsK&c)-Bu}RO+!jds~hz zaC@{(=xW;7l^ymeMIF7)U4b{l%*+NV!wBMm%XZ9kKl0-}IwMt=QqxlZTuOMacm|<R z?zCE?fkILN?zCM7lYQB%ECImttR|z#Ty(?@)p3=WXiy!YL%2?pTnf>oBNW0CLGD8k z&BN~xye>50G&-oHQZ_2oI}_gq+jcrQ-adf%ytCC+y}<Ox|464eV!2sr(Qcv-euaTH zNNo^8N<)x(Fm9Ke4>!Vyeicp}ZTG?MN_5L`=*+k`+ka^7(n|Qe;j5s{uEDH7uJCqZ z_RLQmnEq4#$h`nvm)-rold%DUvBX(|&xg^>M;#<;E1^Xi$3Wuh6(GnX*`TKn2<Ncl zwyT-kH!5Cxc8lzNpQ3SW;8e$W=KYh`Hzf>he@8>lvHs2pG2++wo?b4kW&Wj6;3rvy z>$_(Bv&C##3~vcCluuN_#{z8}lpF}WP3U&oSdHRP%H6HF9Hc1g%vM}3@|2<YqA=p1 z*h0tD^bC(M8d}`Pb()tyUINCjj5M=r4tuG%xxUd`K{hK_htLd%7UtFe5Di@b=h>NP zz06A6uU_|H4Eh&P_+O6u|IjA^h%=io-*xzaf-=$&1X#=S1)?G6X@b#!SR0n{39TVs zJxHX}B;w~EvLD3DjCMaWOyB)PemCR3h3u$mP#aD(<fYfn)xtq21)OYqNS4+U+J0ig z2P6{G6dK%?Pqf4w1_SZN!d%(e?|HoPQFyYzZ{lDP#0@MH8}$C$1%nACtD|S?jwqhF zLO5M^I^3X~@{GfhoongdH;2!MCkjcYHtOdkFGNl*<JzL}ZypfNgN-Q$qL6qgXeqZ| zfKtaPh=2ygU1wZ{+2MuprYL0gv+*2*U61+HX)UGSkvooR%OvQ!>V<=0bYb(pZ9;<? zYo&?@_*;aSkR;AFp^`JY;#)g-&gl!}sXaOoa$%Q?UM)QtOS(^Je)OgjX{elf<_7&L zDRorTN-z`Kp^eqUK@mt;3^%kZug!%waYR!kEf%7FJA8i7ew{UDhIn-G3hYI)5PKjm z`8B}H0S$*L*-S0^o&IjTQ64;0fAjAqzFKS;GpvjG*4kKLE&E7HH8uy?Rjw-C*<`R! zjD}PjBjH$aPE+p9H8E)Uk<y&{Qa7Hu0-&=HygznJuZH5fqv4nMH1-}=vSv}w)x(); zF$2z+BwT0yE-f(l?0P_GM@zjACp{=VGU(EhUnJaXV%CR|%`Ob5SQWYoU7M*T$3|0O zNK~C?im40A%GyF29g!=FQs<L|EF1b(xSuIK9X%d~Ih;VcR=p%;-0ar-Y$(T_<}Im- zaq69)CLO$RQryinFVA@T#8+4j`ZC=Lj}F056+B1b+Hiz!9CC*5hF5X$DlOH7@p1h@ z)|&fDHB*@>efM;vPR8LXzq(a@o~5foOCyjj=6&ihQz0euL@IQf&`ic!o#FtbZ9BGI zL^>luqo+n-#TOBFS?QIasTrN0V@{&AUWXc`t1s2#I|psgiCqQ8yqs$jZB-rA5Re1W zDncNT2BWM5cO0g!GsKjJ3P$|o4X8ekHlU-)Sy6H}swbPOrLT%gKWw*)CFP2jC0{d# zW_qR@m&7LlSBq)n2z}b;&fM{ccr*8aaci~be~6uYYeJSD0O1}Hn7Ohx)?@*<PeH`T zddy({x;WSRr64U}MA(a~ee2A_q{ouEyNF#<UK620BQU|^onWT4_6n81aS#op*7Uor zDq;1|*>8@)>db8<n@#Y<k-pD2x;)Q3X4nw8bo@}BhENt`go7o(Vv0~3DN(vzrKm4W zY92(;M5&1W>%YpwD86EkaorQGio9@8lkt8*o{)$o8v9GCo2#ZvaJAe|73r?LQ_xYD z?npV2Mt3o183);!CO}-l_}N?gVCzak3J`k5dCn=J`>tb6u_?w0#+?REorRtHx>JXm zbP^2`Zd=ZsG_#Dw7;H_?c=%%XMnr*1TL6^tLTUCtqCW33*4CB!_(jo9N4@W&!i;Ei z_*ty@*8UJr!Ur_8M@J*cHE-M)od!Sj$<ni=N&dF_C2QVw5N6f=DnBYcCJj{W_^@qP z%<JocZdNu$T}3mpwQM?DRwh_)Lb_YF>*bY@))Hkaq%0rk#>9rrMq3PKP7%S{$J19e zrL()Q)0T^pY-9EQRyG*!!@wJlui9$X`>M~7rEFx0S!#eJF0=e~@qRuWLQ~$+$QrN@ z`6EyzE+#wTivf>l)%CbCCa<Aohk}pewZ43z53WMhLwR+C_Ls+F-)Y@z)oIxM<wFPF z9on_2+xuM02MIl7^0h+Bm5|LTO)5`Opk{I5g;dAj$7&t1pehNm7dT(dwzn;rogH=- zKV${PD(rV-WZLtWVrc~J@%aPbFM8l{KiV_-qbE%|!=zq&N<Y8+<20+VK8C%S=Y3pe zN1s`X8p&Kt+}O0V96=^yCsxcdb@BrfMk{I?sjJ`|Bbc=P)`~loiHZ^+mcqT#emrkj znz$ZIjdHU<9Iotk?VdYf@aAQqX6PYo^DbhX=0?M|hPDXJ?4)k(;4u!XEdyISct~iJ zve=e}xEX34?K3)sVA^PP&>xNi$4}d&%`19HmMX?4$X{YOLQ6|CPedwGr3Z;!OQTO; zs7Lbb3iu+L6IoDOUAW~mbi)E~`|G{y#tD~Bb<27sXrq&to>xe#>|ZD8Qs#P@?mLRD za-v;_KpFw#CdX<POzx`=m%6<uNKQ%6ZD!l_0t))F-Z89F6qch4sA&Ft7b?(}>~5VM zgdj-@t+#Dbk4jUVrb7}xxrsS2PFi&5{<`(<Gg3<Iyw#xtW?WSXrxML`$T|u1<p-^k z^dYIs$$I-4`o{-*Y`XH?apiM>n5-zi1IK`)%wzym&V?{@mNb0UGsKq{j}`OuDDO2A zQPts?b)V6PUDGzb>_xjUxgH&lh<{k7S5-oi6s~oU+6!|LPI7qj>O{34Vz@`9YWIxV zu4q$FHD_C8N0VC}EL77ypg$o8e?v8^cqUg=W+z3g&svkw)h#2Uz)(^+q*EK6vqy$u zf|CYa*Zh7hg6Z|j|HM#t02ZjdWT{(wqsFsoo6xevI!O5uB&ySir8Y5r%8Yhk{vSf* zbN>+1e!@<;mGSDmNwg8@l#A^Dz)k$`16V-$jfYGbY8tzRh0`U?yj4F+_fnk`=TwyA z<jJ_}^TVoNn@JrcuC`<dTJya0pi``U_pJ<f6l7jNt*}zC;vON!hYZ;Dm#OUPXa{ot zwjRp*(=cI&G3Y}D$HcjmYOxUJ3nn->aUy4=;t7VMbe}l0bb{oPW3H6QL;9>yiaJsn z4(7>8s``)8Z);Pg4w!w;0`}6O$wZY(ZJ}|hzhY%cF<R=}4gum|xMja``BKO&obtdf zh>L}~H6q$9-WV*4k8pYn7q*%yN8@J8PV)?tis6j#9QY%#-AZL@nVHnWKWR)DeqVMO z+{5CNb5()S;k9_WhdQjurE)5Zt{veazQf#gq4D;S>TN<x8SC(!`}tdh*pQ`_Z9+|F zu-hj|PK(cjwoa0)o+TMnnoDK&T>mq<D6E`<E2v2H#;JJAx#*8@!wnTw)Wmh=0?<oE zrE$V`xKz&g&6j9%1T-nVvWny_^-UKQSJAj&;U4<=iMCHqIqA5Nhkd_vXM#)V%&oj& zkM}MwPsz1_Us`9GBRwA0)E1Zt)Q;(zh*<AFL<o)fByU%gl36IgVgVgcDyLXC0D)7) zm|69svOS^N1U`kJCLQtGXGJ<nO@{FXP3Z`hFQ@Guh*?stAT_A4YxnQ$Z5mJ!ZjRzq zA2(l@GxDkr;o3fA21&=CZuD6Ynj+*F%c<bGBog2R!OReuBWRWxjuV%yqTUK;_`(u> zY_;Ft>z~$Mv(+tYS5JzWGN$C7$rBo}vE_MKbvdQ)OJnC+N%*YI(4U9BGd$Ykz8map zXJnG^T;Zt>72y^+7ALE##3f>$Af`g3#ewJ*kkx((GoQrxxFV7&5+R#BD^Rl-4-B4t zgvN$l2Q`tVHK8mdq$skV&23Yj2lDm)r6J_M2=V`e(A3#~2%XLF*(Nm7jP`T5<cPzi zmVQ9ktG7RQcSt*tiP8o8+6HN7Zk<Z=w$uvgW|)EA3xp7gmNVI^3bMXHB2L{yF9k?_ zZ(nskMUl!Iu7`C%xP_8joVf3tMm%`>Y$n+4hE<<kk;O@hpp(F#b~cGzzglIQ+hvD9 z<rI!YrR)$wLXTI+0~n}Xy5D7BNQN9V*lxH^cLGZNa2Pjl(#p8f8T=aR+S#Lr$X<G3 zF+9o4`dBHg3c~}}5XKWuo2*lMR1zW2;t6q&O8z1{^qQbLXmxQP?W9h8Hd;jsU%D=9 zDuRK(utx$oc#h&@3s9kM%(H^XBku|;L8KuTuBn$dQ*H6ddtSxiOM7EXx9g%1SWU$p zu6fY*aDfBbzp3iC;Eii0*H<^<N<g%=!Eon-3sRg5{3#<bg~Xt(4B6QJY@(qL;48!} z6`-cs^0}aFZcJ=Wnv6WDY@F^{_41WJ<#e&4?b54j(3I;g#_rbN$BsS|I_Y`;HLY!` z;GOUGfyTv*wKqyz8j5!E?5bJWnuqA;q7=pE5Ox_EYP@!~juS3o8QE|4#j4V5E-hno z6Oee@iUG|6kXJhuaTWlihPjV}W7)y)#_~0(BX=`Fxw2qBV9ks5W58%&5wru5=?hM< z#|IZ2KY3a5WkAS|ir^BoVFUBAuf%)1vrL)W!GA^Q&V?Q;%A<C?s5Dlen-s~MOE=xO z`4iZ8VS*)`2uPeb7Z!J3ZFI6PX!mcw<R<oV$ybYG?@}(=%BDA;-8XHCgz0GMzkrxl z0G$g0<Nm(B;$74JPq`Rv2bcn!my}p@Xaz@|KsE+LtZRUdm=Qdu;Q+zzH%wE8OEp8P zq9E`%z)b`OhnD~G6Nwatt#55n04x-6qI80|BVltD9@7^y6Z;ZVN$7h7YeW}p{<g3I z8>^cg?#7gxS2?Q;Z*Kl<ZC>W9yW1s(YNy*pzS=ssxu!@j*sor!+BvLAt+{1a4pqT} z6h{$M)FPa2uDXD#Sr9EGvHN9e&S{B!-(PVn^XZwNk7Zb0<K`>je>|2mO*K&R`DdX3 zKwNiH(@p`fpsr=fhH2o{<&mHAFS(Ggdpr5N8Nio|f=CR~$-%u5cG4CUH^}wR$;u+0 z5<IB|aEuZpQ4%60$+$7i%4(87JOxW&fcQeCUNau~J~=;;bUh%GgP~wyk|IEpG!lid zx%d@>5f^(00l0tw3rv!m0(MDk&Pobp33VY_@KoQdbg{!4Mw>swlc9c8&fP>jC5%>W zeR*^9+ezPX7_~VEHSegHy?STM0rO@>hUs=ho468smZM(|1#aa9HZMnKstltFLv03B z90%lZ+^%dr##a|Q+1|$3(A?PNznlKA8~%3(`mcV!P3VZk3IGHO|8wwI3_HDTL6!ep S0YvVW{jb{o`}_YN9{690y_~uL literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/4.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2b3b2c3e4e0b43101ce04ee14f7d768a8ebbab4b GIT binary patch literal 13259 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 C^wvrM literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/5.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2243fbee8f0a76ea4d5f0279d709f1b6f2a6b87a GIT binary patch literal 13259 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%0Ac{3ATg#_ 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/6.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/6.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..dc640b242f8e148c54f958ff98a1a38443a8d0f5 GIT binary patch literal 13259 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/7.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3e423af6cb7da9a5cfe4604bb24ca67f532d8ffc GIT binary patch literal 13259 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 Rs2oZA-<bH%@V|8j{s+S5-2eap literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/8.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/8.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..59f4bcc617bbba6a8cbd76f8fa0f3bc24659fd7f GIT binary patch literal 13259 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/basic/9.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/basic/9.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..a1b5d0b46a2b5b4dc147a5c962388fabdac7e315 GIT binary patch literal 13259 zcmeI2XH*kg+xOE6kVa1+K!8vM3{{$#Kq#RZsuaP{J5r_CLJvJ4NI+DYbQKYgf-O|( zQdK;tG!axhfaQRV7tZrMYrXID`M%#z_g-ty-m~_aYp%I|^WWFZ?4eP$z<|914{@S7 zY3_A^d)0|<rtv>rijB$tbRA5s_qw3HN^){DbJ%O4dsUO9q2*+H)NZf4f2`?ITigF0 z@s9`u?2YX2?vEUEb#>iq_KycRnc11{HDY_!Jlfx%U>m7LI2P_rFg+P@%0D{RKYH&t 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 Mq5quhe?{Q`06lgV=Kufz literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/0.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/0.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..051d494c6adf013224260cd9120642993685d5fb GIT binary patch literal 10008 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 AMgRZ+ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/1.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/1.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..2a89aa50e96bdc04126f87a37594ac87be51accc GIT binary patch literal 8340 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 W=4@%HLo_`Z+oXn~{6t>=Joq2ZyS38* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/2.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/2.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..325bd2c1d4c85152cdb8065a78e0b8cb869a216c GIT binary patch literal 8340 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 J&11DB{U0)r#8v<R literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/3.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/3.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..bfd4df7f8fd6f80b30c07d1bcd9e4294308d6965 GIT binary patch literal 9174 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/4.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/4.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..1ef3cd5a1ef3629b0bdc57a1807420572ddb83b9 GIT binary patch literal 10425 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 T<ZUAvN~k}-Znv#c&iVfX%RhBJ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/5.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/5.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3e50114ee896f279714926c4d2d712117d8a0f4c GIT binary patch literal 10008 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/6.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/6.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..ca45dfe468458c3172ce8de695cb92ba9739fbdb GIT binary patch literal 10842 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/7.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/7.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..8968e8352ed808993d6fb71670b656476cc3428f GIT binary patch literal 10008 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 A0RR91 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/8.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/8.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..f2ae153e92226922d42eaeed575e0db54c6ec81c GIT binary patch literal 10842 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 NdGDe;Zd57ce*gw;da3{b literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/9.mp3 b/AvocadoEdition/plugin/kcaptcha/mp3/jmoon/9.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..d534cecb36540b7db4e210318f22219664aae721 GIT binary patch literal 10425 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/_common.php b/AvocadoEdition/plugin/sns/_common.php new file mode 100644 index 0000000..bad54a5 --- /dev/null +++ b/AvocadoEdition/plugin/sns/_common.php @@ -0,0 +1,3 @@ +<?php +include_once('../../common.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/sns/facebook/_common.php b/AvocadoEdition/plugin/sns/facebook/_common.php new file mode 100644 index 0000000..0319f1f --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/_common.php @@ -0,0 +1,3 @@ +<?php +include_once("../../../common.php"); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/sns/facebook/callback.php b/AvocadoEdition/plugin/sns/facebook/callback.php new file mode 100644 index 0000000..e37db9a --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/callback.php @@ -0,0 +1,62 @@ +<?php +include_once("./_common.php"); +include_once(G5_SNS_PATH."/facebook/src/facebook.php"); + +$facebook = new Facebook(array( + 'appId' => $config['cf_facebook_appid'], + 'secret' => $config['cf_facebook_secret'] +)); + +$user = $facebook->getUser(); + +if ($user) { + try { + $user_profile = $facebook->api('/me'); + } catch (FacebookApiException $e) { + error_log($e); + $user = NULL; + } +} + +$g5['title'] = '페이스북 콜백'; +include_once(G5_PATH.'/head.sub.php'); + +if ($user) { + $sns_name = $user_profile['name']; + $sns_user = $user; + + set_cookie('ck_sns_name', $sns_name, 86400); + set_session('ss_facebook_user', $user); + + $g5_sns_url = G5_SNS_URL; + + echo <<<EOT + <script> + $(function() { + document.write("<strong>페이스북 승인이 되었습니다.</strong>"); + + var opener = window.opener; + opener.$("#wr_name").val("{$sns_name}"); + opener.$("#facebook_icon").attr("src", "{$g5_sns_url}/icon/facebook.png"); + opener.$("#facebook_checked").attr("disabled", false); + opener.$("#facebook_checked").attr("checked", true); + window.close(); + }); + </script> +EOT; + +} else { + + echo <<<EOT + <script> + $(function() { + alert("페이스북 승인이 되지 않았습니다."); + window.close(); + }); + </script> +EOT; + +} + +include_once(G5_PATH.'/tail.sub.php'); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/sns/facebook/changelog.md b/AvocadoEdition/plugin/sns/facebook/changelog.md new file mode 100644 index 0000000..16728fe --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/changelog.md @@ -0,0 +1,28 @@ +Facebook PHP SDK (v.3.0.0) +========================== + +The new PHP SDK (v3.0.0) is a major upgrade to the older one (v2.2.x): + +- Uses OAuth authentication flows instead of our legacy authentication flow +- Consists of two classes. The first (class BaseFacebook) maintains the core of the upgrade, and the second one (class Facebook) is a small subclass that uses PHP sessions to store the user id and access token. + +If you’re currently using the PHP SDK (v2.2.x) for authentication, you will recall that the login code looked like this: + + $facebook = new Facebook(…); + $session = $facebook->getSession(); + if ($session) { + // proceed knowing you have a valid user session + } else { + // proceed knowing you require user login and/or authentication + } + +The login code is now: + + $facebook = new Facebook(…); + $user = $facebook->getUser(); + if ($user) { + // proceed knowing you have a logged in user who's authenticated + } else { + // proceed knowing you require user login and/or authentication + } + diff --git a/AvocadoEdition/plugin/sns/facebook/composer.json b/AvocadoEdition/plugin/sns/facebook/composer.json new file mode 100644 index 0000000..6ec7c91 --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/composer.json @@ -0,0 +1,22 @@ +{ + "name": "facebook/php-sdk", + "description": "Facebook PHP SDK", + "keywords": ["facebook", "sdk"], + "type": "library", + "homepage": "https://github.com/facebook/facebook-php-sdk", + "license": "Apache2", + "authors": [ + { + "name": "Facebook", + "homepage": "https://github.com/facebook/facebook-php-sdk/contributors" + } + ], + "require": { + "php": ">=5.2.0", + "ext-curl": "*", + "ext-json": "*" + }, + "autoload": { + "classmap": ["src"] + } +} diff --git a/AvocadoEdition/plugin/sns/facebook/readme.md b/AvocadoEdition/plugin/sns/facebook/readme.md new file mode 100644 index 0000000..ebbe667 --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/readme.md @@ -0,0 +1,85 @@ +Facebook PHP SDK (v.3.2.2) + +The [Facebook Platform](http://developers.facebook.com/) is +a set of APIs that make your app more social. + +This repository contains the open source PHP SDK that allows you to +access Facebook Platform from your PHP app. Except as otherwise noted, +the Facebook PHP SDK is licensed under the Apache Licence, Version 2.0 +(http://www.apache.org/licenses/LICENSE-2.0.html). + + +Usage +----- + +The [examples][examples] are a good place to start. The minimal you'll need to +have is: + + require 'facebook-php-sdk/src/facebook.php'; + + $facebook = new Facebook(array( + 'appId' => 'YOUR_APP_ID', + 'secret' => 'YOUR_APP_SECRET', + )); + + // Get User ID + $user = $facebook->getUser(); + +To make [API][API] calls: + + if ($user) { + try { + // Proceed knowing you have a logged in user who's authenticated. + $user_profile = $facebook->api('/me'); + } catch (FacebookApiException $e) { + error_log($e); + $user = null; + } + } + +Login or logout url will be needed depending on current user state. + + if ($user) { + $logoutUrl = $facebook->getLogoutUrl(); + } else { + $loginUrl = $facebook->getLoginUrl(); + } + +[examples]: http://github.com/facebook/facebook-php-sdk/blob/master/examples/example.php +[API]: http://developers.facebook.com/docs/api + + +Tests +----- + +In order to keep us nimble and allow us to bring you new functionality, without +compromising on stability, we have ensured full test coverage of the SDK. +We are including this in the open source repository to assure you of our +commitment to quality, but also with the hopes that you will contribute back to +help keep it stable. The easiest way to do so is to file bugs and include a +test case. + +The tests can be executed by using this command from the base directory: + + phpunit --stderr --bootstrap tests/bootstrap.php tests/tests.php + + +Contributing +=========== +For us to accept contributions you will have to first have signed the +[Contributor License Agreement](https://developers.facebook.com/opensource/cla). + +When commiting, keep all lines to less than 80 characters, and try to +follow the existing style. + +Before creating a pull request, squash your commits into a single commit. + +Add the comments where needed, and provide ample explanation in the +commit message. + + +Report Issues/Bugs +=============== +[Bugs](https://developers.facebook.com/bugs) + +[Questions](http://facebook.stackoverflow.com) diff --git a/AvocadoEdition/plugin/sns/facebook/src/base_facebook.php b/AvocadoEdition/plugin/sns/facebook/src/base_facebook.php new file mode 100644 index 0000000..2ea0fb4 --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/src/base_facebook.php @@ -0,0 +1,1441 @@ +<?php +/** + * Copyright 2011 Facebook, 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. + */ + +if (!function_exists('curl_init')) { + throw new Exception('Facebook needs the CURL PHP extension.'); +} +if (!function_exists('json_decode')) { + throw new Exception('Facebook needs the JSON PHP extension.'); +} + +/** + * Thrown when an API call returns an exception. + * + * @author Naitik Shah <naitik@facebook.com> + */ +class FacebookApiException extends Exception +{ + /** + * The result from the API server that represents the exception information. + */ + protected $result; + + /** + * Make a new API Exception with the given result. + * + * @param array $result The result from the API server + */ + public function __construct($result) { + $this->result = $result; + + $code = isset($result['error_code']) ? $result['error_code'] : 0; + + if (isset($result['error_description'])) { + // OAuth 2.0 Draft 10 style + $msg = $result['error_description']; + } else if (isset($result['error']) && is_array($result['error'])) { + // OAuth 2.0 Draft 00 style + $msg = $result['error']['message']; + } else if (isset($result['error_msg'])) { + // Rest server style + $msg = $result['error_msg']; + } else { + $msg = 'Unknown Error. Check getResult()'; + } + + parent::__construct($msg, $code); + } + + /** + * Return the associated result object returned by the API server. + * + * @return array The result from the API server + */ + public function getResult() { + return $this->result; + } + + /** + * Returns the associated type for the error. This will default to + * 'Exception' when a type is not available. + * + * @return string + */ + public function getType() { + if (isset($this->result['error'])) { + $error = $this->result['error']; + if (is_string($error)) { + // OAuth 2.0 Draft 10 style + return $error; + } else if (is_array($error)) { + // OAuth 2.0 Draft 00 style + if (isset($error['type'])) { + return $error['type']; + } + } + } + + return 'Exception'; + } + + /** + * To make debugging easier. + * + * @return string The string representation of the error + */ + public function __toString() { + $str = $this->getType() . ': '; + if ($this->code != 0) { + $str .= $this->code . ': '; + } + return $str . $this->message; + } +} + +/** + * Provides access to the Facebook Platform. This class provides + * a majority of the functionality needed, but the class is abstract + * because it is designed to be sub-classed. The subclass must + * implement the four abstract methods listed at the bottom of + * the file. + * + * @author Naitik Shah <naitik@facebook.com> + */ +abstract class BaseFacebook +{ + /** + * Version. + */ + const VERSION = '3.2.2'; + + /** + * Signed Request Algorithm. + */ + const SIGNED_REQUEST_ALGORITHM = 'HMAC-SHA256'; + + /** + * Default options for curl. + */ + public static $CURL_OPTS = array( + CURLOPT_CONNECTTIMEOUT => 10, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_TIMEOUT => 60, + CURLOPT_USERAGENT => 'facebook-php-3.2', + ); + + /** + * List of query parameters that get automatically dropped when rebuilding + * the current URL. + */ + protected static $DROP_QUERY_PARAMS = array( + 'code', + 'state', + 'signed_request', + ); + + /** + * Maps aliases to Facebook domains. + */ + public static $DOMAIN_MAP = array( + 'api' => 'https://api.facebook.com/', + 'api_video' => 'https://api-video.facebook.com/', + 'api_read' => 'https://api-read.facebook.com/', + 'graph' => 'https://graph.facebook.com/', + 'graph_video' => 'https://graph-video.facebook.com/', + 'www' => 'https://www.facebook.com/', + ); + + /** + * The Application ID. + * + * @var string + */ + protected $appId; + + /** + * The Application App Secret. + * + * @var string + */ + protected $appSecret; + + /** + * The ID of the Facebook user, or 0 if the user is logged out. + * + * @var integer + */ + protected $user; + + /** + * The data from the signed_request token. + */ + protected $signedRequest; + + /** + * A CSRF state variable to assist in the defense against CSRF attacks. + */ + protected $state; + + /** + * The OAuth access token received in exchange for a valid authorization + * code. null means the access token has yet to be determined. + * + * @var string + */ + protected $accessToken = null; + + /** + * Indicates if the CURL based @ syntax for file uploads is enabled. + * + * @var boolean + */ + protected $fileUploadSupport = false; + + /** + * Indicates if we trust HTTP_X_FORWARDED_* headers. + * + * @var boolean + */ + protected $trustForwarded = false; + + /** + * Initialize a Facebook Application. + * + * The configuration: + * - appId: the application ID + * - secret: the application secret + * - fileUpload: (optional) boolean indicating if file uploads are enabled + * + * @param array $config The application configuration + */ + public function __construct($config) { + $this->setAppId($config['appId']); + $this->setAppSecret($config['secret']); + if (isset($config['fileUpload'])) { + $this->setFileUploadSupport($config['fileUpload']); + } + if (isset($config['trustForwarded']) && $config['trustForwarded']) { + $this->trustForwarded = true; + } + $state = $this->getPersistentData('state'); + if (!empty($state)) { + $this->state = $state; + } + } + + /** + * Set the Application ID. + * + * @param string $appId The Application ID + * @return BaseFacebook + */ + public function setAppId($appId) { + $this->appId = $appId; + return $this; + } + + /** + * Get the Application ID. + * + * @return string the Application ID + */ + public function getAppId() { + return $this->appId; + } + + /** + * Set the App Secret. + * + * @param string $apiSecret The App Secret + * @return BaseFacebook + * @deprecated + */ + public function setApiSecret($apiSecret) { + $this->setAppSecret($apiSecret); + return $this; + } + + /** + * Set the App Secret. + * + * @param string $appSecret The App Secret + * @return BaseFacebook + */ + public function setAppSecret($appSecret) { + $this->appSecret = $appSecret; + return $this; + } + + /** + * Get the App Secret. + * + * @return string the App Secret + * @deprecated + */ + public function getApiSecret() { + return $this->getAppSecret(); + } + + /** + * Get the App Secret. + * + * @return string the App Secret + */ + public function getAppSecret() { + return $this->appSecret; + } + + /** + * Set the file upload support status. + * + * @param boolean $fileUploadSupport The file upload support status. + * @return BaseFacebook + */ + public function setFileUploadSupport($fileUploadSupport) { + $this->fileUploadSupport = $fileUploadSupport; + return $this; + } + + /** + * Get the file upload support status. + * + * @return boolean true if and only if the server supports file upload. + */ + public function getFileUploadSupport() { + return $this->fileUploadSupport; + } + + /** + * DEPRECATED! Please use getFileUploadSupport instead. + * + * Get the file upload support status. + * + * @return boolean true if and only if the server supports file upload. + */ + public function useFileUploadSupport() { + return $this->getFileUploadSupport(); + } + + /** + * Sets the access token for api calls. Use this if you get + * your access token by other means and just want the SDK + * to use it. + * + * @param string $access_token an access token. + * @return BaseFacebook + */ + public function setAccessToken($access_token) { + $this->accessToken = $access_token; + return $this; + } + + /** + * Extend an access token, while removing the short-lived token that might + * have been generated via client-side flow. Thanks to http://bit.ly/b0Pt0H + * for the workaround. + */ + public function setExtendedAccessToken() { + try { + // need to circumvent json_decode by calling _oauthRequest + // directly, since response isn't JSON format. + $access_token_response = $this->_oauthRequest( + $this->getUrl('graph', '/oauth/access_token'), + $params = array( + 'client_id' => $this->getAppId(), + 'client_secret' => $this->getAppSecret(), + 'grant_type' => 'fb_exchange_token', + 'fb_exchange_token' => $this->getAccessToken(), + ) + ); + } + catch (FacebookApiException $e) { + // most likely that user very recently revoked authorization. + // In any event, we don't have an access token, so say so. + return false; + } + + if (empty($access_token_response)) { + return false; + } + + $response_params = array(); + parse_str($access_token_response, $response_params); + + if (!isset($response_params['access_token'])) { + return false; + } + + $this->destroySession(); + + $this->setPersistentData( + 'access_token', $response_params['access_token'] + ); + } + + /** + * Determines the access token that should be used for API calls. + * The first time this is called, $this->accessToken is set equal + * to either a valid user access token, or it's set to the application + * access token if a valid user access token wasn't available. Subsequent + * calls return whatever the first call returned. + * + * @return string The access token + */ + public function getAccessToken() { + if ($this->accessToken !== null) { + // we've done this already and cached it. Just return. + return $this->accessToken; + } + + // first establish access token to be the application + // access token, in case we navigate to the /oauth/access_token + // endpoint, where SOME access token is required. + $this->setAccessToken($this->getApplicationAccessToken()); + $user_access_token = $this->getUserAccessToken(); + if ($user_access_token) { + $this->setAccessToken($user_access_token); + } + + return $this->accessToken; + } + + /** + * Determines and returns the user access token, first using + * the signed request if present, and then falling back on + * the authorization code if present. The intent is to + * return a valid user access token, or false if one is determined + * to not be available. + * + * @return string A valid user access token, or false if one + * could not be determined. + */ + protected function getUserAccessToken() { + // first, consider a signed request if it's supplied. + // if there is a signed request, then it alone determines + // the access token. + $signed_request = $this->getSignedRequest(); + if ($signed_request) { + // apps.facebook.com hands the access_token in the signed_request + if (array_key_exists('oauth_token', $signed_request)) { + $access_token = $signed_request['oauth_token']; + $this->setPersistentData('access_token', $access_token); + return $access_token; + } + + // the JS SDK puts a code in with the redirect_uri of '' + if (array_key_exists('code', $signed_request)) { + $code = $signed_request['code']; + if ($code && $code == $this->getPersistentData('code')) { + // short-circuit if the code we have is the same as the one presented + return $this->getPersistentData('access_token'); + } + + $access_token = $this->getAccessTokenFromCode($code, ''); + if ($access_token) { + $this->setPersistentData('code', $code); + $this->setPersistentData('access_token', $access_token); + return $access_token; + } + } + + // signed request states there's no access token, so anything + // stored should be cleared. + $this->clearAllPersistentData(); + return false; // respect the signed request's data, even + // if there's an authorization code or something else + } + + $code = $this->getCode(); + if ($code && $code != $this->getPersistentData('code')) { + $access_token = $this->getAccessTokenFromCode($code); + if ($access_token) { + $this->setPersistentData('code', $code); + $this->setPersistentData('access_token', $access_token); + return $access_token; + } + + // code was bogus, so everything based on it should be invalidated. + $this->clearAllPersistentData(); + return false; + } + + // as a fallback, just return whatever is in the persistent + // store, knowing nothing explicit (signed request, authorization + // code, etc.) was present to shadow it (or we saw a code in $_REQUEST, + // but it's the same as what's in the persistent store) + return $this->getPersistentData('access_token'); + } + + /** + * Retrieve the signed request, either from a request parameter or, + * if not present, from a cookie. + * + * @return string the signed request, if available, or null otherwise. + */ + public function getSignedRequest() { + if (!$this->signedRequest) { + if (!empty($_REQUEST['signed_request'])) { + $this->signedRequest = $this->parseSignedRequest( + $_REQUEST['signed_request']); + } else if (!empty($_COOKIE[$this->getSignedRequestCookieName()])) { + $this->signedRequest = $this->parseSignedRequest( + $_COOKIE[$this->getSignedRequestCookieName()]); + } + } + return $this->signedRequest; + } + + /** + * Get the UID of the connected user, or 0 + * if the Facebook user is not connected. + * + * @return string the UID if available. + */ + public function getUser() { + if ($this->user !== null) { + // we've already determined this and cached the value. + return $this->user; + } + + return $this->user = $this->getUserFromAvailableData(); + } + + /** + * Determines the connected user by first examining any signed + * requests, then considering an authorization code, and then + * falling back to any persistent store storing the user. + * + * @return integer The id of the connected Facebook user, + * or 0 if no such user exists. + */ + protected function getUserFromAvailableData() { + // if a signed request is supplied, then it solely determines + // who the user is. + $signed_request = $this->getSignedRequest(); + if ($signed_request) { + if (array_key_exists('user_id', $signed_request)) { + $user = $signed_request['user_id']; + + if($user != $this->getPersistentData('user_id')){ + $this->clearAllPersistentData(); + } + + $this->setPersistentData('user_id', $signed_request['user_id']); + return $user; + } + + // if the signed request didn't present a user id, then invalidate + // all entries in any persistent store. + $this->clearAllPersistentData(); + return 0; + } + + $user = $this->getPersistentData('user_id', $default = 0); + $persisted_access_token = $this->getPersistentData('access_token'); + + // use access_token to fetch user id if we have a user access_token, or if + // the cached access token has changed. + $access_token = $this->getAccessToken(); + if ($access_token && + $access_token != $this->getApplicationAccessToken() && + !($user && $persisted_access_token == $access_token)) { + $user = $this->getUserFromAccessToken(); + if ($user) { + $this->setPersistentData('user_id', $user); + } else { + $this->clearAllPersistentData(); + } + } + + return $user; + } + + /** + * Get a Login URL for use with redirects. By default, full page redirect is + * assumed. If you are using the generated URL with a window.open() call in + * JavaScript, you can pass in display=popup as part of the $params. + * + * The parameters: + * - redirect_uri: the url to go to after a successful login + * - scope: comma separated list of requested extended perms + * + * @param array $params Provide custom parameters + * @return string The URL for the login flow + */ + public function getLoginUrl($params=array()) { + $this->establishCSRFTokenState(); + $currentUrl = $this->getCurrentUrl(); + + // if 'scope' is passed as an array, convert to comma separated list + $scopeParams = isset($params['scope']) ? $params['scope'] : null; + if ($scopeParams && is_array($scopeParams)) { + $params['scope'] = implode(',', $scopeParams); + } + + return $this->getUrl( + 'www', + 'dialog/oauth', + array_merge(array( + 'client_id' => $this->getAppId(), + 'redirect_uri' => $currentUrl, // possibly overwritten + 'state' => $this->state), + $params)); + } + + /** + * Get a Logout URL suitable for use with redirects. + * + * The parameters: + * - next: the url to go to after a successful logout + * + * @param array $params Provide custom parameters + * @return string The URL for the logout flow + */ + public function getLogoutUrl($params=array()) { + return $this->getUrl( + 'www', + 'logout.php', + array_merge(array( + 'next' => $this->getCurrentUrl(), + 'access_token' => $this->getUserAccessToken(), + ), $params) + ); + } + + /** + * Get a login status URL to fetch the status from Facebook. + * + * The parameters: + * - ok_session: the URL to go to if a session is found + * - no_session: the URL to go to if the user is not connected + * - no_user: the URL to go to if the user is not signed into facebook + * + * @param array $params Provide custom parameters + * @return string The URL for the logout flow + */ + public function getLoginStatusUrl($params=array()) { + return $this->getUrl( + 'www', + 'extern/login_status.php', + array_merge(array( + 'api_key' => $this->getAppId(), + 'no_session' => $this->getCurrentUrl(), + 'no_user' => $this->getCurrentUrl(), + 'ok_session' => $this->getCurrentUrl(), + 'session_version' => 3, + ), $params) + ); + } + + /** + * Make an API call. + * + * @return mixed The decoded response + */ + public function api(/* polymorphic */) { + $args = func_get_args(); + if (is_array($args[0])) { + return $this->_restserver($args[0]); + } else { + return call_user_func_array(array($this, '_graph'), $args); + } + } + + /** + * Constructs and returns the name of the cookie that + * potentially houses the signed request for the app user. + * The cookie is not set by the BaseFacebook class, but + * it may be set by the JavaScript SDK. + * + * @return string the name of the cookie that would house + * the signed request value. + */ + protected function getSignedRequestCookieName() { + return 'fbsr_'.$this->getAppId(); + } + + /** + * Constructs and returns the name of the coookie that potentially contain + * metadata. The cookie is not set by the BaseFacebook class, but it may be + * set by the JavaScript SDK. + * + * @return string the name of the cookie that would house metadata. + */ + protected function getMetadataCookieName() { + return 'fbm_'.$this->getAppId(); + } + + /** + * Get the authorization code from the query parameters, if it exists, + * and otherwise return false to signal no authorization code was + * discoverable. + * + * @return mixed The authorization code, or false if the authorization + * code could not be determined. + */ + protected function getCode() { + if (isset($_REQUEST['code'])) { + if ($this->state !== null && + isset($_REQUEST['state']) && + $this->state === $_REQUEST['state']) { + + // CSRF state has done its job, so clear it + $this->state = null; + $this->clearPersistentData('state'); + return $_REQUEST['code']; + } else { + self::errorLog('CSRF state token does not match one provided.'); + return false; + } + } + + return false; + } + + /** + * Retrieves the UID with the understanding that + * $this->accessToken has already been set and is + * seemingly legitimate. It relies on Facebook's Graph API + * to retrieve user information and then extract + * the user ID. + * + * @return integer Returns the UID of the Facebook user, or 0 + * if the Facebook user could not be determined. + */ + protected function getUserFromAccessToken() { + try { + $user_info = $this->api('/me'); + return $user_info['id']; + } catch (FacebookApiException $e) { + return 0; + } + } + + /** + * Returns the access token that should be used for logged out + * users when no authorization code is available. + * + * @return string The application access token, useful for gathering + * public information about users and applications. + */ + protected function getApplicationAccessToken() { + return $this->appId.'|'.$this->appSecret; + } + + /** + * Lays down a CSRF state token for this process. + * + * @return void + */ + protected function establishCSRFTokenState() { + if ($this->state === null) { + $this->state = md5(uniqid(mt_rand(), true)); + $this->setPersistentData('state', $this->state); + } + } + + /** + * Retrieves an access token for the given authorization code + * (previously generated from www.facebook.com on behalf of + * a specific user). The authorization code is sent to graph.facebook.com + * and a legitimate access token is generated provided the access token + * and the user for which it was generated all match, and the user is + * either logged in to Facebook or has granted an offline access permission. + * + * @param string $code An authorization code. + * @return mixed An access token exchanged for the authorization code, or + * false if an access token could not be generated. + */ + protected function getAccessTokenFromCode($code, $redirect_uri = null) { + if (empty($code)) { + return false; + } + + if ($redirect_uri === null) { + $redirect_uri = $this->getCurrentUrl(); + } + + try { + // need to circumvent json_decode by calling _oauthRequest + // directly, since response isn't JSON format. + $access_token_response = + $this->_oauthRequest( + $this->getUrl('graph', '/oauth/access_token'), + $params = array('client_id' => $this->getAppId(), + 'client_secret' => $this->getAppSecret(), + 'redirect_uri' => $redirect_uri, + 'code' => $code)); + } catch (FacebookApiException $e) { + // most likely that user very recently revoked authorization. + // In any event, we don't have an access token, so say so. + return false; + } + + if (empty($access_token_response)) { + return false; + } + + $response_params = array(); + parse_str($access_token_response, $response_params); + if (!isset($response_params['access_token'])) { + return false; + } + + return $response_params['access_token']; + } + + /** + * Invoke the old restserver.php endpoint. + * + * @param array $params Method call object + * + * @return mixed The decoded response object + * @throws FacebookApiException + */ + protected function _restserver($params) { + // generic application level parameters + $params['api_key'] = $this->getAppId(); + $params['format'] = 'json-strings'; + + $result = json_decode($this->_oauthRequest( + $this->getApiUrl($params['method']), + $params + ), true); + + // results are returned, errors are thrown + if (is_array($result) && isset($result['error_code'])) { + $this->throwAPIException($result); + // @codeCoverageIgnoreStart + } + // @codeCoverageIgnoreEnd + + $method = strtolower($params['method']); + if ($method === 'auth.expiresession' || + $method === 'auth.revokeauthorization') { + $this->destroySession(); + } + + return $result; + } + + /** + * Return true if this is video post. + * + * @param string $path The path + * @param string $method The http method (default 'GET') + * + * @return boolean true if this is video post + */ + protected function isVideoPost($path, $method = 'GET') { + if ($method == 'POST' && preg_match("/^(\/)(.+)(\/)(videos)$/", $path)) { + return true; + } + return false; + } + + /** + * Invoke the Graph API. + * + * @param string $path The path (required) + * @param string $method The http method (default 'GET') + * @param array $params The query/post data + * + * @return mixed The decoded response object + * @throws FacebookApiException + */ + protected function _graph($path, $method = 'GET', $params = array()) { + if (is_array($method) && empty($params)) { + $params = $method; + $method = 'GET'; + } + $params['method'] = $method; // method override as we always do a POST + + if ($this->isVideoPost($path, $method)) { + $domainKey = 'graph_video'; + } else { + $domainKey = 'graph'; + } + + $result = json_decode($this->_oauthRequest( + $this->getUrl($domainKey, $path), + $params + ), true); + + // results are returned, errors are thrown + if (is_array($result) && isset($result['error'])) { + $this->throwAPIException($result); + // @codeCoverageIgnoreStart + } + // @codeCoverageIgnoreEnd + + return $result; + } + + /** + * Make a OAuth Request. + * + * @param string $url The path (required) + * @param array $params The query/post data + * + * @return string The decoded response object + * @throws FacebookApiException + */ + protected function _oauthRequest($url, $params) { + if (!isset($params['access_token'])) { + $params['access_token'] = $this->getAccessToken(); + } + + // json_encode all params values that are not strings + foreach ($params as $key => $value) { + if (!is_string($value)) { + $params[$key] = json_encode($value); + } + } + + return $this->makeRequest($url, $params); + } + + /** + * Makes an HTTP request. This method can be overridden by subclasses if + * developers want to do fancier things or use something other than curl to + * make the request. + * + * @param string $url The URL to make the request to + * @param array $params The parameters to use for the POST body + * @param CurlHandler $ch Initialized curl handle + * + * @return string The response text + */ + protected function makeRequest($url, $params, $ch=null) { + if (!$ch) { + $ch = curl_init(); + } + + $opts = self::$CURL_OPTS; + if ($this->getFileUploadSupport()) { + $opts[CURLOPT_POSTFIELDS] = $params; + } else { + $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&'); + } + $opts[CURLOPT_URL] = $url; + + // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait + // for 2 seconds if the server does not support this header. + if (isset($opts[CURLOPT_HTTPHEADER])) { + $existing_headers = $opts[CURLOPT_HTTPHEADER]; + $existing_headers[] = 'Expect:'; + $opts[CURLOPT_HTTPHEADER] = $existing_headers; + } else { + $opts[CURLOPT_HTTPHEADER] = array('Expect:'); + } + + curl_setopt_array($ch, $opts); + $result = curl_exec($ch); + + if (curl_errno($ch) == 60) { // CURLE_SSL_CACERT + self::errorLog('Invalid or no certificate authority found, '. + 'using bundled information'); + curl_setopt($ch, CURLOPT_CAINFO, + dirname(__FILE__) . '/fb_ca_chain_bundle.crt'); + $result = curl_exec($ch); + } + + // With dual stacked DNS responses, it's possible for a server to + // have IPv6 enabled but not have IPv6 connectivity. If this is + // the case, curl will try IPv4 first and if that fails, then it will + // fall back to IPv6 and the error EHOSTUNREACH is returned by the + // operating system. + if ($result === false && empty($opts[CURLOPT_IPRESOLVE])) { + $matches = array(); + $regex = '/Failed to connect to ([^:].*): Network is unreachable/'; + if (preg_match($regex, curl_error($ch), $matches)) { + if (strlen(@inet_pton($matches[1])) === 16) { + self::errorLog('Invalid IPv6 configuration on server, '. + 'Please disable or get native IPv6 on your server.'); + self::$CURL_OPTS[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; + curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); + $result = curl_exec($ch); + } + } + } + + if ($result === false) { + $e = new FacebookApiException(array( + 'error_code' => curl_errno($ch), + 'error' => array( + 'message' => curl_error($ch), + 'type' => 'CurlException', + ), + )); + curl_close($ch); + throw $e; + } + curl_close($ch); + return $result; + } + + /** + * Parses a signed_request and validates the signature. + * + * @param string $signed_request A signed token + * @return array The payload inside it or null if the sig is wrong + */ + protected function parseSignedRequest($signed_request) { + list($encoded_sig, $payload) = explode('.', $signed_request, 2); + + // decode the data + $sig = self::base64UrlDecode($encoded_sig); + $data = json_decode(self::base64UrlDecode($payload), true); + + if (strtoupper($data['algorithm']) !== self::SIGNED_REQUEST_ALGORITHM) { + self::errorLog( + 'Unknown algorithm. Expected ' . self::SIGNED_REQUEST_ALGORITHM); + return null; + } + + // check sig + $expected_sig = hash_hmac('sha256', $payload, + $this->getAppSecret(), $raw = true); + if ($sig !== $expected_sig) { + self::errorLog('Bad Signed JSON signature!'); + return null; + } + + return $data; + } + + /** + * Makes a signed_request blob using the given data. + * + * @param array The data array. + * @return string The signed request. + */ + protected function makeSignedRequest($data) { + if (!is_array($data)) { + throw new InvalidArgumentException( + 'makeSignedRequest expects an array. Got: ' . print_r($data, true)); + } + $data['algorithm'] = self::SIGNED_REQUEST_ALGORITHM; + $data['issued_at'] = time(); + $json = json_encode($data); + $b64 = self::base64UrlEncode($json); + $raw_sig = hash_hmac('sha256', $b64, $this->getAppSecret(), $raw = true); + $sig = self::base64UrlEncode($raw_sig); + return $sig.'.'.$b64; + } + + /** + * Build the URL for api given parameters. + * + * @param $method String the method name. + * @return string The URL for the given parameters + */ + protected function getApiUrl($method) { + static $READ_ONLY_CALLS = + array('admin.getallocation' => 1, + 'admin.getappproperties' => 1, + 'admin.getbannedusers' => 1, + 'admin.getlivestreamvialink' => 1, + 'admin.getmetrics' => 1, + 'admin.getrestrictioninfo' => 1, + 'application.getpublicinfo' => 1, + 'auth.getapppublickey' => 1, + 'auth.getsession' => 1, + 'auth.getsignedpublicsessiondata' => 1, + 'comments.get' => 1, + 'connect.getunconnectedfriendscount' => 1, + 'dashboard.getactivity' => 1, + 'dashboard.getcount' => 1, + 'dashboard.getglobalnews' => 1, + 'dashboard.getnews' => 1, + 'dashboard.multigetcount' => 1, + 'dashboard.multigetnews' => 1, + 'data.getcookies' => 1, + 'events.get' => 1, + 'events.getmembers' => 1, + 'fbml.getcustomtags' => 1, + 'feed.getappfriendstories' => 1, + 'feed.getregisteredtemplatebundlebyid' => 1, + 'feed.getregisteredtemplatebundles' => 1, + 'fql.multiquery' => 1, + 'fql.query' => 1, + 'friends.arefriends' => 1, + 'friends.get' => 1, + 'friends.getappusers' => 1, + 'friends.getlists' => 1, + 'friends.getmutualfriends' => 1, + 'gifts.get' => 1, + 'groups.get' => 1, + 'groups.getmembers' => 1, + 'intl.gettranslations' => 1, + 'links.get' => 1, + 'notes.get' => 1, + 'notifications.get' => 1, + 'pages.getinfo' => 1, + 'pages.isadmin' => 1, + 'pages.isappadded' => 1, + 'pages.isfan' => 1, + 'permissions.checkavailableapiaccess' => 1, + 'permissions.checkgrantedapiaccess' => 1, + 'photos.get' => 1, + 'photos.getalbums' => 1, + 'photos.gettags' => 1, + 'profile.getinfo' => 1, + 'profile.getinfooptions' => 1, + 'stream.get' => 1, + 'stream.getcomments' => 1, + 'stream.getfilters' => 1, + 'users.getinfo' => 1, + 'users.getloggedinuser' => 1, + 'users.getstandardinfo' => 1, + 'users.hasapppermission' => 1, + 'users.isappuser' => 1, + 'users.isverified' => 1, + 'video.getuploadlimits' => 1); + $name = 'api'; + if (isset($READ_ONLY_CALLS[strtolower($method)])) { + $name = 'api_read'; + } else if (strtolower($method) == 'video.upload') { + $name = 'api_video'; + } + return self::getUrl($name, 'restserver.php'); + } + + /** + * Build the URL for given domain alias, path and parameters. + * + * @param $name string The name of the domain + * @param $path string Optional path (without a leading slash) + * @param $params array Optional query parameters + * + * @return string The URL for the given parameters + */ + protected function getUrl($name, $path='', $params=array()) { + $url = self::$DOMAIN_MAP[$name]; + if ($path) { + if ($path[0] === '/') { + $path = substr($path, 1); + } + $url .= $path; + } + if ($params) { + $url .= '?' . http_build_query($params, null, '&'); + } + + return $url; + } + + protected function getHttpHost() { + if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { + return $_SERVER['HTTP_X_FORWARDED_HOST']; + } + return $_SERVER['HTTP_HOST']; + } + + protected function getHttpProtocol() { + if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { + return 'https'; + } + return 'http'; + } + /*apache + variants specific way of checking for https*/ + if (isset($_SERVER['HTTPS']) && + ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) { + return 'https'; + } + /*nginx way of checking for https*/ + if (isset($_SERVER['SERVER_PORT']) && + ($_SERVER['SERVER_PORT'] === '443')) { + return 'https'; + } + return 'http'; + } + + /** + * Get the base domain used for the cookie. + */ + protected function getBaseDomain() { + // The base domain is stored in the metadata cookie if not we fallback + // to the current hostname + $metadata = $this->getMetadataCookie(); + if (array_key_exists('base_domain', $metadata) && + !empty($metadata['base_domain'])) { + return trim($metadata['base_domain'], '.'); + } + return $this->getHttpHost(); + } + + /** + + /** + * Returns the Current URL, stripping it of known FB parameters that should + * not persist. + * + * @return string The current URL + */ + protected function getCurrentUrl() { + $protocol = $this->getHttpProtocol() . '://'; + $host = $this->getHttpHost(); + $currentUrl = $protocol.$host.$_SERVER['REQUEST_URI']; + $parts = parse_url($currentUrl); + + $query = ''; + if (!empty($parts['query'])) { + // drop known fb params + $params = explode('&', $parts['query']); + $retained_params = array(); + foreach ($params as $param) { + if ($this->shouldRetainParam($param)) { + $retained_params[] = $param; + } + } + + if (!empty($retained_params)) { + $query = '?'.implode($retained_params, '&'); + } + } + + // use port if non default + $port = + isset($parts['port']) && + (($protocol === 'http://' && $parts['port'] !== 80) || + ($protocol === 'https://' && $parts['port'] !== 443)) + ? ':' . $parts['port'] : ''; + + // rebuild + return $protocol . $parts['host'] . $port . $parts['path'] . $query; + } + + /** + * Returns true if and only if the key or key/value pair should + * be retained as part of the query string. This amounts to + * a brute-force search of the very small list of Facebook-specific + * params that should be stripped out. + * + * @param string $param A key or key/value pair within a URL's query (e.g. + * 'foo=a', 'foo=', or 'foo'. + * + * @return boolean + */ + protected function shouldRetainParam($param) { + foreach (self::$DROP_QUERY_PARAMS as $drop_query_param) { + if (strpos($param, $drop_query_param.'=') === 0) { + return false; + } + } + + return true; + } + + /** + * Analyzes the supplied result to see if it was thrown + * because the access token is no longer valid. If that is + * the case, then we destroy the session. + * + * @param $result array A record storing the error message returned + * by a failed API call. + */ + protected function throwAPIException($result) { + $e = new FacebookApiException($result); + switch ($e->getType()) { + // OAuth 2.0 Draft 00 style + case 'OAuthException': + // OAuth 2.0 Draft 10 style + case 'invalid_token': + // REST server errors are just Exceptions + case 'Exception': + $message = $e->getMessage(); + if ((strpos($message, 'Error validating access token') !== false) || + (strpos($message, 'Invalid OAuth access token') !== false) || + (strpos($message, 'An active access token must be used') !== false) + ) { + $this->destroySession(); + } + break; + } + + throw $e; + } + + + /** + * Prints to the error log if you aren't in command line mode. + * + * @param string $msg Log message + */ + protected static function errorLog($msg) { + // disable error log if we are running in a CLI environment + // @codeCoverageIgnoreStart + if (php_sapi_name() != 'cli') { + error_log($msg); + } + // uncomment this if you want to see the errors on the page + // print 'error_log: '.$msg."\n"; + // @codeCoverageIgnoreEnd + } + + /** + * Base64 encoding that doesn't need to be urlencode()ed. + * Exactly the same as base64_encode except it uses + * - instead of + + * _ instead of / + * No padded = + * + * @param string $input base64UrlEncoded string + * @return string + */ + protected static function base64UrlDecode($input) { + return base64_decode(strtr($input, '-_', '+/')); + } + + /** + * Base64 encoding that doesn't need to be urlencode()ed. + * Exactly the same as base64_encode except it uses + * - instead of + + * _ instead of / + * + * @param string $input string + * @return string base64Url encoded string + */ + protected static function base64UrlEncode($input) { + $str = strtr(base64_encode($input), '+/', '-_'); + $str = str_replace('=', '', $str); + return $str; + } + + /** + * Destroy the current session + */ + public function destroySession() { + $this->accessToken = null; + $this->signedRequest = null; + $this->user = null; + $this->clearAllPersistentData(); + + // Javascript sets a cookie that will be used in getSignedRequest that we + // need to clear if we can + $cookie_name = $this->getSignedRequestCookieName(); + if (array_key_exists($cookie_name, $_COOKIE)) { + unset($_COOKIE[$cookie_name]); + if (!headers_sent()) { + $base_domain = $this->getBaseDomain(); + setcookie($cookie_name, '', 1, '/', '.'.$base_domain); + } else { + // @codeCoverageIgnoreStart + self::errorLog( + 'There exists a cookie that we wanted to clear that we couldn\'t '. + 'clear because headers was already sent. Make sure to do the first '. + 'API call before outputing anything.' + ); + // @codeCoverageIgnoreEnd + } + } + } + + /** + * Parses the metadata cookie that our Javascript API set + * + * @return an array mapping key to value + */ + protected function getMetadataCookie() { + $cookie_name = $this->getMetadataCookieName(); + if (!array_key_exists($cookie_name, $_COOKIE)) { + return array(); + } + + // The cookie value can be wrapped in "-characters so remove them + $cookie_value = trim($_COOKIE[$cookie_name], '"'); + + if (empty($cookie_value)) { + return array(); + } + + $parts = explode('&', $cookie_value); + $metadata = array(); + foreach ($parts as $part) { + $pair = explode('=', $part, 2); + if (!empty($pair[0])) { + $metadata[urldecode($pair[0])] = + (count($pair) > 1) ? urldecode($pair[1]) : ''; + } + } + + return $metadata; + } + + protected static function isAllowedDomain($big, $small) { + if ($big === $small) { + return true; + } + return self::endsWith($big, '.'.$small); + } + + protected static function endsWith($big, $small) { + $len = strlen($small); + if ($len === 0) { + return true; + } + return substr($big, -$len) === $small; + } + + /** + * Each of the following four methods should be overridden in + * a concrete subclass, as they are in the provided Facebook class. + * The Facebook class uses PHP sessions to provide a primitive + * persistent store, but another subclass--one that you implement-- + * might use a database, memcache, or an in-memory cache. + * + * @see Facebook + */ + + /** + * Stores the given ($key, $value) pair, so that future calls to + * getPersistentData($key) return $value. This call may be in another request. + * + * @param string $key + * @param array $value + * + * @return void + */ + abstract protected function setPersistentData($key, $value); + + /** + * Get the data for $key, persisted by BaseFacebook::setPersistentData() + * + * @param string $key The key of the data to retrieve + * @param boolean $default The default value to return if $key is not found + * + * @return mixed + */ + abstract protected function getPersistentData($key, $default = false); + + /** + * Clear the data with $key from the persistent storage + * + * @param string $key + * @return void + */ + abstract protected function clearPersistentData($key); + + /** + * Clear all data from the persistent storage + * + * @return void + */ + abstract protected function clearAllPersistentData(); +} diff --git a/AvocadoEdition/plugin/sns/facebook/src/facebook.php b/AvocadoEdition/plugin/sns/facebook/src/facebook.php new file mode 100644 index 0000000..a2238ef --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/src/facebook.php @@ -0,0 +1,160 @@ +<?php +/** + * Copyright 2011 Facebook, 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. + */ + +require_once "base_facebook.php"; + +/** + * Extends the BaseFacebook class with the intent of using + * PHP sessions to store user ids and access tokens. + */ +class Facebook extends BaseFacebook +{ + const FBSS_COOKIE_NAME = 'fbss'; + + // We can set this to a high number because the main session + // expiration will trump this. + const FBSS_COOKIE_EXPIRE = 31556926; // 1 year + + // Stores the shared session ID if one is set. + protected $sharedSessionID; + + /** + * Identical to the parent constructor, except that + * we start a PHP session to store the user ID and + * access token if during the course of execution + * we discover them. + * + * @param Array $config the application configuration. Additionally + * accepts "sharedSession" as a boolean to turn on a secondary + * cookie for environments with a shared session (that is, your app + * shares the domain with other apps). + * @see BaseFacebook::__construct in facebook.php + */ + public function __construct($config) { + if (!session_id()) { + session_start(); + } + parent::__construct($config); + if (!empty($config['sharedSession'])) { + $this->initSharedSession(); + } + } + + protected static $kSupportedKeys = + array('state', 'code', 'access_token', 'user_id'); + + protected function initSharedSession() { + $cookie_name = $this->getSharedSessionCookieName(); + if (isset($_COOKIE[$cookie_name])) { + $data = $this->parseSignedRequest($_COOKIE[$cookie_name]); + if ($data && !empty($data['domain']) && + self::isAllowedDomain($this->getHttpHost(), $data['domain'])) { + // good case + $this->sharedSessionID = $data['id']; + return; + } + // ignoring potentially unreachable data + } + // evil/corrupt/missing case + $base_domain = $this->getBaseDomain(); + $this->sharedSessionID = md5(uniqid(mt_rand(), true)); + $cookie_value = $this->makeSignedRequest( + array( + 'domain' => $base_domain, + 'id' => $this->sharedSessionID, + ) + ); + $_COOKIE[$cookie_name] = $cookie_value; + if (!headers_sent()) { + $expire = time() + self::FBSS_COOKIE_EXPIRE; + setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain); + } else { + // @codeCoverageIgnoreStart + self::errorLog( + 'Shared session ID cookie could not be set! You must ensure you '. + 'create the Facebook instance before headers have been sent. This '. + 'will cause authentication issues after the first request.' + ); + // @codeCoverageIgnoreEnd + } + } + + /** + * Provides the implementations of the inherited abstract + * methods. The implementation uses PHP sessions to maintain + * a store for authorization codes, user ids, CSRF states, and + * access tokens. + */ + protected function setPersistentData($key, $value) { + if (!in_array($key, self::$kSupportedKeys)) { + self::errorLog('Unsupported key passed to setPersistentData.'); + return; + } + + $session_var_name = $this->constructSessionVariableName($key); + $_SESSION[$session_var_name] = $value; + } + + protected function getPersistentData($key, $default = false) { + if (!in_array($key, self::$kSupportedKeys)) { + self::errorLog('Unsupported key passed to getPersistentData.'); + return $default; + } + + $session_var_name = $this->constructSessionVariableName($key); + return isset($_SESSION[$session_var_name]) ? + $_SESSION[$session_var_name] : $default; + } + + protected function clearPersistentData($key) { + if (!in_array($key, self::$kSupportedKeys)) { + self::errorLog('Unsupported key passed to clearPersistentData.'); + return; + } + + $session_var_name = $this->constructSessionVariableName($key); + unset($_SESSION[$session_var_name]); + } + + protected function clearAllPersistentData() { + foreach (self::$kSupportedKeys as $key) { + $this->clearPersistentData($key); + } + if ($this->sharedSessionID) { + $this->deleteSharedSessionCookie(); + } + } + + protected function deleteSharedSessionCookie() { + $cookie_name = $this->getSharedSessionCookieName(); + unset($_COOKIE[$cookie_name]); + $base_domain = $this->getBaseDomain(); + setcookie($cookie_name, '', 1, '/', '.'.$base_domain); + } + + protected function getSharedSessionCookieName() { + return self::FBSS_COOKIE_NAME . '_' . $this->getAppId(); + } + + protected function constructSessionVariableName($key) { + $parts = array('fb', $this->getAppId(), $key); + if ($this->sharedSessionID) { + array_unshift($parts, $this->sharedSessionID); + } + return implode('_', $parts); + } +} diff --git a/AvocadoEdition/plugin/sns/facebook/src/fb_ca_chain_bundle.crt b/AvocadoEdition/plugin/sns/facebook/src/fb_ca_chain_bundle.crt new file mode 100644 index 0000000..969239f --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/src/fb_ca_chain_bundle.crt @@ -0,0 +1,3920 @@ +## +## ca-bundle.crt -- Bundle of CA Root Certificates +## +## Certificate data from Mozilla as of: Thu Oct 18 19:05:59 2012 +## +## This is a bundle of X.509 certificates of public Certificate Authorities +## (CA). These were automatically extracted from Mozilla's root certificates +## file (certdata.txt). This file can be found in the mozilla source tree: +## http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1 +## +## It contains the certificates in PEM format and therefore +## can be directly used with curl / libcurl / php_curl, or with +## an Apache+mod_ssl webserver for SSL client authentication. +## Just configure this file as the SSLCACertificateFile. +## + +# @(#) $RCSfile: certdata.txt,v $ $Revision: 1.86 $ $Date: 2012/10/18 16:26:52 $ + +GTE CyberTrust Global Root +========================== +-----BEGIN CERTIFICATE----- +MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYDVQQKEw9HVEUg +Q29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEG +A1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJvb3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEz +MjM1OTAwWjB1MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQL +Ex5HVEUgQ3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0 +IEdsb2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrHiM3dFw4u +sJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTSr41tiGeA5u2ylc9yMcql +HHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X404Wqk2kmhXBIgD8SFcd5tB8FLztimQID +AQABMA0GCSqGSIb3DQEBBAUAA4GBAG3rGwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMW +M4ETCJ57NE7fQMh017l93PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OF +NMQkpw0PlZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ +-----END CERTIFICATE----- + +Thawte Server CA +================ +-----BEGIN CERTIFICATE----- +MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UE +AxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5j +b20wHhcNOTYwODAxMDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNV +BAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29u +c3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcG +A1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0 +ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl +/Kj0R1HahbUgdJSGHg91yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg7 +1CcEJRCXL+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGjEzAR +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG7oWDTSEwjsrZqG9J +GubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6eQNuozDJ0uW8NxuOzRAvZim+aKZuZ +GCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZqdq5snUb9kLy78fyGPmJvKP/iiMucEc= +-----END CERTIFICATE----- + +Thawte Premium Server CA +======================== +-----BEGIN CERTIFICATE----- +MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkExFTATBgNVBAgT +DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3Vs +dGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UE +AxMYVGhhd3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZl +ckB0aGF3dGUuY29tMB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYT +AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsGA1UEChMU +VGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2 +aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNlcnZlciBDQTEoMCYGCSqGSIb3DQEJARYZ +cHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2 +aovXwlue2oFBYo847kkEVdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIh +Udib0GfQug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMRuHM/ +qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQAm +SCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUIhfzJATj/Tb7yFkJD57taRvvBxhEf +8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JMpAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7t +UCemDaYj+bvLpgcUQg== +-----END CERTIFICATE----- + +Equifax Secure CA +================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoT +B0VxdWlmYXgxLTArBgNVBAsTJEVxdWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPR +fM6fBeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+AcJkVV5MW +8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kCAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UE +CxMkRXF1aWZheCBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTgwODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvS +spXXR9gjIBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAFjOKer89961 +zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y7qj/WsjTVbJmcVfewCHrPSqnI0kB +BIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee95 +70+sB3c4 +-----END CERTIFICATE----- + +Digital Signature Trust Co. Global CA 1 +======================================= +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE +ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMTAeFw05ODEy +MTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs +IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQCgbIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJE +NySZj9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlVSn5JTe2i +o74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo +BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw +IoAPMTk5ODEyMTAxODEwMjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQY +MBaAFGp5fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i+DAM +BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +ACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lNQseSJqBcNJo4cvj9axY+IO6CizEq +kzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4 +RbyhkwS7hp86W0N6w4pl +-----END CERTIFICATE----- + +Digital Signature Trust Co. Global CA 3 +======================================= +-----BEGIN CERTIFICATE----- +MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJVUzEkMCIGA1UE +ChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQLEwhEU1RDQSBFMjAeFw05ODEy +MDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJBgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFs +IFNpZ25hdHVyZSBUcnVzdCBDby4xETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUA +A4GLADCBhwKBgQC/k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGOD +VvsoLeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3oTQPMx7JS +xhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCGSAGG+EIBAQQEAwIABzBo +BgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0 +dXJlIFRydXN0IENvLjERMA8GA1UECxMIRFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQw +IoAPMTk5ODEyMDkxOTE3MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQY +MBaAFB6CTShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5WzAM +BgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4GB +AEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHRxdf0CiUPPXiBng+xZ8SQTGPdXqfi +up/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVLB3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1 +mPnHfxsb1gYgAlihw6ID +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA +TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah +WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf +Tqj/ZA1k +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgd +k4xWArzZbxpvUjZudVYKVdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIq +WpDBucSmFc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQIDAQAB +MA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0Jh9ZrbWB85a7FkCMM +XErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2uluIncrKTdcu1OofdPvAbT6shkdHvC +lUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68DzFc6PLZ +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h +cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp +Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazAeFw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGljIFByaW1h +cnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNp +Z24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjx +nNuX6Zr8wgQGE75fUsjMHiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRC +wiNPStjwDqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cCAwEA +ATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9jinb3/7aHmZuovCfTK +1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAXrXfMSTWqz9iP0b63GJZHc2pUIjRk +LbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnInjBJ7xUS0rg== +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G2 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO +FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71 +lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB +MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT +1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD +Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9 +-----END CERTIFICATE----- + +GlobalSign Root CA +================== +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx +GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds +b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV +BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD +VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa +DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc +THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb +Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP +c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX +gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF +AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj +Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG +j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH +hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC +X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +GlobalSign Root CA - R2 +======================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6 +ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp +s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN +S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL +TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C +ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i +YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN +BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp +9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu +01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7 +9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +ValiCert Class 1 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy +MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi +GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm +DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG +lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX +icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP +Orf1LXLI +-----END CERTIFICATE----- + +ValiCert Class 2 VA +=================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC +CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf +ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ +SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV +UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8 +W9ViH0Pd +-----END CERTIFICATE----- + +RSA Root Certificate 1 +====================== +-----BEGIN CERTIFICATE----- +MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp +b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs +YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh +bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw +MjIzM1oXDTE5MDYyNjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0 +d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMg +UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0 +LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDjmFGWHOjVsQaBalfDcnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td +3zZxFJmP3MKS8edgkpfs2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89H +BFx1cQqYJJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliEZwgs +3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJn0WuPIqpsHEzXcjF +V9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/APhmcGcwTTYJBtYze4D1gCCAPRX5r +on+jjBXu +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN2E1Lm0+afY8wR4nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/E +bRrsC+MO8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjVojYJ +rKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjbPG7PoBMAGrgnoeS+ +Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP26KbqxzcSXKMpHgLZ2x87tNcPVkeB +FQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vrn5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +q2aN17O6x5q25lXQBfGfMY1aqtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/N +y9Sn2WCVhDr4wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 +ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrspSCAaWihT37h +a88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4E1Z5T21Q6huwtVexN2ZYI/Pc +D98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== +-----END CERTIFICATE----- + +Verisign Class 2 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYTAlVT +MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29y +azE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug +b25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJ +BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1 +c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y +aXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArwoNwtUs22e5LeWUJ92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6 +tW8UvxDOJxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUYwZF7 +C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9okoqQHgiBVrKtaaNS +0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjNqWm6o+sdDZykIKbBoMXRRkwXbdKs +Zj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/ESrg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0 +JhU8wI1NQ0kdvekhktdmnLfexbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf +0xwLRtxyID+u7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU +sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RIsH/7NiXaldDx +JBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTPcjnhsUPgKM+351psE2tJs//j +GHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1 +EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc +cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw +EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj +055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f +j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0 +xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa +t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +Verisign Class 4 Public Primary Certification Authority - G3 +============================================================ +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy +dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS +tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM +8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW +Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX +Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA +j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt +mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm +fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd +RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG +UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== +-----END CERTIFICATE----- + +Entrust.net Secure Server CA +============================ +-----BEGIN CERTIFICATE----- +MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMCVVMxFDASBgNV +BAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5uZXQvQ1BTIGluY29ycC4gYnkg +cmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRl +ZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTAeFw05OTA1MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIG +A1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBi +eSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1p +dGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQ +aO2f55M28Qpku0f1BBc/I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5 +gXpa0zf3wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OCAdcw +ggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHboIHYpIHVMIHSMQsw +CQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5l +dC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF +bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu +dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0MFqBDzIwMTkw +NTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8BdiE1U9s/8KAGv7UISX8+1i0Bow +HQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAaMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA +BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyN +Ewr75Ji174z4xRAN95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9 +n9cd2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= +-----END CERTIFICATE----- + +Entrust.net Premium 2048 Secure Server CA +========================================= +-----BEGIN CERTIFICATE----- +MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u +ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp +bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV +BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx +NzUwNTFaFw0xOTEyMjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 +d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl +MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u +ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL +Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr +hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW +nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi +VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo3QwcjARBglghkgBhvhC +AQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGAvtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdER +gL7YibkIozH5oSQJFrlwMB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0B +AQUFAAOCAQEAWUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo +oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQh7A6tcOdBTcS +o8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18f3v/rxzP5tsHrV7bhZ3QKw0z +2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfNB/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjX +OP/swNlQ8C5LWK5Gb9Auw2DaclVyvUxFnmG6v4SBkgPR0ml8xQ== +-----END CERTIFICATE----- + +Baltimore CyberTrust Root +========================= +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE +ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li +ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC +SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs +dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME +uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB +UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C +G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9 +XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr +l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI +VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB +BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh +cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5 +hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa +Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H +RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +Equifax Secure Global eBusiness CA +================================== +-----BEGIN CERTIFICATE----- +MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBTZWN1cmUgR2xvYmFsIGVCdXNp +bmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIwMDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMx +HDAaBgNVBAoTE0VxdWlmYXggU2VjdXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEds +b2JhbCBlQnVzaW5lc3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRV +PEnCUdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc58O/gGzN +qfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/o5brhTMhHD4ePmBudpxn +hcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAHMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j +BBgwFoAUvqigdHJQa0S3ySPY+6j/s1draGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hs +MA0GCSqGSIb3DQEBBAUAA4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okEN +I7SS+RkAZ70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv8qIY +NMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 1 +============================= +-----BEGIN CERTIFICATE----- +MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +RXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENB +LTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQwMDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UE +ChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNz +IENBLTEwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ +1MRoRvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBuWqDZQu4a +IZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKwEnv+j6YDAgMBAAGjZjBk +MBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEp4MlIR21kW +Nl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRKeDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQF +AAOBgQB1W6ibAxHm6VZMzfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5 +lSE/9dR+WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN/Bf+ +KpYrtWKmpj29f5JZzVoqgrI3eQ== +-----END CERTIFICATE----- + +Equifax Secure eBusiness CA 2 +============================= +-----BEGIN CERTIFICATE----- +MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJVUzEXMBUGA1UE +ChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0y +MB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoT +DkVxdWlmYXggU2VjdXJlMSYwJAYDVQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCB +nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn +2Z0GvxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/BPO3QSQ5 +BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0CAwEAAaOCAQkwggEFMHAG +A1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUx +JjAkBgNVBAsTHUVxdWlmYXggU2VjdXJlIGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoG +A1UdEAQTMBGBDzIwMTkwNjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9e +uSBIplBqy/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQFMAMB +Af8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUAA4GBAAyGgq3oThr1 +jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia +78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUm +V+GRMOrN +-----END CERTIFICATE----- + +AddTrust Low-Value Services Root +================================ +-----BEGIN CERTIFICATE----- +MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU +cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw +CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO +ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6 +54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr +oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1 +Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui +GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w +HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT +RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw +HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt +ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph +iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY +eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr +mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj +ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= +-----END CERTIFICATE----- + +AddTrust External Root +====================== +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD +VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw +NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU +cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg +Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821 ++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw +Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo +aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy +2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7 +7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL +VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk +VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB +IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl +j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355 +e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u +G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +AddTrust Public Services Root +============================= +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU +cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ +BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l +dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu +nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i +d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG +Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw +HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G +A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G +A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4 +JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL ++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao +GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9 +Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H +EufOX1362KqxMy3ZdvJOOjMMK7MtkAY= +-----END CERTIFICATE----- + +AddTrust Qualified Certificates Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML +QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU +cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx +CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ +IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx +64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3 +KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o +L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR +wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU +MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE +BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y +azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG +GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X +dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze +RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB +iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE= +-----END CERTIFICATE----- + +Entrust Root Certification Authority +==================================== +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV +BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw +b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG +A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 +MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu +MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu +Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v +dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz +A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww +Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 +j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN +rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 +MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH +hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM +Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa +v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS +W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 +tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +RSA Security 2048 v3 +==================== +-----BEGIN CERTIFICATE----- +MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK +ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy +MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb +BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7 +Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb +WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH +KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP ++Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E +FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY +v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj +0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj +VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395 +nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA +pKnXwiJPZ9d37CAFYd4= +-----END CERTIFICATE----- + +GeoTrust Global CA +================== +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw +MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo +BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet +8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc +T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU +vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q +zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4 +d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2 +mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p +XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm +Mw== +-----END CERTIFICATE----- + +GeoTrust Global CA 2 +==================== +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw +MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j +LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/ +NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k +LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA +Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b +HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH +K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7 +srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh +ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL +OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC +x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF +H4z1Ir+rzoPz4iIprn2DQKi6bA== +-----END CERTIFICATE----- + +GeoTrust Universal CA +===================== +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1 +MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu +Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t +JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e +RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs +7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d +8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V +qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga +Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB +Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu +KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08 +ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0 +XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB +hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2 +qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL +oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK +xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF +KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2 +DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK +xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU +p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI +P/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +GeoTrust Universal CA 2 +======================= +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN +R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0 +MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg +SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0 +DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17 +j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q +JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a +QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2 +WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP +20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn +ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC +SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG +8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2 ++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E +BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ +4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+ +mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq +A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg +Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP +pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d +FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp +gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm +X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +UTN-USER First-Network Applications +=================================== +-----BEGIN CERTIFICATE----- +MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCBozELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzAp +BgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5 +WhcNMTkwNzA5MTg1NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5T +YWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho +dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3QtTmV0d29yayBB +cHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+5Gh5DZVhawGNFug +mliy+LUPBXeDrjKxdpJo7CNKyXY/45y2N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4Cj +DUeJT1FxL+78P/m4FoCHiZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXu +Ozr0hAReYFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1axwi +P8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6gyN7igEL66S/ozjIE +j3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8w +HQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPhahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9j +cmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0G +CSqGSIb3DQEBBQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y +IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6LzsQCv4AdRWOOTK +RIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4ZSfP1FMa8Kxun08FDAOBp4Qp +xFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qMYEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAq +DbUMo2s/rn9X9R+WfN9v3YIwLGUbQErNaLly7HF27FSOH4UMAWr6pjisH8SE +-----END CERTIFICATE----- + +America Online Root Certification Authority 1 +============================================= +-----BEGIN CERTIFICATE----- +MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lkhsmj76CG +v2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym1BW32J/X3HGrfpq/m44z +DyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsWOqMFf6Dch9Wc/HKpoH145LcxVR5lu9Rh +sCFg7RAycsWSJR74kEoYeEfffjA3PlAb2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP +8c9GsEsPPt2IYriMqQkoO3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0T +AQH/BAUwAwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAUAK3Z +o/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQB8itEf +GDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkFZu90821fnZmv9ov761KyBZiibyrF +VL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAbLjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft +3OJvx8Fi8eNy1gTIdGcL+oiroQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43g +Kd8hdIaC2y+CMMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds +sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 +-----END CERTIFICATE----- + +America Online Root Certification Authority 2 +============================================= +-----BEGIN CERTIFICATE----- +MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEcMBoGA1UEChMT +QW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBPbmxpbmUgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkG +A1UEBhMCVVMxHDAaBgNVBAoTE0FtZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2Eg +T25saW5lIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC206B89en +fHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFciKtZHgVdEglZTvYYUAQv8 +f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2JxhP7JsowtS013wMPgwr38oE18aO6lhO +qKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JN +RvCAOVIyD+OEsnpD8l7eXz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0 +gBe4lL8BPeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67Xnfn +6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEqZ8A9W6Wa6897Gqid +FEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZo2C7HK2JNDJiuEMhBnIMoVxtRsX6 +Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnj +B453cMor9H124HhnAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3Op +aaEg5+31IqEjFNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE +AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmnxPBUlgtk87FY +T15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2LHo1YGwRgJfMqZJS5ivmae2p ++DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzcccobGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXg +JXUjhx5c3LqdsKyzadsXg8n33gy8CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//Zoy +zH1kUQ7rVyZ2OuMeIjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgO +ZtMADjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2FAjgQ5ANh +1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUXOm/9riW99XJZZLF0Kjhf +GEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPbAZO1XB4Y3WRayhgoPmMEEf0cjQAPuDff +Z4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQlZvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuP +cX/9XhmgD0uRuMRUvAawRY8mkaKO/qk= +-----END CERTIFICATE----- + +Visa eCommerce Root +=================== +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG +EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug +QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2 +WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm +VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL +F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b +RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0 +TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI +/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs +GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG +MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc +CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW +YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz +zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu +YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +Certum Root CA +============== +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK +ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla +Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u +by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x +wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL +kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ +89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K +Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P +NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq +hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+ +GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg +GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/ +0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS +qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw== +-----END CERTIFICATE----- + +Comodo AAA Services root +======================== +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw +MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl +c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV +BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG +C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs +i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW +Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH +Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK +Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f +BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl +cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz +LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm +7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z +8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C +12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +Comodo Secure Services root +=========================== +-----BEGIN CERTIFICATE----- +MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw +MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu +Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi +BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP +9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc +rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC +oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V +p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E +FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj +YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm +aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm +4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj +Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL +DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw +pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H +RR3B7Hzs/Sk= +-----END CERTIFICATE----- + +Comodo Trusted Services root +============================ +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS +R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg +TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw +MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h +bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw +IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7 +3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y +/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6 +juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS +ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud +DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp +ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl +cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw +uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 +pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA +BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l +R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O +9y5Xt5hwXsjEeLBi +-----END CERTIFICATE----- + +QuoVadis Root CA +================ +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE +ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz +MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp +cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD +EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk +J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL +F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL +YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen +AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w +PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y +ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7 +MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj +YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs +ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW +Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu +BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw +FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6 +tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo +fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul +LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x +gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi +5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi +5nrQNiOKSnQ2+Q== +-----END CERTIFICATE----- + +QuoVadis Root CA 2 +================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +QuoVadis Root CA 3 +================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +Security Communication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP +U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw +8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM +DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX +5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd +DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2 +JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw +DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g +0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a +mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ +s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ +6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi +FL39vmwLAw== +-----END CERTIFICATE----- + +Sonera Class 1 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAxMDQwNjEwNDkxM1oXDTIxMDQw +NjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H88 +7dF+2rDNbS82rDTG29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9 +EJUkoVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk3w0LBUXl +0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBLqdReLjVQCfOAl/QMF645 +2F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIINnvmLVz5MxxftLItyM19yejhW1ebZrgUa +HXVFsculJRwSVzb9IjcCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZT +iFIwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE9 +28Jj2VuXZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0HDjxV +yhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VOTzF2nBBhjrZTOqMR +vq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2UvkVrCqIexVmiUefkl98HVrhq4uz2P +qYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4wzMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9Z +IRlXvVWa +-----END CERTIFICATE----- + +Sonera Class 2 Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG +U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw +NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh +IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3 +/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT +dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG +f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P +tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH +nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT +XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt +0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI +cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph +Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx +EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH +llpwrN9M +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA +============================= +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJOTDEeMBwGA1UE +ChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEyMTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4w +HAYDVQQKExVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxh +bmRlbiBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFt +vsznExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw719tV2U02P +jLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MOhXeiD+EwR+4A5zN9RGca +C1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+UtFE5A3+y3qcym7RHjm+0Sq7lr7HcsBth +vJly3uSJt3omXdozSVtSnA71iq3DuD3oBmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn6 +22r+I/q85Ej0ZytqERAhSQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRV +HSAAMDwwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMvcm9v +dC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA7Jbg0zTBLL9s+DAN +BgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k/rvuFbQvBgwp8qiSpGEN/KtcCFtR +EytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzmeafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbw +MVcoEoJz6TMvplW0C5GUR5z6u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3y +nGQI0DvDKcWy7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR +iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== +-----END CERTIFICATE----- + +TDC Internet Root CA +==================== +-----BEGIN CERTIFICATE----- +MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJESzEVMBMGA1UE +ChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTAeFw0wMTA0MDUx +NjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNVBAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJu +ZXQxHTAbBgNVBAsTFFREQyBJbnRlcm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxLhAvJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20j +xsNuZp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a0vnRrEvL +znWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc14izbSysseLlJ28TQx5yc +5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGNeGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6 +otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcDR0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZI +AYb4QgEBBAQDAgAHMGUGA1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMM +VERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxMEQ1JM +MTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3WjALBgNVHQ8EBAMC +AQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAwHQYDVR0OBBYEFGxkAcf9hW2syNqe +UAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJKoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0G +CSqGSIb3DQEBBQUAA4IBAQBOQ8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540m +gwV5dOy0uaOXwTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ +2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm899qNLPg7kbWzb +O0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0jUNAE4z9mQNUecYu6oah9jrU +Cbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38aQNiuJkFBT1reBK9sG9l +-----END CERTIFICATE----- + +TDC OCES Root CA +================ +-----BEGIN CERTIFICATE----- +MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJESzEMMAoGA1UE +ChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEwODM5MzBaFw0zNzAyMTEwOTA5 +MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNUREMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuH +nEz9pPPEXyG9VhDr2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0 +zY0s2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItUGBxIYXvV +iGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKjdGqPqcNiKXEx5TukYBde +dObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+rTpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO +3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB +5DCB4TCB3gYIKoFQgSkBAQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5k +ay9yZXBvc2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRlciBm +cmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4xLiBDZXJ0aWZp +Y2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEuMS4x +LjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1UdHwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEM +MAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYm +aHR0cDovL2NybC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy +MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZJ2cdUBVLc647 ++RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6 +NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACromJkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4 +A9G28kNBKWKnctj7fAXmMXAnVBhOinxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYsc +A+UYyAFMP8uXBV2YcaaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9 +AOoBmbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQYqbsFbS1 +AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9BKNDLdr8C2LqL19iUw== +-----END CERTIFICATE----- + +UTN DATACorp SGC Root CA +======================== +-----BEGIN CERTIFICATE----- +MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCBkzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZ +BgNVBAMTElVUTiAtIERBVEFDb3JwIFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBa +MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4w +HAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRy +dXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ys +raP6LnD43m77VkIVni5c7yPeIbkFdicZD0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlo +wHDyUwDAXlCCpVZvNvlK4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA +9P4yPykqlXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulWbfXv +33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQABo4GrMIGoMAsGA1Ud +DwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRTMtGzz3/64PGgXYVOktKeRR20TzA9 +BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dD +LmNybDAqBgNVHSUEIzAhBggrBgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3 +DQEBBQUAA4IBAQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft +Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyjj98C5OBxOvG0 +I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVHKWss5nbZqSl9Mt3JNjy9rjXx +EZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwP +DPafepE39peC4N1xaf92P2BNPM/3mfnGV/TJVTl4uix5yaaIK/QI +-----END CERTIFICATE----- + +UTN USERFirst Email Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0 +BgNVBAMTLVVUTi1VU0VSRmlyc3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05 +OTA3MDkxNzI4NTBaFw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQx +FzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx +ITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UEAxMtVVROLVVTRVJGaXJz +dC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWlsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3BYHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIx +B8dOtINknS4p1aJkxIW9hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8 +om+rWV6lL8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLmSGHG +TPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM1tZUOt4KpLoDd7Nl +yP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws6wIDAQABo4G5MIG2MAsGA1UdDwQE +AwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNV +HR8EUTBPME2gS6BJhkdodHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGll +bnRBdXRoZW50aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH +AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u7mFVbwQ+zzne +xRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0xtcgBEXkzYABurorbs6q15L+ +5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQrfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarV +NZ1yQAOJujEdxRBoUp7fooXFXAimeOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZ +w7JHpsIyYdfHb0gkUSeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= +-----END CERTIFICATE----- + +UTN USERFirst Hardware Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd +BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx +OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0 +eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz +ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI +wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd +tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8 +i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf +Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw +gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF +lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF +UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF +BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM +//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW +XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2 +lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn +iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67 +nfhmqA== +-----END CERTIFICATE----- + +UTN USERFirst Object Root CA +============================ +-----BEGIN CERTIFICATE----- +MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UE +BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl +IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAb +BgNVBAMTFFVUTi1VU0VSRmlyc3QtT2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAz +NlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx +HjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3dy51c2Vy +dHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicPHxzfOpuCaDDASmEd8S8O+r5596Uj71VR +loTN2+O5bj4x2AogZ8f02b+U60cEPgLOKqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQ +w5ujm9M89RKZd7G3CeBo5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vu +lBe3/IW+pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehbkkj7 +RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUCAwEAAaOBrzCBrDAL +BgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2u1kdBScFDyr3ZmpvVsoTYs8 +ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly +c3QtT2JqZWN0LmNybDApBgNVHSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQw +DQYJKoZIhvcNAQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw +NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXBmMiKVl0+7kNO +PmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU4U3GDZlDAQ0Slox4nb9QorFE +qmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK581OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCG +hU3IfdeLA/5u1fedFqySLKAj5ZyRUh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= +-----END CERTIFICATE----- + +Camerfirma Chambers of Commerce Root +==================================== +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx +NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp +cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn +MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC +AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU +xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH +NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW +DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV +d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud +EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v +cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P +AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh +bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD +VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz +aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi +fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD +L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN +UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n +ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1 +erfutGWaIZDgqtCYvDi1czyL+Nw= +-----END CERTIFICATE----- + +Camerfirma Global Chambersign Root +================================== +-----BEGIN CERTIFICATE----- +MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe +QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i +ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx +NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt +YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg +MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw +ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J +1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O +by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl +6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c +8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/ +BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j +aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B +Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj +aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y +ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh +bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA +PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y +gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ +PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4 +IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes +t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== +-----END CERTIFICATE----- + +NetLock Qualified (Class QA) Root +================================= +-----BEGIN CERTIFICATE----- +MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQDEzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVn +eXpvaSAoQ2xhc3MgUUEpIFRhbnVzaXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0 +bG9jay5odTAeFw0wMzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNhZ2kgS2Z0 +LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5ldExvY2sgTWlub3NpdGV0 +dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZhbnlraWFkbzEeMBwGCSqGSIb3DQEJARYP +aW5mb0BuZXRsb2NrLmh1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRV +CacbvWy5FPSKAtt2/GoqeKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e +8ia6AFQer7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO53Lhb +m+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWdvLrqOU+L73Sa58XQ +0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0lmT+1fMptsK6ZmfoIYOcZwvK9UdPM +0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4ICwDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV +HQ8BAf8EBAMCAQYwggJ1BglghkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2 +YW55IGEgTmV0TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh +biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQgZWxla3Ryb25p +a3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywgdmFsYW1pbnQgZWxmb2dhZGFz +YW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwg +YXogQWx0YWxhbm9zIFN6ZXJ6b2Rlc2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kg +ZWxqYXJhcyBtZWd0ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczov +L3d3dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0BuZXRsb2Nr +Lm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0 +aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMg +YXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0 +IGluZm9AbmV0bG9jay5uZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3 +DQEBBQUAA4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQMznN +wNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+NFAwLvt/MpqNPfMg +W/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCRVCHnpgu0mfVRQdzNo0ci2ccBgcTc +R08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR +5qq5aKrN9p2QdRLqOBrKROi3macqaJVmlaut74nLYKkGEsaUR+ko +-----END CERTIFICATE----- + +NetLock Notary (Class A) Root +============================= +-----BEGIN CERTIFICATE----- +MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQI +EwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9j +ayBLb3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oX +DTE5MDIxOTIzMTQ0N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQH +EwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYD +VQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFz +cyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSM +D7tM9DceqQWC2ObhbHDqeLVu0ThEDaiDzl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZ +z+qMkjvN9wfcZnSX9EUi3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC +/tmwqcm8WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LYOph7 +tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2EsiNCubMvJIH5+hCoR6 +4sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCCApswDgYDVR0PAQH/BAQDAgAGMBIG +A1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaC +Ak1GSUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pv +bGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu +IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2Vn +LWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0 +ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFz +IGxlaXJhc2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBh +IGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVu +b3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBh +bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sg +Q1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFp +bCBhdCBjcHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5 +ayZrU3/b39/zcT0mwBQOxmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjP +ytoUMaFP0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQQeJB +CWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxkf1qbFFgBJ34TUMdr +KuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK8CtmdWOMovsEPoMOmzbwGOQmIMOM +8CgHrTwXZoi1/baI +-----END CERTIFICATE----- + +NetLock Business (Class B) Root +=============================== +-----BEGIN CERTIFICATE----- +MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQDEylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikg +VGFudXNpdHZhbnlraWFkbzAeFw05OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYD +VQQGEwJIVTERMA8GA1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRv +bnNhZ2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5ldExvY2sg +VXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xKgZjupNTKihe5In+DCnVMm8Bp2GQ5o+2S +o/1bXHQawEfKOml2mrriRBf8TKPV/riXiK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr +1nGTLbO/CVRY7QbrqHvcQ7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNV +HQ8BAf8EBAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZ +RUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRh +dGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQuIEEgaGl0 +ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRv +c2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUg +YXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh +c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBz +Oi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6ZXNA +bmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhl +IHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2 +YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBj +cHNAbmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06sPgzTEdM +43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXan3BukxowOR0w2y7jfLKR +stE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKSNitjrFgBazMpUIaD8QFI +-----END CERTIFICATE----- + +NetLock Express (Class C) Root +============================== +-----BEGIN CERTIFICATE----- +MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUxETAPBgNVBAcT +CEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0b25zYWdpIEtmdC4xGjAYBgNV +BAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQDEytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBD +KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJ +BgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6 +dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMrTmV0TG9j +ayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzANBgkqhkiG9w0BAQEFAAOB +jQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNAOoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3Z +W3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63 +euyucYT2BDMIJTLrdKwWRMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQw +DgYDVR0PAQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEWggJN +RklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0YWxhbm9zIFN6b2xn +YWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBB +IGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBOZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1i +aXp0b3NpdGFzYSB2ZWRpLiBBIGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0 +ZWxlIGF6IGVsb2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs +ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25sYXBqYW4gYSBo +dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kga2VyaGV0byBheiBlbGxlbm9y +emVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4gSU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5k +IHRoZSB1c2Ugb2YgdGhpcyBjZXJ0aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQ +UyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwg +YXQgY3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmYta3UzbM2 +xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2gpO0u9f38vf5NNwgMvOOW +gyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4Fp1hBWeAyNDYpQcCNJgEjTME1A== +-----END CERTIFICATE----- + +XRamp Global CA Root +==================== +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE +BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj +dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx +HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg +U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu +IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx +foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE +zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs +AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry +xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap +oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC +AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc +/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n +nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz +8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +Go Daddy Class 2 CA +=================== +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY +VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG +A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g +RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD +ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv +2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32 +qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j +YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY +vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O +BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o +atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu +MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG +A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim +PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt +I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI +Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b +vZ8= +-----END CERTIFICATE----- + +Starfield Class 2 CA +==================== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc +U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg +Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo +MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG +A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG +SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY +bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ +JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm +epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN +F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF +MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f +hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo +bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g +QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs +afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM +PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD +KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3 +QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE +FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0 +Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj +YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH +AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw +Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg +U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5 +LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl +cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh +cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT +dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC +AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh +3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm +vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk +fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3 +fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ +EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq +yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl +1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/ +lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro +g14= +-----END CERTIFICATE----- + +Taiwan GRCA +=========== +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG +EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X +DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv +dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN +w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5 +BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O +1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO +htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov +J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7 +Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t +B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB +O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8 +lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV +HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2 +09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj +Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2 +Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU +D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz +DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk +Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk +7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ +CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy ++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS +-----END CERTIFICATE----- + +Firmaprofesional Root CA +======================== +-----BEGIN CERTIFICATE----- +MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMxIjAgBgNVBAcT +GUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1dG9yaWRhZCBkZSBDZXJ0aWZp +Y2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FA +ZmlybWFwcm9mZXNpb25hbC5jb20wHhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTEL +MAkGA1UEBhMCRVMxIjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMT +OUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2 +ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20wggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5uCp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5V +j1H5WuretXDE7aTt/6MNbg9kUDGvASdYrv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJH +lShbz++AbOCQl4oBPB3zhxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf +3H5idPayBQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcLiam8 +NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcbAgMBAAGjgZ8wgZww +KgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lvbmFsLmNvbTASBgNVHRMBAf8ECDAG +AQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQAD +ggEBAEdz/o0nVPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq +u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36mhoEyIwOdyPdf +wUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzflZKG+TQyTmAyX9odtsz/ny4Cm +7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBpQWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YG +VM+h4k0460tQtcsm9MracEpqoeJ5quGnM/b9Sh/22WA= +-----END CERTIFICATE----- + +Wells Fargo Root CA +=================== +-----BEGIN CERTIFICATE----- +MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMCVVMxFDASBgNV +BAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDAxMDExMTY0MTI4WhcNMjEwMTE0MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dl +bGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEv +MC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n135zHCLielTWi5MbqNQ1mX +x3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHESxP9cMIlrCL1dQu3U+SlK93OvRw6esP3 +E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4OJgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5 +OEL8pahbSCOz6+MlsoCultQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4j +sNtlAHCEAQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMBAAGj +YTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcBCzAyMDAGCCsGAQUF +BwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRwb2xpY3kwDQYJKoZIhvcNAQEFBQAD +ggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrv +m+0fazbuSCUlFLZWohDo7qd/0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0R +OhPs7fpvcmR7nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx +x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ33ZwmVxwQ023 +tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= +-----END CERTIFICATE----- + +Swisscom Root CA 1 +================== +-----BEGIN CERTIFICATE----- +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 +NY6E0F/6MBr1mmz0DlP5OlvRHA== +-----END CERTIFICATE----- + +DigiCert Assured ID Root CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw +IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx +MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO +9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy +UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW +/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy +oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf +GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF +66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq +hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc +EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn +SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i +8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +DigiCert Global Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw +HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw +MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 +dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn +TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 +BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H +4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y +7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB +o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm +8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF +BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr +EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt +tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 +UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +DigiCert High Assurance EV Root CA +================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw +KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw +MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ +MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu +Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t +Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS +OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 +MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ +NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe +h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB +Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY +JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ +V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp +myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK +mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K +-----END CERTIFICATE----- + +Certplus Class 2 Primary CA +=========================== +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE +BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN +OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy +dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR +5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ +Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO +YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e +e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME +CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ +YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t +L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD +P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R +TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+ +7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW +//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +DST Root CA X3 +============== +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK +ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X +DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1 +cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT +rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9 +UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy +xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d +utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ +MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug +dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE +GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw +RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS +fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +DST ACES CA X6 +============== +-----BEGIN CERTIFICATE----- +MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT +MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha +MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE +CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI +DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa +pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow +GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy +MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu +Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy +dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU +CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2 +5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t +Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq +nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs +vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3 +oKfN5XozNmr6mis= +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 1 +============================================== +-----BEGIN CERTIFICATE----- +MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGDAJUUjEP +MA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykgMjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0 +acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMx +MDI3MTdaFw0xNTAzMjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsg +U2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYDVQQHDAZB +TktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBC +aWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GX +yGl8hMW0kWxsE2qkVa2kheiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8i +Si9BB35JYbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5CurKZ +8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1JuTm5Rh8i27fbMx4 +W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51b0dewQIDAQABoxAwDjAMBgNVHRME +BTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46 +sWrv7/hg0Uw2ZkUd82YCdAR7kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxE +q8Sn5RTOPEFhfEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy +B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdAaLX/7KfS0zgY +nNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKSRGQDJereW26fyfJOrN3H +-----END CERTIFICATE----- + +TURKTRUST Certificate Services Provider Root 2 +============================================== +-----BEGIN CERTIFICATE----- +MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcN +MDUxMTA3MTAwNzU3WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVr +dHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEPMA0G +A1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmls +acWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqe +LCDe2JAOCtFp0if7qnefJ1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKI +x+XlZEdhR3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJQv2g +QrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGXJHpsmxcPbe9TmJEr +5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1pzpwACPI2/z7woQ8arBT9pmAPAgMB +AAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58SFq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/ntt +Rbj2hWyfIvwqECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 +Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFzgw2lGh1uEpJ+ +hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotHuFEJjOp9zYhys2AzsfAKRO8P +9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LSy3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5 +UrbnBEI= +-----END CERTIFICATE----- + +SwissSign Platinum CA - G2 +========================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +SwissSign Gold CA - G2 +====================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +SwissSign Silver CA - G2 +======================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority +======================================== +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx +CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ +cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN +b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9 +nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge +RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt +tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI +hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K +Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN +NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa +Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG +1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +thawte Primary Root CA +====================== +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3 +MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg +SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv +KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT +FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs +oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ +1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc +q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K +aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p +afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF +AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE +uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89 +jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH +z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G5 +============================================================ +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln +biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh +dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt +YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz +j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD +Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r +fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/ +BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv +Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG +SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+ +X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE +KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC +Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE +ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +SecureTrust CA +============== +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy +dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe +BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX +OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t +DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH +GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b +01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH +ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu +SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf +mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ +nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +Secure Global CA +================ +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG +EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH +bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg +MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx +YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ +bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g +8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV +HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi +0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn +oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA +MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ +OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn +CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 +3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +COMODO Certification Authority +============================== +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb +MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD +T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH ++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww +xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV +4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA +1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI +rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k +b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC +AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP +OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc +IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN ++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== +-----END CERTIFICATE----- + +Network Solutions Certificate Authority +======================================= +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG +EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr +IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx +MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx +jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT +aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT +crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc +/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB +AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv +bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA +A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q +4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/ +GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD +ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +WellsSecure Public Root Certificate Authority +============================================= +-----BEGIN CERTIFICATE----- +MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoM +F1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYw +NAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcN +MDcxMjEzMTcwNzU0WhcNMjIxMjE0MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dl +bGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYD +VQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+rWxxTkqxtnt3CxC5FlAM1 +iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjUDk/41itMpBb570OYj7OeUt9tkTmPOL13 +i0Nj67eT/DBMHAGTthP796EfvyXhdDcsHqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8 +bJVhHlfXBIEyg1J55oNjz7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiB +K0HmOFafSZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/SlwxlAgMB +AAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9jcmwu +cGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0PAQH/BAQDAgHGMB0GA1UdDgQWBBQm +lRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0jBIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGB +i6SBiDCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRww +GgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEBALkVsUSRzCPI +K0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd/ZDJPHV3V3p9+N701NX3leZ0 +bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pBA4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSlj +qHyita04pO2t/caaH/+Xc/77szWnk4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+es +E2fDbbFwRnzVlhE9iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJ +tylv2G0xffX8oRAHh84vWdw+WNs= +-----END CERTIFICATE----- + +COMODO ECC Certification Authority +================================== +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix +GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X +4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni +wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG +FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA +U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +IGC/A +===== +-----BEGIN CERTIFICATE----- +MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD +VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE +Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy +MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI +EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT +STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2 +TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW +So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy +HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd +frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ +tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB +egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC +iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK +q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q +MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg +Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI +lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF +0mBWWg== +-----END CERTIFICATE----- + +Security Communication EV RootCA1 +================================= +-----BEGIN CERTIFICATE----- +MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE +BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl +Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO +/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX +WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z +ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4 +bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK +9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG +SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm +iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG +Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW +mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW +T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490 +-----END CERTIFICATE----- + +OISTE WISeKey Global Root GA CA +=============================== +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE +BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG +A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH +bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD +VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw +IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5 +IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9 +Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg +Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD +d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ +/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R +LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ +KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm +MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4 ++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY +okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0= +-----END CERTIFICATE----- + +S-TRUST Authentication and Encryption Root CA 2005 PN +===================================================== +-----BEGIN CERTIFICATE----- +MIIEezCCA2OgAwIBAgIQNxkY5lNUfBq1uMtZWts1tzANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UE +BhMCREUxIDAeBgNVBAgTF0JhZGVuLVd1ZXJ0dGVtYmVyZyAoQlcpMRIwEAYDVQQHEwlTdHV0dGdh +cnQxKTAnBgNVBAoTIERldXRzY2hlciBTcGFya2Fzc2VuIFZlcmxhZyBHbWJIMT4wPAYDVQQDEzVT +LVRSVVNUIEF1dGhlbnRpY2F0aW9uIGFuZCBFbmNyeXB0aW9uIFJvb3QgQ0EgMjAwNTpQTjAeFw0w +NTA2MjIwMDAwMDBaFw0zMDA2MjEyMzU5NTlaMIGuMQswCQYDVQQGEwJERTEgMB4GA1UECBMXQmFk +ZW4tV3VlcnR0ZW1iZXJnIChCVykxEjAQBgNVBAcTCVN0dXR0Z2FydDEpMCcGA1UEChMgRGV1dHNj +aGVyIFNwYXJrYXNzZW4gVmVybGFnIEdtYkgxPjA8BgNVBAMTNVMtVFJVU1QgQXV0aGVudGljYXRp +b24gYW5kIEVuY3J5cHRpb24gUm9vdCBDQSAyMDA1OlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2bVKwdMz6tNGs9HiTNL1toPQb9UY6ZOvJ44TzbUlNlA0EmQpoVXhOmCTnijJ4/Ob +4QSwI7+Vio5bG0F/WsPoTUzVJBY+h0jUJ67m91MduwwA7z5hca2/OnpYH5Q9XIHV1W/fuJvS9eXL +g3KSwlOyggLrra1fFi2SU3bxibYs9cEv4KdKb6AwajLrmnQDaHgTncovmwsdvs91DSaXm8f1Xgqf +eN+zvOyauu9VjxuapgdjKRdZYgkqeQd3peDRF2npW932kKvimAoA0SVtnteFhy+S8dF2g08LOlk3 +KC8zpxdQ1iALCvQm+Z845y2kuJuJja2tyWp9iRe79n+Ag3rm7QIDAQABo4GSMIGPMBIGA1UdEwEB +/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTVFJv +bmxpbmUxLTIwNDgtNTAdBgNVHQ4EFgQUD8oeXHngovMpttKFswtKtWXsa1IwHwYDVR0jBBgwFoAU +D8oeXHngovMpttKFswtKtWXsa1IwDQYJKoZIhvcNAQEFBQADggEBAK8B8O0ZPCjoTVy7pWMciDMD +pwCHpB8gq9Yc4wYfl35UvbfRssnV2oDsF9eK9XvCAPbpEW+EoFolMeKJ+aQAPzFoLtU96G7m1R08 +P7K9n3frndOMusDXtk3sU5wPBG7qNWdX4wple5A64U8+wwCSersFiXOMy6ZNwPv2AtawB6MDwidA +nwzkhYItr5pCHdDHjfhA7p0GVxzZotiAFP7hYy0yh9WUUpY6RsZxlj33mA6ykaqP2vROJAA5Veit +F7nTNCtKqUDMFypVZUF0Qn71wK/Ik63yGFs9iQzbRzkk+OBM8h+wPQrKBU6JIRrjKpms/H+h8Q8b +Hz2eBIPdltkdOpQ= +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA +========================= +-----BEGIN CERTIFICATE----- +MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAwcjELMAkGA1UE +BhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNyb3NlYyBMdGQuMRQwEgYDVQQL +EwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9zZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0 +MDYxMjI4NDRaFw0xNzA0MDYxMjI4NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVz +dDEWMBQGA1UEChMNTWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMT +GU1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2uuO/TEdyB5s87lozWbxXG +d36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/N +oqdNAoI/gqyFxuEPkEeZlApxcpMqyabAvjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjc +QR/Ji3HWVBTji1R4P770Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJ +PqW+jqpx62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcBAQRb +MFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3AwLQYIKwYBBQUHMAKG +IWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAPBgNVHRMBAf8EBTADAQH/MIIBcwYD +VR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIBAQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3 +LmUtc3ppZ25vLmh1L1NaU1ovMIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0A +dAB2AOEAbgB5ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn +AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABTAHoAbwBsAGcA +4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABhACAAcwB6AGUAcgBpAG4AdAAg +AGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABoAHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMA +egBpAGcAbgBvAC4AaAB1AC8AUwBaAFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6 +Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NO +PU1pY3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxPPU1pY3Jv +c2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdDtiaW5h +cnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuBEGluZm9AZS1zemlnbm8uaHWkdzB1MSMw +IQYDVQQDDBpNaWNyb3NlYyBlLVN6aWduw7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhT +WjEWMBQGA1UEChMNTWljcm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhV +MIGsBgNVHSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJIVTER +MA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDASBgNVBAsTC2UtU3pp +Z25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBSb290IENBghEAzLjnv04pGv2i3Gal +HCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMT +nGZjWS7KXHAM/IO8VbH0jgdsZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FE +aGAHQzAxQmHl7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a +86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfRhUZLphK3dehK +yVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/MPMMNz7UwiiAc7EBt51alhQB +S6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU= +-----END CERTIFICATE----- + +Certigna +======== +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw +EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 +MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI +Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q +XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH +GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p +ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg +DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf +Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ +tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ +BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J +SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA +hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ +ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu +PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY +1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +AC Ra\xC3\xADz Certic\xC3\xA1mara S.A. +====================================== +-----BEGIN CERTIFICATE----- +MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNVBAYT +AkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRpZmljYWNpw7NuIERpZ2l0YWwg +LSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwaQUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4w +HhcNMDYxMTI3MjA0NjI5WhcNMzAwNDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+ +U29jaWVkYWQgQ2FtZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJh +IFMuQS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeGqentLhM0R7LQcNzJPNCN +yu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzLfDe3fezTf3MZsGqy2IiKLUV0qPezuMDU +2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQY5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU3 +4ojC2I+GdV75LaeHM/J4Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP +2yYe68yQ54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+bMMCm +8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48jilSH5L887uvDdUhf +HjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++EjYfDIJss2yKHzMI+ko6Kh3VOz3vCa +Mh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/ztA/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK +5lw1omdMEWux+IBkAC1vImHFrEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1b +czwmPS9KvqfJpxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE +AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCBlTCBkgYEVR0g +ADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFyYS5jb20vZHBjLzBaBggrBgEF +BQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW507WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2Ug +cHVlZGVuIGVuY29udHJhciBlbiBsYSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEf +AygPU3zmpFmps4p6xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuX +EpBcunvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/Jre7Ir5v +/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dpezy4ydV/NgIlqmjCMRW3 +MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42gzmRkBDI8ck1fj+404HGIGQatlDCIaR4 +3NAvO2STdPCWkPHv+wlaNECW8DYSwaN0jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wk +eZBWN7PGKX6jD/EpOe9+XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f +/RWmnkJDW2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/RL5h +RqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35rMDOhYil/SrnhLecU +Iw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxkBYn8eNZcLCZDqQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 2 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYw +MTEyMTQzODQzWhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jftMjWQ+nEdVl//OEd+DFw +IxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKguNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2 +xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2JXjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQ +Xa7pIXSSTYtZgo+U4+lK8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7u +SNQZu+995OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3kUrL84J6E1wIqzCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iSGNn3Bzn1LL4G +dXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprtZjluS5TmVfwLG4t3wVMTZonZ +KNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8au0WOB9/WIFaGusyiC2y8zl3gK9etmF1Kdsj +TYjKUCjLhdLTEKJZbtOTVAB6okaVhgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kP +JOzHdiEoZa5X6AeIdUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfk +vQ== +-----END CERTIFICATE----- + +TC TrustCenter Class 3 CA II +============================ +-----BEGIN CERTIFICATE----- +MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNVBAsTGVRDIFRydXN0Q2VudGVy +IENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYw +MTEyMTQ0MTU3WhcNMjUxMjMxMjI1OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1 +c3RDZW50ZXIgR21iSDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UE +AxMcVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJWHt4bNwcwIi9v8Qbxq63W +yKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+QVl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo +6SI7dYnWRBpl8huXJh0obazovVkdKyT21oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZ +uV3bOx4a+9P/FRQI2AlqukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk +2ZyqBwi1Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NXXAek0CSnwPIA1DCB +7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRydXN0Y2VudGVyLmRlL2NybC92Mi90 +Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBU +cnVzdENlbnRlciUyMENsYXNzJTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21i +SCxPVT1yb290Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u +TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlNirTzwppVMXzE +O2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8TtXqluJucsG7Kv5sbviRmEb8 +yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9 +IJqDnxrcOfHFcqMRA/07QlIp2+gB95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal +092Y+tTmBvTwtiBjS+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc +5A== +-----END CERTIFICATE----- + +TC TrustCenter Universal CA I +============================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy +IFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcN +MDYwMzIyMTU1NDI4WhcNMjUxMjMxMjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMg +VHJ1c3RDZW50ZXIgR21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYw +JAYDVQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSRJJZ4Hgmgm5qVSkr1YnwC +qMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3TfCZdzHd55yx4Oagmcw6iXSVphU9VDprv +xrlE4Vc93x9UIuVvZaozhDrzznq+VZeujRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtw +ag+1m7Z3W0hZneTvWq3zwZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9O +gdwZu5GQfezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYDVR0j +BBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0GCSqGSIb3DQEBBQUAA4IBAQAo0uCG +1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X17caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/Cy +vwbZ71q+s2IhtNerNXxTPqYn8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3 +ghUJGooWMNjsydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT +ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/2TYcuiUaUj0a +7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY +-----END CERTIFICATE----- + +Deutsche Telekom Root CA 2 +========================== +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT +RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG +A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5 +MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G +A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS +b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5 +bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI +KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY +AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK +Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV +jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV +HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr +E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy +zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8 +rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G +dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +ComSign CA +========== +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIQFBOWgxRVjOp7Y+X8NId3RDANBgkqhkiG9w0BAQUFADA0MRMwEQYDVQQD +EwpDb21TaWduIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTMy +MThaFw0yOTAzMTkxNTAyMThaMDQxEzARBgNVBAMTCkNvbVNpZ24gQ0ExEDAOBgNVBAoTB0NvbVNp +Z24xCzAJBgNVBAYTAklMMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ORUaSvTx49q +ROR+WCf4C9DklBKK8Rs4OC8fMZwG1Cyn3gsqrhqg455qv588x26i+YtkbDqthVVRVKU4VbirgwTy +P2Q298CNQ0NqZtH3FyrV7zb6MBBC11PN+fozc0yz6YQgitZBJzXkOPqUm7h65HkfM/sb2CEJKHxN +GGleZIp6GZPKfuzzcuc3B1hZKKxC+cX/zT/npfo4sdAMx9lSGlPWgcxCejVb7Us6eva1jsz/D3zk +YDaHL63woSV9/9JLEYhwVKZBqGdTUkJe5DSe5L6j7KpiXd3DTKaCQeQzC6zJMw9kglcq/QytNuEM +rkvF7zuZ2SOzW120V+x0cAwqTwIDAQABo4GgMIGdMAwGA1UdEwQFMAMBAf8wPQYDVR0fBDYwNDAy +oDCgLoYsaHR0cDovL2ZlZGlyLmNvbXNpZ24uY28uaWwvY3JsL0NvbVNpZ25DQS5jcmwwDgYDVR0P +AQH/BAQDAgGGMB8GA1UdIwQYMBaAFEsBmz5WGmU2dst7l6qSBe4y5ygxMB0GA1UdDgQWBBRLAZs+ +VhplNnbLe5eqkgXuMucoMTANBgkqhkiG9w0BAQUFAAOCAQEA0Nmlfv4pYEWdfoPPbrxHbvUanlR2 +QnG0PFg/LUAlQvaBnPGJEMgOqnhPOAlXsDzACPw1jvFIUY0McXS6hMTXcpuEfDhOZAYnKuGntewI +mbQKDdSFc8gS4TXt8QUxHXOZDOuWyt3T5oWq8Ir7dcHyCTxlZWTzTNity4hp8+SDtwy9F1qWF8pb +/627HOkthIDYIb6FUtnUdLlphbpN7Sgy6/lhSuTENh4Z3G+EER+V9YMoGKgzkkMn3V0TBEVPh9VG +zT2ouvDzuFYkRes3x+F2T3I5GN9+dHLHcy056mDmrRGiVod7w2ia/viMcKjfZTL0pECMocJEAw6U +AGegcQCCSA== +-----END CERTIFICATE----- + +ComSign Secured CA +================== +-----BEGIN CERTIFICATE----- +MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAwPDEbMBkGA1UE +AxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWduMQswCQYDVQQGEwJJTDAeFw0w +NDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwxGzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBD +QTEQMA4GA1UEChMHQ29tU2lnbjELMAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDGtWhfHZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs +49ohgHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sWv+bznkqH +7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ueMv5WJDmyVIRD9YTC2LxB +kMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d1 +9guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUw +AwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29t +U2lnblNlY3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58ADsA +j8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkqhkiG9w0BAQUFAAOC +AQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7piL1DRYHjZiM/EoZNGeQFsOY3wo3a +BijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtCdsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtp +FhpFfTMDZflScZAmlaxMDPWLkz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP +51qJThRv4zdLhfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz +OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== +-----END CERTIFICATE----- + +Cybertrust Global Root +====================== +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li +ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4 +MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD +ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA ++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW +0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL +AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin +89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT +8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2 +MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G +A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO +lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi +5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2 +hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T +X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +ePKI Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG +EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx +MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq +MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs +IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi +lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv +qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX +12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O +WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ +ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao +lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ +vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi +Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi +MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 +1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq +KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV +xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP +NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r +GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE +xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx +gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy +sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD +BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3 +============================================================================================================================= +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH +DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q +aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry +b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV +BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg +S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4 +MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl +IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF +n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl +IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft +dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl +cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO +Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1 +xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR +6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL +hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd +BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4 +N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT +y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh +LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M +dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= +-----END CERTIFICATE----- + +Buypass Class 2 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2 +MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M +cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83 +0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4 +0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R +uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV +1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt +7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2 +fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w +wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho +-----END CERTIFICATE----- + +Buypass Class 3 CA 1 +==================== +-----BEGIN CERTIFICATE----- +MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMyBDQSAxMB4XDTA1 +MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh +c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKx +ifZgisRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//zNIqeKNc0 +n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI+MkcVyzwPX6UvCWThOia +AJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2RhzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c +1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0P +AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFPBdy7 +pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27sEzNxZy5p+qksP2bA +EllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2mSlf56oBzKwzqBwKu5HEA6BvtjT5 +htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yCe/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQj +el/wroQk5PMr+4okoyeYZdowdXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 +-----END CERTIFICATE----- + +EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 +========================================================================== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +certSIGN ROOT CA +================ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD +VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa +Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE +CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I +JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH +rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 +ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD +0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 +AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B +Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB +AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 +SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 +x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt +vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz +TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +CNNIC ROOT +========== +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE +ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw +OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD +o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz +VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT +VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or +czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK +y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC +wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S +lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5 +Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM +O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8 +BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2 +G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m +mxE= +-----END CERTIFICATE----- + +ApplicationCA - Japanese Government +=================================== +-----BEGIN CERTIFICATE----- +MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEcMBoGA1UEChMT +SmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRpb25DQTAeFw0wNzEyMTIxNTAw +MDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYTAkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zl +cm5tZW50MRYwFAYDVQQLEw1BcHBsaWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAp23gdE6Hj6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4 +fl+Kf5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55IrmTwcrN +wVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cwFO5cjFW6WY2H/CPek9AE +jP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDihtQWEjdnjDuGWk81quzMKq2edY3rZ+nYVu +nyoKb58DKTCXKB28t89UKU5RMfkntigm/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRU +WssmP3HMlEYNllPqa0jQk/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNV +BAYTAkpQMRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOCseOD +vOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADlqRHZ3ODrs +o2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJhyzjVOGjprIIC8CFqMjSnHH2HZ9g +/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYD +io+nEhEMy/0/ecGc/WLuo89UDNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmW +dupwX3kSa+SjB1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL +rosot4LKGAfmt1t06SAZf7IbiVQ= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G3 +============================================= +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0 +IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy +eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz +NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo +YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT +LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j +K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE +c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C +IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu +dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr +2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9 +cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE +Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s +t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +thawte Primary Root CA - G2 +=========================== +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC +VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu +IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg +Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV +MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG +b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt +IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS +LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5 +8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN +G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K +rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +thawte Primary Root CA - G3 +=========================== +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE +BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2 +aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv +cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w +ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD +VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG +A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At +P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC ++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY +7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW +vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ +KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK +A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC +8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm +er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +GeoTrust Primary Certification Authority - G2 +============================================= +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu +Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1 +OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl +b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG +BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc +KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+ +EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m +ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2 +npaqBA+K +-----END CERTIFICATE----- + +VeriSign Universal Root Certification Authority +=============================================== +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE +BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO +ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk +IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV +UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv +cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj +1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP +MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72 +9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I +AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR +tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G +CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O +a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3 +Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx +Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx +P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P +wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4 +mJO37M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +VeriSign Class 3 Public Primary Certification Authority - G4 +============================================================ +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC +VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3 +b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz +ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU +cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo +b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8 +Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz +rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw +HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u +Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD +A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx +AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +NetLock Arany (Class Gold) Főtanúsítvány +============================================ +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G +A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 +dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB +cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx +MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO +ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv +biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 +c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu +0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw +/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk +H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw +fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 +neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW +qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta +YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna +NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu +dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +Staat der Nederlanden Root CA - G2 +================================== +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE +CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g +Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC +TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l +ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ +5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn +vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj +CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil +e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR +OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI +CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65 +48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi +trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737 +qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB +AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC +ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA +A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz ++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj +f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN +kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk +CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF +URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb +CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h +oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV +IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm +66+KAQ== +-----END CERTIFICATE----- + +CA Disig +======== +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMK +QnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwHhcNMDYw +MzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQswCQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlz +bGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgm +GErENx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnXmjxUizkD +Pw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYDXcDtab86wYqg6I7ZuUUo +hwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhWS8+2rT+MitcE5eN4TPWGqvWP+j1scaMt +ymfraHtuM6kMgiioTGohQBUgDCZbg8KpFhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8w +gfwwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0P +AQH/BAQDAgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cuZGlz +aWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5zay9jYS9jcmwvY2Ff +ZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2svY2EvY3JsL2NhX2Rpc2lnLmNybDAa +BgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEwDQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59t +WDYcPQuBDRIrRhCA/ec8J9B6yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3 +mkkp7M5+cTxqEEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ +CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeBEicTXxChds6K +ezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFNPGO+I++MzVpQuGhU+QqZMxEA +4Z7CRneC9VkGjCFMhwnN5ag= +-----END CERTIFICATE----- + +Juur-SK +======= +-----BEGIN CERTIFICATE----- +MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA +c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw +DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG +SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy +aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf +TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC ++Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw +UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa +Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF +MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD +HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh +AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA +cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr +AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw +cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE +FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G +A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo +ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL +abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678 +IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh +Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2 +yyqcjg== +-----END CERTIFICATE----- + +Hongkong Post Root CA 1 +======================= +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT +DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx +NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n +IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1 +ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr +auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh +qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY +V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV +HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i +h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio +l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei +IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps +T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT +c4afU9hDDl3WY4JxHYB0yvbiAmvZWg== +-----END CERTIFICATE----- + +SecureSign RootCA11 +=================== +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi +SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS +b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw +KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1 +cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL +TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO +wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq +g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP +O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA +bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX +t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh +OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r +bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ +Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01 +y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061 +lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +ACEDICOM Root +============= +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +Verisign Class 1 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ +VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2 +yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa +XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n +0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ +RjXZ+Hxb +-----END CERTIFICATE----- + +Verisign Class 3 Public Primary Certification Authority +======================================================= +-----BEGIN CERTIFICATE----- +MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5 +IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow +XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA +A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94 +f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol +hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky +CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX +bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/ +D/xwzoiQ +-----END CERTIFICATE----- + +Microsec e-Szigno Root CA 2009 +============================== +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER +MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv +c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE +BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt +U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA +fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG +0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA +pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm +1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC +AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf +QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE +FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o +lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX +I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 +yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi +LXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi +=================================================== +-----BEGIN CERTIFICATE----- +MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxpZ2kgQS5TLjE8MDoGA1UEAxMz +ZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3 +MDEwNDExMzI0OFoXDTE3MDEwNDExMzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0 +cm9uaWsgQmlsZ2kgR3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9u +aWsgU2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdUMZTe1RK6UxYC6lhj71vY +8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlTL/jDj/6z/P2douNffb7tC+Bg62nsM+3Y +jfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAI +JjjcJRFHLfO6IxClv7wC90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk +9Ok0oSy1c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/BAQD +AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoEVtstxNulMA0GCSqG +SIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLPqk/CaOv/gKlR6D1id4k9CnU58W5d +F4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwq +D2fK/A+JYZ1lpTzlvBNbCNvj/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4 +Vwpm+Vganf2XKWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq +fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX +-----END CERTIFICATE----- + +GlobalSign Root CA - R3 +======================= +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv +YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh +bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT +aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln +bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt +iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ +0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 +rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl +OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 +xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE +FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 +lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 +EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E +bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 +YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r +kpeDMdmztcpHWD9f +-----END CERTIFICATE----- + +TC TrustCenter Universal CA III +=============================== +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezELMAkGA1UEBhMC +REUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNVBAsTG1RDIFRydXN0Q2VudGVy +IFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAe +Fw0wOTA5MDkwODE1MjdaFw0yOTEyMzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNU +QyBUcnVzdENlbnRlciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0Ex +KDAmBgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF5+cvAqBNLaT6hdqbJYUt +QCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYvDIRlzg9uwliT6CwLOunBjvvya8o84pxO +juT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8vzArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+Eut +CHnNaYlAJ/Uqwa1D7KRTyGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1 +M4BDj5yjdipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBhMB8G +A1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI4jANBgkqhkiG9w0BAQUFAAOCAQEA +g8ev6n9NCjw5sWi+e22JLumzCecYV42FmhfzdkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+ +KGwWaODIl0YgoGhnYIg5IFHYaAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhK +BgePxLcHsU0GDeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV +CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPHLQNjO9Po5KIq +woIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== +-----END CERTIFICATE----- + +Autoridad de Certificacion Firmaprofesional CIF A62634068 +========================================================= +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA +BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 +MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw +QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB +NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD +Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P +B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY +7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH +ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI +plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX +MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX +LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK +bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU +vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH +DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA +bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx +ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx +51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk +R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP +T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f +Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl +osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR +crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR +saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD +KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi +6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +Izenpe.com +========== +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +Chambers of Commerce Root - 2008 +================================ +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy +Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl +ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF +EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl +cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA +XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj +h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/ +ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk +NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g +D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331 +lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ +0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2 +EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI +G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ +BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh +bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh +bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC +CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH +AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1 +wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH +3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU +RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6 +M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1 +YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF +9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK +zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG +nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ +-----END CERTIFICATE----- + +Global Chambersign Root - 2008 +============================== +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD +MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv +bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu +QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx +NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg +Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ +QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf +VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf +XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0 +ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB +/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA +TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M +H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe +Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF +HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB +AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT +BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE +BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm +aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm +aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp +1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0 +dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG +/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6 +ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s +dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg +9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH +foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du +qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr +P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq +c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +Go Daddy Root Certificate Authority - G2 +======================================== +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu +MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G +A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq +9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD ++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd +fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl +NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 +BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac +vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r +5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV +N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 +-----END CERTIFICATE----- + +Starfield Root Certificate Authority - G2 +========================================= +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 +eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw +DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg +VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB +dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv +W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs +bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk +N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf +ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU +JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol +TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx +4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw +F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ +c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +Starfield Services Root Certificate Authority - G2 +================================================== +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s +b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl +IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT +dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg +Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 +h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa +hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP +LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB +rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG +SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP +E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy +xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza +YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 +-----END CERTIFICATE----- + +AffirmTrust Commercial +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw +MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb +DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV +C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 +BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww +MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV +HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG +hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi +qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv +0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh +sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +AffirmTrust Networking +====================== +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw +MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly +bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE +Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI +dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 +/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb +h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV +HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu +UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 +12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 +WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 +/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +AffirmTrust Premium +=================== +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS +BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy +OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy +dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn +BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV +5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs ++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd +GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R +p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI +S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 +6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 +/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo ++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv +MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC +6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S +L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK ++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV +BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg +IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 +g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb +zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== +-----END CERTIFICATE----- + +AffirmTrust Premium ECC +======================= +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV +BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx +MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U +cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ +N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW +BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X +57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM +eQ== +-----END CERTIFICATE----- + +Certum Trusted Network CA +========================= +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK +ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy +MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU +ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC +l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J +J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 +fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 +cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB +Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw +DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj +jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 +mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj +Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +Certinomis - Autorité Racine +============================= +-----BEGIN CERTIFICATE----- +MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK +Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg +LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG +A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw +JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa +wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly +Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw +2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N +jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q +c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC +lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb +xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g +530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna +4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ +KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x +WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva +R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40 +nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B +CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv +JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE +qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b +WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE +wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/ +vgt2Fl43N+bYdJeimUV5 +-----END CERTIFICATE----- + +Root CA Generalitat Valenciana +============================== +-----BEGIN CERTIFICATE----- +MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE +ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290 +IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3 +WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE +CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2 +F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B +ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ +D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte +JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB +AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n +dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB +ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl +AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA +YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy +AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA +aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt +AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA +YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu +AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA +OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0 +dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV +BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G +A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S +b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh +TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz +Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63 +NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH +iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt ++GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= +-----END CERTIFICATE----- + +A-Trust-nQual-03 +================ +-----BEGIN CERTIFICATE----- +MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJBVDFIMEYGA1UE +Cgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVy +a2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5R +dWFsLTAzMB4XDTA1MDgxNzIyMDAwMFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgw +RgYDVQQKDD9BLVRydXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0 +ZW52ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMMEEEtVHJ1 +c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtPWFuA/OQO8BBC4SA +zewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUjlUC5B3ilJfYKvUWG6Nm9wASOhURh73+n +yfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZznF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPE +SU7l0+m0iKsMrmKS1GWH2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4 +iHQF63n1k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs2e3V +cuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0OBAoECERqlWdV +eRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAVdRU0VlIXLOThaq/Yy/kgM40 +ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fGKOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmr +sQd7TZjTXLDR8KdCoLXEjq/+8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZd +JXDRZslo+S4RFGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS +mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmEDNuxUCAKGkq6 +ahq97BvIxYSazQ== +-----END CERTIFICATE----- + +TWCA Root Certification Authority +================================= +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ +VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG +EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB +IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx +QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC +oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP +4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r +y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG +9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC +mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW +QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY +T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny +Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +Security Communication RootCA2 +============================== +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh +dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC +SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy +aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ ++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R +3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV +spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K +EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 +QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB +CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj +u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk +3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q +tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 +mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +EC-ACC +====== +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE +BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w +ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD +VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE +CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT +BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7 +MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt +SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl +Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh +cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK +w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT +ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4 +HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a +E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw +0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD +VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0 +Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l +dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ +lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa +Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe +l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2 +E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D +5EI= +-----END CERTIFICATE----- + +Hellenic Academic and Research Institutions RootCA 2011 +======================================================= +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT +O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y +aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT +AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z +IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo +IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI +1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa +71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u +8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH +3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8 +MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu +b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt +XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD +/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N +7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +Actalis Authentication Root CA +============================== +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM +BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE +AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky +MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz +IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ +wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa +by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 +zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f +YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 +oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l +EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 +hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 +EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 +jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY +iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI +WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 +JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx +K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ +Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC +4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo +2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz +lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem +OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 +vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +Trustis FPS Root CA +=================== +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG +EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290 +IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV +BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ +RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk +H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa +cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt +o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA +AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd +BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c +GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC +yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P +8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV +l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl +iB6XzCGcKQENZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +StartCom Certification Authority +================================ +-----BEGIN CERTIFICATE----- +MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu +ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0 +NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk +LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg +U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw +ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y +o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/ +Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d +eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt +2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z +6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ +osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/ +untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc +UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT +37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ +Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0 +dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu +c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv +bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0 +aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t +L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5 +fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm +N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN +Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T +tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX +e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA +2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs +HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE +JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib +D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8= +-----END CERTIFICATE----- + +StartCom Certification Authority G2 +=================================== +-----BEGIN CERTIFICATE----- +MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN +U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE +ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O +o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG +4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi +Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul +Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs +O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H +vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L +nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS +FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa +z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ +KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K +2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk +J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+ +JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG +/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc +nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld +blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc +l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm +7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm +obp573PYtlNXLfbQ4ddI +-----END CERTIFICATE----- + +Buypass Class 2 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X +DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 +g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn +9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b +/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU +CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff +awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI +zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn +Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX +Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs +M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI +osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S +aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd +DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD +LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 +oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC +wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS +CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN +rJgWVqA= +-----END CERTIFICATE----- + +Buypass Class 3 Root CA +======================= +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU +QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X +DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 +eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH +sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR +5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh +7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ +ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH +2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV +/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ +RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA +Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq +j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD +VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF +AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G +uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG +Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 +ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 +KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz +6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug +UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe +eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi +Cp/HuZc= +-----END CERTIFICATE----- + +TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı +====================================================== +-----BEGIN CERTIFICATE----- +MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP +MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg +QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X +DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl +a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN +BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp +bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N +YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv +KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya +KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT +rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC +AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s +Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I +aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO +Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb +BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK +poRq0Tl9 +-----END CERTIFICATE----- + +T-TeleSec GlobalRoot Class 3 +============================ +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM +IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU +cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx +MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz +dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD +ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK +9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU +NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF +iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W +0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr +AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb +fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT +ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h +P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== +-----END CERTIFICATE----- + +EE Certification Centre Root CA +=============================== +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG +EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy +dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw +MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB +UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy +ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM +TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2 +rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw +93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN +P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T +AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ +MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF +BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj +xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM +lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU +3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM +dcGWxZ0= +-----END CERTIFICATE----- diff --git a/AvocadoEdition/plugin/sns/facebook/tests/bootstrap.php b/AvocadoEdition/plugin/sns/facebook/tests/bootstrap.php new file mode 100644 index 0000000..e32b9f8 --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/tests/bootstrap.php @@ -0,0 +1,5 @@ +<?php + +$base = realpath(dirname(__FILE__) . '/..'); +require "$base/src/base_facebook.php"; +require "$base/src/facebook.php"; diff --git a/AvocadoEdition/plugin/sns/facebook/tests/tests.php b/AvocadoEdition/plugin/sns/facebook/tests/tests.php new file mode 100644 index 0000000..d261cce --- /dev/null +++ b/AvocadoEdition/plugin/sns/facebook/tests/tests.php @@ -0,0 +1,2034 @@ +<?php +/** + * Copyright 2011 Facebook, 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. + */ + +class PHPSDKTestCase extends PHPUnit_Framework_TestCase { + const APP_ID = '117743971608120'; + const SECRET = '9c8ea2071859659bea1246d33a9207cf'; + + const MIGRATED_APP_ID = '174236045938435'; + const MIGRATED_SECRET = '0073dce2d95c4a5c2922d1827ea0cca6'; + + const TEST_USER = 499834690; + const TEST_USER_2 = 499835484; + + private static $kExpiredAccessToken = 'AAABrFmeaJjgBAIshbq5ZBqZBICsmveZCZBi6O4w9HSTkFI73VMtmkL9jLuWsZBZC9QMHvJFtSulZAqonZBRIByzGooCZC8DWr0t1M4BL9FARdQwPWPnIqCiFQ'; + + private static function kValidSignedRequest($id = self::TEST_USER, $oauth_token = null) { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + return $facebook->publicMakeSignedRequest( + array( + 'user_id' => $id, + 'oauth_token' => $oauth_token + ) + ); + } + + private static function kNonTosedSignedRequest() { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + return $facebook->publicMakeSignedRequest(array()); + } + + private static function kSignedRequestWithEmptyValue() { + return ''; + } + + private static function kSignedRequestWithBogusSignature() { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => 'bogus', + )); + return $facebook->publicMakeSignedRequest( + array( + 'algorithm' => 'HMAC-SHA256', + ) + ); + } + + private static function kSignedRequestWithWrongAlgo() { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $data['algorithm'] = 'foo'; + $json = json_encode($data); + $b64 = $facebook->publicBase64UrlEncode($json); + $raw_sig = hash_hmac('sha256', $b64, self::SECRET, $raw = true); + $sig = $facebook->publicBase64UrlEncode($raw_sig); + return $sig.'.'.$b64; + } + + public function testConstructor() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $this->assertEquals($facebook->getAppId(), self::APP_ID, + 'Expect the App ID to be set.'); + $this->assertEquals($facebook->getAppSecret(), self::SECRET, + 'Expect the API secret to be set.'); + } + + public function testConstructorWithFileUpload() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'fileUpload' => true, + )); + $this->assertEquals($facebook->getAppId(), self::APP_ID, + 'Expect the App ID to be set.'); + $this->assertEquals($facebook->getAppSecret(), self::SECRET, + 'Expect the API secret to be set.'); + $this->assertTrue($facebook->getFileUploadSupport(), + 'Expect file upload support to be on.'); + // alias (depricated) for getFileUploadSupport -- test until removed + $this->assertTrue($facebook->useFileUploadSupport(), + 'Expect file upload support to be on.'); + } + + public function testSetAppId() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $facebook->setAppId('dummy'); + $this->assertEquals($facebook->getAppId(), 'dummy', + 'Expect the App ID to be dummy.'); + } + + public function testSetAPISecret() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $facebook->setApiSecret('dummy'); + $this->assertEquals($facebook->getApiSecret(), 'dummy', + 'Expect the API secret to be dummy.'); + } + + public function testSetAPPSecret() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $facebook->setAppSecret('dummy'); + $this->assertEquals($facebook->getAppSecret(), 'dummy', + 'Expect the API secret to be dummy.'); + } + + public function testSetAccessToken() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setAccessToken('saltydog'); + $this->assertEquals($facebook->getAccessToken(), 'saltydog', + 'Expect installed access token to remain \'saltydog\''); + } + + public function testSetFileUploadSupport() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $this->assertFalse($facebook->getFileUploadSupport(), + 'Expect file upload support to be off.'); + // alias for getFileUploadSupport (depricated), testing until removed + $this->assertFalse($facebook->useFileUploadSupport(), + 'Expect file upload support to be off.'); + $facebook->setFileUploadSupport(true); + $this->assertTrue($facebook->getFileUploadSupport(), + 'Expect file upload support to be on.'); + // alias for getFileUploadSupport (depricated), testing until removed + $this->assertTrue($facebook->useFileUploadSupport(), + 'Expect file upload support to be on.'); + } + + public function testGetCurrentURL() { + $facebook = new FBGetCurrentURLFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + // fake the HPHP $_SERVER globals + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php?one=one&two=two&three=three'; + $current_url = $facebook->publicGetCurrentUrl(); + $this->assertEquals( + 'http://www.test.com/unit-tests.php?one=one&two=two&three=three', + $current_url, + 'getCurrentUrl function is changing the current URL'); + + // ensure structure of valueless GET params is retained (sometimes + // an = sign was present, and sometimes it was not) + // first test when equal signs are present + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php?one=&two=&three='; + $current_url = $facebook->publicGetCurrentUrl(); + $this->assertEquals( + 'http://www.test.com/unit-tests.php?one=&two=&three=', + $current_url, + 'getCurrentUrl function is changing the current URL'); + + // now confirm that + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php?one&two&three'; + $current_url = $facebook->publicGetCurrentUrl(); + $this->assertEquals( + 'http://www.test.com/unit-tests.php?one&two&three', + $current_url, + 'getCurrentUrl function is changing the current URL'); + } + + public function testGetLoginURL() { + $facebook = new Facebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + // fake the HPHP $_SERVER globals + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php'; + $login_url = parse_url($facebook->getLoginUrl()); + $this->assertEquals($login_url['scheme'], 'https'); + $this->assertEquals($login_url['host'], 'www.facebook.com'); + $this->assertEquals($login_url['path'], '/dialog/oauth'); + $expected_login_params = + array('client_id' => self::APP_ID, + 'redirect_uri' => 'http://www.test.com/unit-tests.php'); + + $query_map = array(); + parse_str($login_url['query'], $query_map); + $this->assertIsSubset($expected_login_params, $query_map); + // we don't know what the state is, but we know it's an md5 and should + // be 32 characters long. + $this->assertEquals(strlen($query_map['state']), $num_characters = 32); + } + + public function testGetLoginURLWithExtraParams() { + $facebook = new Facebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + // fake the HPHP $_SERVER globals + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php'; + $extra_params = array('scope' => 'email, sms', + 'nonsense' => 'nonsense'); + $login_url = parse_url($facebook->getLoginUrl($extra_params)); + $this->assertEquals($login_url['scheme'], 'https'); + $this->assertEquals($login_url['host'], 'www.facebook.com'); + $this->assertEquals($login_url['path'], '/dialog/oauth'); + $expected_login_params = + array_merge( + array('client_id' => self::APP_ID, + 'redirect_uri' => 'http://www.test.com/unit-tests.php'), + $extra_params); + $query_map = array(); + parse_str($login_url['query'], $query_map); + $this->assertIsSubset($expected_login_params, $query_map); + // we don't know what the state is, but we know it's an md5 and should + // be 32 characters long. + $this->assertEquals(strlen($query_map['state']), $num_characters = 32); + } + + public function testGetLoginURLWithScopeParamsAsArray() { + $facebook = new Facebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + // fake the HPHP $_SERVER globals + $_SERVER['HTTP_HOST'] = 'www.test.com'; + $_SERVER['REQUEST_URI'] = '/unit-tests.php'; + $scope_params_as_array = array('email','sms','read_stream'); + $extra_params = array('scope' => $scope_params_as_array, + 'nonsense' => 'nonsense'); + $login_url = parse_url($facebook->getLoginUrl($extra_params)); + $this->assertEquals($login_url['scheme'], 'https'); + $this->assertEquals($login_url['host'], 'www.facebook.com'); + $this->assertEquals($login_url['path'], '/dialog/oauth'); + // expect api to flatten array params to comma separated list + // should do the same here before asserting to make sure API is behaving + // correctly; + $extra_params['scope'] = implode(',', $scope_params_as_array); + $expected_login_params = + array_merge( + array('client_id' => self::APP_ID, + 'redirect_uri' => 'http://www.test.com/unit-tests.php'), + $extra_params); + $query_map = array(); + parse_str($login_url['query'], $query_map); + $this->assertIsSubset($expected_login_params, $query_map); + // we don't know what the state is, but we know it's an md5 and should + // be 32 characters long. + $this->assertEquals(strlen($query_map['state']), $num_characters = 32); + } + + public function testGetCodeWithValidCSRFState() { + $facebook = new FBCode(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setCSRFStateToken(); + $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); + $_REQUEST['state'] = $facebook->getCSRFStateToken(); + $this->assertEquals($code, + $facebook->publicGetCode(), + 'Expect code to be pulled from $_REQUEST[\'code\']'); + } + + public function testGetCodeWithInvalidCSRFState() { + $facebook = new FBCode(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setCSRFStateToken(); + $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); + $_REQUEST['state'] = $facebook->getCSRFStateToken().'forgery!!!'; + $this->assertFalse($facebook->publicGetCode(), + 'Expect getCode to fail, CSRF state should not match.'); + } + + public function testGetCodeWithMissingCSRFState() { + $facebook = new FBCode(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); + // intentionally don't set CSRF token at all + $this->assertFalse($facebook->publicGetCode(), + 'Expect getCode to fail, CSRF state not sent back.'); + } + + public function testGetUserFromSignedRequest() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $_REQUEST['signed_request'] = self::kValidSignedRequest(); + $this->assertEquals('499834690', $facebook->getUser(), + 'Failed to get user ID from a valid signed request.'); + } + + public function testSignedRequestRewrite(){ + $facebook = new FBRewrite(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER, 'Hello sweetie'); + + $this->assertEquals(self::TEST_USER, $facebook->getUser(), + 'Failed to get user ID from a valid signed request.'); + + $this->assertEquals('Hello sweetie', $facebook->getAccessToken(), + 'Failed to get access token from signed request'); + + $facebook->uncache(); + + $_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER_2, 'spoilers'); + + $this->assertEquals(self::TEST_USER_2, $facebook->getUser(), + 'Failed to get user ID from a valid signed request.'); + + $_REQUEST['signed_request'] = null; + $facebook ->uncacheSignedRequest(); + + $this->assertNotEquals('Hello sweetie', $facebook->getAccessToken(), + 'Failed to clear access token'); + } + + public function testGetSignedRequestFromCookie() { + $facebook = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $_COOKIE[$facebook->publicGetSignedRequestCookieName()] = + self::kValidSignedRequest(); + $this->assertNotNull($facebook->publicGetSignedRequest()); + $this->assertEquals('499834690', $facebook->getUser(), + 'Failed to get user ID from a valid signed request.'); + } + + public function testGetSignedRequestWithIncorrectSignature() { + $facebook = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $_COOKIE[$facebook->publicGetSignedRequestCookieName()] = + self::kSignedRequestWithBogusSignature(); + $this->assertNull($facebook->publicGetSignedRequest()); + } + + public function testNonUserAccessToken() { + $facebook = new FBAccessToken(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + // no cookies, and no request params, so no user or code, + // so no user access token (even with cookie support) + $this->assertEquals($facebook->publicGetApplicationAccessToken(), + $facebook->getAccessToken(), + 'Access token should be that for logged out users.'); + } + + public function testMissingMetadataCookie() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $this->assertEmpty($fb->publicGetMetadataCookie()); + } + + public function testEmptyMetadataCookie() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $_COOKIE[$fb->publicGetMetadataCookieName()] = ''; + $this->assertEmpty($fb->publicGetMetadataCookie()); + } + + public function testMetadataCookie() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = 'foo'; + $val = '42'; + $_COOKIE[$fb->publicGetMetadataCookieName()] = "$key=$val"; + $this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie()); + } + + public function testQuotedMetadataCookie() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = 'foo'; + $val = '42'; + $_COOKIE[$fb->publicGetMetadataCookieName()] = "\"$key=$val\""; + $this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie()); + } + + public function testAPIForLoggedOutUsers() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $response = $facebook->api(array( + 'method' => 'fql.query', + 'query' => 'SELECT name FROM user WHERE uid=4', + )); + $this->assertEquals(count($response), 1, + 'Expect one row back.'); + $this->assertEquals($response[0]['name'], 'Mark Zuckerberg', + 'Expect the name back.'); + } + + public function testAPIWithBogusAccessToken() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setAccessToken('this-is-not-really-an-access-token'); + // if we don't set an access token and there's no way to + // get one, then the FQL query below works beautifully, handing + // over Zuck's public data. But if you specify a bogus access + // token as I have right here, then the FQL query should fail. + // We could return just Zuck's public data, but that wouldn't + // advertise the issue that the access token is at worst broken + // and at best expired. + try { + $response = $facebook->api(array( + 'method' => 'fql.query', + 'query' => 'SELECT name FROM profile WHERE id=4', + )); + $this->fail('Should not get here.'); + } catch(FacebookApiException $e) { + $result = $e->getResult(); + $this->assertTrue(is_array($result), 'expect a result object'); + $this->assertEquals('190', $result['error_code'], 'expect code'); + } + } + + public function testAPIGraphPublicData() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $response = $facebook->api('/jerry'); + $this->assertEquals( + $response['id'], '214707', 'should get expected id.'); + } + + public function testGraphAPIWithBogusAccessToken() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setAccessToken('this-is-not-really-an-access-token'); + try { + $response = $facebook->api('/me'); + $this->fail('Should not get here.'); + } catch(FacebookApiException $e) { + // means the server got the access token and didn't like it + $msg = 'OAuthException: Invalid OAuth access token.'; + $this->assertEquals($msg, (string) $e, + 'Expect the invalid OAuth token message.'); + } + } + + public function testGraphAPIWithExpiredAccessToken() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $facebook->setAccessToken(self::$kExpiredAccessToken); + try { + $response = $facebook->api('/me'); + $this->fail('Should not get here.'); + } catch(FacebookApiException $e) { + // means the server got the access token and didn't like it + $error_msg_start = 'OAuthException: Error validating access token:'; + $this->assertTrue(strpos((string) $e, $error_msg_start) === 0, + 'Expect the token validation error message.'); + } + } + + public function testGraphAPIOAuthSpecError() { + $facebook = new TransientFacebook(array( + 'appId' => self::MIGRATED_APP_ID, + 'secret' => self::MIGRATED_SECRET, + )); + + try { + $response = $facebook->api('/me', array( + 'client_id' => self::MIGRATED_APP_ID)); + + $this->fail('Should not get here.'); + } catch(FacebookApiException $e) { + // means the server got the access token + $msg = 'invalid_request: An active access token must be used '. + 'to query information about the current user.'; + $this->assertEquals($msg, (string) $e, + 'Expect the invalid session message.'); + } + } + + public function testGraphAPIMethodOAuthSpecError() { + $facebook = new TransientFacebook(array( + 'appId' => self::MIGRATED_APP_ID, + 'secret' => self::MIGRATED_SECRET, + )); + + try { + $response = $facebook->api('/daaku.shah', 'DELETE', array( + 'client_id' => self::MIGRATED_APP_ID)); + $this->fail('Should not get here.'); + } catch(FacebookApiException $e) { + $this->assertEquals(strpos($e, 'invalid_request'), 0); + } + } + + public function testCurlFailure() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + if (!defined('CURLOPT_TIMEOUT_MS')) { + // can't test it if we don't have millisecond timeouts + return; + } + + $exception = null; + try { + // we dont expect facebook will ever return in 1ms + Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS] = 50; + $facebook->api('/naitik'); + } catch(FacebookApiException $e) { + $exception = $e; + } + unset(Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS]); + if (!$exception) { + $this->fail('no exception was thrown on timeout.'); + } + + $code = $exception->getCode(); + if ($code != CURLE_OPERATION_TIMEOUTED && $code != CURLE_COULDNT_CONNECT) { + $this->fail("Expected curl error code 7 or 28 but got: $code"); + } + $this->assertEquals('CurlException', $exception->getType(), 'expect type'); + } + + public function testGraphAPIWithOnlyParams() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + + $response = $facebook->api('/jerry'); + $this->assertTrue(isset($response['id']), + 'User ID should be public.'); + $this->assertTrue(isset($response['name']), + 'User\'s name should be public.'); + $this->assertTrue(isset($response['first_name']), + 'User\'s first name should be public.'); + $this->assertTrue(isset($response['last_name']), + 'User\'s last name should be public.'); + $this->assertFalse(isset($response['work']), + 'User\'s work history should only be available with '. + 'a valid access token.'); + $this->assertFalse(isset($response['education']), + 'User\'s education history should only be '. + 'available with a valid access token.'); + $this->assertFalse(isset($response['verified']), + 'User\'s verification status should only be '. + 'available with a valid access token.'); + } + + public function testLoginURLDefaults() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), + 'Expect the current url to exist.'); + } + + public function testLoginURLDefaultsDropStateQueryParam() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples?state=xx42xx'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1, + 'Expect the current url to exist.'); + $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), + 'Expect the session param to be dropped.'); + } + + public function testLoginURLDefaultsDropCodeQueryParam() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples?code=xx42xx'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1, + 'Expect the current url to exist.'); + $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), + 'Expect the session param to be dropped.'); + } + + public function testLoginURLDefaultsDropSignedRequestParamButNotOthers() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = + '/examples?signed_request=xx42xx&do_not_drop=xx43xx'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), + 'Expect the session param to be dropped.'); + $this->assertTrue(strpos($facebook->getLoginUrl(), 'xx43xx') > -1, + 'Expect the do_not_drop param to exist.'); + } + + public function testLoginURLCustomNext() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $next = 'http://fbrell.com/custom'; + $loginUrl = $facebook->getLoginUrl(array( + 'redirect_uri' => $next, + 'cancel_url' => $next + )); + $currentEncodedUrl = rawurlencode('http://fbrell.com/examples'); + $expectedEncodedUrl = rawurlencode($next); + $this->assertNotNull(strpos($loginUrl, $expectedEncodedUrl), + 'Expect the custom url to exist.'); + $this->assertFalse(strpos($loginUrl, $currentEncodedUrl), + 'Expect the current url to not exist.'); + } + + public function testLogoutURLDefaults() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertNotNull(strpos($facebook->getLogoutUrl(), $encodedUrl), + 'Expect the current url to exist.'); + $this->assertFalse(strpos($facebook->getLogoutUrl(), self::SECRET)); + } + + public function testLoginStatusURLDefaults() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('http://fbrell.com/examples'); + $this->assertNotNull(strpos($facebook->getLoginStatusUrl(), $encodedUrl), + 'Expect the current url to exist.'); + } + + public function testLoginStatusURLCustom() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl1 = rawurlencode('http://fbrell.com/examples'); + $okUrl = 'http://fbrell.com/here1'; + $encodedUrl2 = rawurlencode($okUrl); + $loginStatusUrl = $facebook->getLoginStatusUrl(array( + 'ok_session' => $okUrl, + )); + $this->assertNotNull(strpos($loginStatusUrl, $encodedUrl1), + 'Expect the current url to exist.'); + $this->assertNotNull(strpos($loginStatusUrl, $encodedUrl2), + 'Expect the custom url to exist.'); + } + + public function testNonDefaultPort() { + $_SERVER['HTTP_HOST'] = 'fbrell.com:8080'; + $_SERVER['REQUEST_URI'] = '/examples'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('http://fbrell.com:8080/examples'); + $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), + 'Expect the current url to exist.'); + } + + public function testSecureCurrentUrl() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $_SERVER['REQUEST_URI'] = '/examples'; + $_SERVER['HTTPS'] = 'on'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('https://fbrell.com/examples'); + $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), + 'Expect the current url to exist.'); + } + + public function testSecureCurrentUrlWithNonDefaultPort() { + $_SERVER['HTTP_HOST'] = 'fbrell.com:8080'; + $_SERVER['REQUEST_URI'] = '/examples'; + $_SERVER['HTTPS'] = 'on'; + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $encodedUrl = rawurlencode('https://fbrell.com:8080/examples'); + $this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), + 'Expect the current url to exist.'); + } + + public function testBase64UrlEncode() { + $input = 'Facebook rocks'; + $output = 'RmFjZWJvb2sgcm9ja3M'; + + $this->assertEquals(FBPublic::publicBase64UrlDecode($output), $input); + } + + public function testSignedToken() { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $payload = $facebook->publicParseSignedRequest(self::kValidSignedRequest()); + $this->assertNotNull($payload, 'Expected token to parse'); + $this->assertEquals($facebook->getSignedRequest(), null); + $_REQUEST['signed_request'] = self::kValidSignedRequest(); + $this->assertEquals($facebook->getSignedRequest(), $payload); + } + + public function testNonTossedSignedtoken() { + $facebook = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $payload = $facebook->publicParseSignedRequest( + self::kNonTosedSignedRequest()); + $this->assertNotNull($payload, 'Expected token to parse'); + $this->assertNull($facebook->getSignedRequest()); + $_REQUEST['signed_request'] = self::kNonTosedSignedRequest(); + $sr = $facebook->getSignedRequest(); + $this->assertTrue(isset($sr['algorithm'])); + } + + public function testSignedRequestWithEmptyValue() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $_REQUEST['signed_request'] = self::kSignedRequestWithEmptyValue(); + $this->assertNull($fb->getSignedRequest()); + $_COOKIE[$fb->publicGetSignedRequestCookieName()] = + self::kSignedRequestWithEmptyValue(); + $this->assertNull($fb->getSignedRequest()); + } + + public function testSignedRequestWithWrongAlgo() { + $fb = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $payload = $fb->publicParseSignedRequest( + self::kSignedRequestWithWrongAlgo()); + $this->assertNull($payload, 'Expected nothing back.'); + } + + public function testMakeAndParse() { + $fb = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $data = array('foo' => 42); + $sr = $fb->publicMakeSignedRequest($data); + $decoded = $fb->publicParseSignedRequest($sr); + $this->assertEquals($data['foo'], $decoded['foo']); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testMakeSignedRequestExpectsArray() { + $fb = new FBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $sr = $fb->publicMakeSignedRequest(''); + } + + public function testBundledCACert() { + $facebook = new TransientFacebook(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + // use the bundled cert from the start + Facebook::$CURL_OPTS[CURLOPT_CAINFO] = + dirname(__FILE__) . '/../src/fb_ca_chain_bundle.crt'; + $response = $facebook->api('/naitik'); + + unset(Facebook::$CURL_OPTS[CURLOPT_CAINFO]); + $this->assertEquals( + $response['id'], '5526183', 'should get expected id.'); + } + + public function testVideoUpload() { + $facebook = new FBRecordURL(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + $facebook->api(array('method' => 'video.upload')); + $this->assertContains('//api-video.', $facebook->getRequestedURL(), + 'video.upload should go against api-video'); + } + + public function testVideoUploadGraph() { + $facebook = new FBRecordURL(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + $facebook->api('/me/videos', 'POST'); + $this->assertContains('//graph-video.', $facebook->getRequestedURL(), + '/me/videos should go against graph-video'); + } + + public function testGetUserAndAccessTokenFromSession() { + $facebook = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + $facebook->publicSetPersistentData('access_token', + self::$kExpiredAccessToken); + $facebook->publicSetPersistentData('user_id', 12345); + $this->assertEquals(self::$kExpiredAccessToken, + $facebook->getAccessToken(), + 'Get access token from persistent store.'); + $this->assertEquals('12345', + $facebook->getUser(), + 'Get user id from persistent store.'); + } + + public function testGetUserAndAccessTokenFromSignedRequestNotSession() { + $facebook = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + $_REQUEST['signed_request'] = self::kValidSignedRequest(); + $facebook->publicSetPersistentData('user_id', 41572); + $facebook->publicSetPersistentData('access_token', + self::$kExpiredAccessToken); + $this->assertNotEquals('41572', $facebook->getUser(), + 'Got user from session instead of signed request.'); + $this->assertEquals('499834690', $facebook->getUser(), + 'Failed to get correct user ID from signed request.'); + $this->assertNotEquals( + self::$kExpiredAccessToken, + $facebook->getAccessToken(), + 'Got access token from session instead of signed request.'); + $this->assertNotEmpty( + $facebook->getAccessToken(), + 'Failed to extract an access token from the signed request.'); + } + + public function testGetUserWithoutCodeOrSignedRequestOrSession() { + $facebook = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + + // deliberately leave $_REQUEST and _$SESSION empty + $this->assertEmpty($_REQUEST, + 'GET, POST, and COOKIE params exist even though '. + 'they should. Test cannot succeed unless all of '. + '$_REQUEST is empty.'); + $this->assertEmpty($_SESSION, + 'Session is carrying state and should not be.'); + $this->assertEmpty($facebook->getUser(), + 'Got a user id, even without a signed request, '. + 'access token, or session variable.'); + $this->assertEmpty($_SESSION, + 'Session superglobal incorrectly populated by getUser.'); + } + + public function testGetAccessTokenUsingCodeInJsSdkCookie() { + $code = 'code1'; + $access_token = 'at1'; + $methods_to_stub = array('getSignedRequest', 'getAccessTokenFromCode'); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getSignedRequest') + ->will($this->returnValue(array('code' => $code))); + $stub + ->expects($this->once()) + ->method('getAccessTokenFromCode') + ->will($this->returnValueMap(array(array($code, '', $access_token)))); + $this->assertEquals($stub->getAccessToken(), $access_token); + } + + public function testSignedRequestWithoutAuthClearsData() { + $methods_to_stub = array('getSignedRequest', 'clearAllPersistentData'); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getSignedRequest') + ->will($this->returnValue(array('foo' => 1))); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); + } + + public function testInvalidCodeInSignedRequestWillClearData() { + $code = 'code1'; + $methods_to_stub = array( + 'getSignedRequest', + 'getAccessTokenFromCode', + 'clearAllPersistentData', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getSignedRequest') + ->will($this->returnValue(array('code' => $code))); + $stub + ->expects($this->once()) + ->method('getAccessTokenFromCode') + ->will($this->returnValue(null)); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); + } + + public function testInvalidCodeWillClearData() { + $code = 'code1'; + $methods_to_stub = array( + 'getCode', + 'getAccessTokenFromCode', + 'clearAllPersistentData', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getCode') + ->will($this->returnValue($code)); + $stub + ->expects($this->once()) + ->method('getAccessTokenFromCode') + ->will($this->returnValue(null)); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); + } + + public function testValidCodeToToken() { + $code = 'code1'; + $access_token = 'at1'; + $methods_to_stub = array( + 'getSignedRequest', + 'getCode', + 'getAccessTokenFromCode', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getCode') + ->will($this->returnValue($code)); + $stub + ->expects($this->once()) + ->method('getAccessTokenFromCode') + ->will($this->returnValueMap(array(array($code, null, $access_token)))); + $this->assertEquals($stub->getAccessToken(), $access_token); + } + + public function testSignedRequestWithoutAuthClearsDataInAvailData() { + $methods_to_stub = array('getSignedRequest', 'clearAllPersistentData'); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getSignedRequest') + ->will($this->returnValue(array('foo' => 1))); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(0, $stub->getUser()); + } + + public function testFailedToGetUserFromAccessTokenClearsData() { + $methods_to_stub = array( + 'getAccessToken', + 'getUserFromAccessToken', + 'clearAllPersistentData', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getAccessToken') + ->will($this->returnValue('at1')); + $stub + ->expects($this->once()) + ->method('getUserFromAccessToken'); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(0, $stub->getUser()); + } + + public function testUserFromAccessTokenIsStored() { + $methods_to_stub = array( + 'getAccessToken', + 'getUserFromAccessToken', + 'setPersistentData', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $user = 42; + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getAccessToken') + ->will($this->returnValue('at1')); + $stub + ->expects($this->once()) + ->method('getUserFromAccessToken') + ->will($this->returnValue($user)); + $stub + ->expects($this->once()) + ->method('setPersistentData'); + $this->assertEquals($user, $stub->getUser()); + } + + public function testUserFromAccessTokenPullsID() { + $methods_to_stub = array( + 'getAccessToken', + 'api', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $user = 42; + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getAccessToken') + ->will($this->returnValue('at1')); + $stub + ->expects($this->once()) + ->method('api') + ->will($this->returnValue(array('id' => $user))); + $this->assertEquals($user, $stub->getUser()); + } + + public function testUserFromAccessTokenResetsOnApiException() { + $methods_to_stub = array( + 'getAccessToken', + 'clearAllPersistentData', + 'api', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('getAccessToken') + ->will($this->returnValue('at1')); + $stub + ->expects($this->once()) + ->method('api') + ->will($this->throwException(new FacebookApiException(false))); + $stub + ->expects($this->once()) + ->method('clearAllPersistentData'); + $this->assertEquals(0, $stub->getUser()); + } + + public function testEmptyCodeReturnsFalse() { + $fb = new FBPublicGetAccessTokenFromCode(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $this->assertFalse($fb->publicGetAccessTokenFromCode('')); + $this->assertFalse($fb->publicGetAccessTokenFromCode(null)); + $this->assertFalse($fb->publicGetAccessTokenFromCode(false)); + } + + public function testNullRedirectURIUsesCurrentURL() { + $methods_to_stub = array( + '_oauthRequest', + 'getCurrentUrl', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $access_token = 'at1'; + $stub = $this->getMock( + 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue("access_token=$access_token")); + $stub + ->expects($this->once()) + ->method('getCurrentUrl'); + $this->assertEquals( + $access_token, $stub->publicGetAccessTokenFromCode('c')); + } + + public function testNullRedirectURIAllowsEmptyStringForCookie() { + $methods_to_stub = array( + '_oauthRequest', + 'getCurrentUrl', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $access_token = 'at1'; + $stub = $this->getMock( + 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue("access_token=$access_token")); + $stub + ->expects($this->never()) + ->method('getCurrentUrl'); + $this->assertEquals( + $access_token, $stub->publicGetAccessTokenFromCode('c', '')); + } + + public function testAPIExceptionDuringCodeExchangeIsIgnored() { + $methods_to_stub = array( + '_oauthRequest', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->throwException(new FacebookApiException(false))); + $this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); + } + + public function testEmptyResponseInCodeExchangeIsIgnored() { + $methods_to_stub = array( + '_oauthRequest', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue('')); + $this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); + } + + public function testExistingStateRestoredInConstructor() { + $fb = new FBPublicState(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $this->assertEquals(FBPublicState::STATE, $fb->publicGetState()); + } + + public function testMissingAccessTokenInCodeExchangeIsIgnored() { + $methods_to_stub = array( + '_oauthRequest', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue('foo=1')); + $this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); + } + + public function testExceptionConstructorWithErrorCode() { + $code = 404; + $e = new FacebookApiException(array('error_code' => $code)); + $this->assertEquals($code, $e->getCode()); + } + + // this happens often despite the fact that it is useless + public function testExceptionTypeFalse() { + $e = new FacebookApiException(false); + $this->assertEquals('Exception', $e->getType()); + } + + public function testExceptionTypeMixedDraft00() { + $e = new FacebookApiException(array('error' => array('message' => 'foo'))); + $this->assertEquals('Exception', $e->getType()); + } + + public function testExceptionTypeDraft00() { + $error = 'foo'; + $e = new FacebookApiException( + array('error' => array('type' => $error, 'message' => 'hello world'))); + $this->assertEquals($error, $e->getType()); + } + + public function testExceptionTypeDraft10() { + $error = 'foo'; + $e = new FacebookApiException(array('error' => $error)); + $this->assertEquals($error, $e->getType()); + } + + public function testExceptionTypeDefault() { + $e = new FacebookApiException(array('error' => false)); + $this->assertEquals('Exception', $e->getType()); + } + + public function testExceptionToString() { + $e = new FacebookApiException(array( + 'error_code' => 1, + 'error_description' => 'foo', + )); + $this->assertEquals('Exception: 1: foo', (string) $e); + } + + public function testDestroyClearsCookie() { + $fb = new FBPublicCookie(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $_COOKIE[$fb->publicGetSignedRequestCookieName()] = 'foo'; + $_COOKIE[$fb->publicGetMetadataCookieName()] = 'base_domain=fbrell.com'; + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb->destroySession(); + $this->assertFalse( + array_key_exists($fb->publicGetSignedRequestCookieName(), $_COOKIE)); + } + + public function testAuthExpireSessionDestroysSession() { + $methods_to_stub = array( + '_oauthRequest', + 'destroySession', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $key = 'foo'; + $val = 42; + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue("{\"$key\":$val}")); + $stub + ->expects($this->once()) + ->method('destroySession'); + $this->assertEquals( + array($key => $val), + $stub->api(array('method' => 'auth.expireSession')) + ); + } + + public function testLowercaseAuthRevokeAuthDestroysSession() { + $methods_to_stub = array( + '_oauthRequest', + 'destroySession', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $key = 'foo'; + $val = 42; + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue("{\"$key\":$val}")); + $stub + ->expects($this->once()) + ->method('destroySession'); + $this->assertEquals( + array($key => $val), + $stub->api(array('method' => 'auth.revokeauthorization')) + ); + } + + /** + * @expectedException FacebookAPIException + */ + public function testErrorCodeFromRestAPIThrowsException() { + $methods_to_stub = array( + '_oauthRequest', + ); + $constructor_args = array(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET + )); + $stub = $this->getMock( + 'TransientFacebook', $methods_to_stub, $constructor_args); + $stub + ->expects($this->once()) + ->method('_oauthRequest') + ->will($this->returnValue('{"error_code": 500}')); + $stub->api(array('method' => 'foo')); + } + + public function testJsonEncodeOfNonStringParams() { + $foo = array(1, 2); + $params = array( + 'method' => 'get', + 'foo' => $foo, + ); + $fb = new FBRecordMakeRequest(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $fb->api('/naitik', $params); + $requests = $fb->publicGetRequests(); + $this->assertEquals(json_encode($foo), $requests[0]['params']['foo']); + } + + public function testSessionBackedFacebook() { + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = 'state'; + $val = 'foo'; + $fb->publicSetPersistentData($key, $val); + $this->assertEquals( + $val, + $_SESSION[sprintf('fb_%s_%s', self::APP_ID, $key)] + ); + $this->assertEquals( + $val, + $fb->publicGetPersistentData($key) + ); + } + + public function testSessionBackedFacebookIgnoresUnsupportedKey() { + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = '--invalid--'; + $val = 'foo'; + $fb->publicSetPersistentData($key, $val); + $this->assertFalse( + array_key_exists( + sprintf('fb_%s_%s', self::APP_ID, $key), + $_SESSION + ) + ); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testClearSessionBackedFacebook() { + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = 'state'; + $val = 'foo'; + $fb->publicSetPersistentData($key, $val); + $this->assertEquals( + $val, + $_SESSION[sprintf('fb_%s_%s', self::APP_ID, $key)] + ); + $this->assertEquals( + $val, + $fb->publicGetPersistentData($key) + ); + $fb->publicClearPersistentData($key); + $this->assertFalse( + array_key_exists( + sprintf('fb_%s_%s', self::APP_ID, $key), + $_SESSION + ) + ); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSessionBackedFacebookIgnoresUnsupportedKeyInClear() { + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = '--invalid--'; + $val = 'foo'; + $session_var_name = sprintf('fb_%s_%s', self::APP_ID, $key); + $_SESSION[$session_var_name] = $val; + $fb->publicClearPersistentData($key); + $this->assertTrue(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testClearAllSessionBackedFacebook() { + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $key = 'state'; + $val = 'foo'; + $session_var_name = sprintf('fb_%s_%s', self::APP_ID, $key); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + $fb->publicClearAllPersistentData(); + $this->assertFalse(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSharedSessionBackedFacebook() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = 'state'; + $val = 'foo'; + $session_var_name = sprintf( + '%s_fb_%s_%s', + $fb->publicGetSharedSessionID(), + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + } + + public function testSharedSessionBackedFacebookIgnoresUnsupportedKey() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = '--invalid--'; + $val = 'foo'; + $session_var_name = sprintf( + '%s_fb_%s_%s', + $fb->publicGetSharedSessionID(), + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertFalse(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSharedClearSessionBackedFacebook() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = 'state'; + $val = 'foo'; + $session_var_name = sprintf( + '%s_fb_%s_%s', + $fb->publicGetSharedSessionID(), + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + $fb->publicClearPersistentData($key); + $this->assertFalse(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSharedSessionBackedFacebookIgnoresUnsupportedKeyInClear() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = '--invalid--'; + $val = 'foo'; + $session_var_name = sprintf( + '%s_fb_%s_%s', + $fb->publicGetSharedSessionID(), + self::APP_ID, + $key + ); + $_SESSION[$session_var_name] = $val; + $fb->publicClearPersistentData($key); + $this->assertTrue(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSharedClearAllSessionBackedFacebook() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = 'state'; + $val = 'foo'; + $session_var_name = sprintf( + '%s_fb_%s_%s', + $fb->publicGetSharedSessionID(), + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + $fb->publicClearAllPersistentData(); + $this->assertFalse(array_key_exists($session_var_name, $_SESSION)); + $this->assertFalse($fb->publicGetPersistentData($key)); + } + + public function testSharedSessionBackedFacebookIsRestored() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = 'state'; + $val = 'foo'; + $shared_session_id = $fb->publicGetSharedSessionID(); + $session_var_name = sprintf( + '%s_fb_%s_%s', + $shared_session_id, + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + + // check the new instance has the same data + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $this->assertEquals( + $shared_session_id, + $fb->publicGetSharedSessionID() + ); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + } + + public function testSharedSessionBackedFacebookIsNotRestoredWhenCorrupt() { + $_SERVER['HTTP_HOST'] = 'fbrell.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $key = 'state'; + $val = 'foo'; + $shared_session_id = $fb->publicGetSharedSessionID(); + $session_var_name = sprintf( + '%s_fb_%s_%s', + $shared_session_id, + self::APP_ID, + $key + ); + $fb->publicSetPersistentData($key, $val); + $this->assertEquals($val, $_SESSION[$session_var_name]); + $this->assertEquals($val, $fb->publicGetPersistentData($key)); + + // break the cookie + $cookie_name = $fb->publicGetSharedSessionCookieName(); + $_COOKIE[$cookie_name] = substr($_COOKIE[$cookie_name], 1); + + // check the new instance does not have the data + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'sharedSession' => true, + )); + $this->assertFalse($fb->publicGetPersistentData($key)); + $this->assertNotEquals( + $shared_session_id, + $fb->publicGetSharedSessionID() + ); + } + + public function testHttpHost() { + $real = 'foo.com'; + $_SERVER['HTTP_HOST'] = $real; + $_SERVER['HTTP_X_FORWARDED_HOST'] = 'evil.com'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $this->assertEquals($real, $fb->publicGetHttpHost()); + } + + public function testHttpProtocol() { + $_SERVER['HTTPS'] = 'on'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + )); + $this->assertEquals('https', $fb->publicGetHttpProtocol()); + } + + public function testHttpHostForwarded() { + $real = 'foo.com'; + $_SERVER['HTTP_HOST'] = 'localhost'; + $_SERVER['HTTP_X_FORWARDED_HOST'] = $real; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'trustForwarded' => true, + )); + $this->assertEquals($real, $fb->publicGetHttpHost()); + } + + public function testHttpProtocolForwarded() { + $_SERVER['HTTPS'] = 'on'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'trustForwarded' => true, + )); + $this->assertEquals('http', $fb->publicGetHttpProtocol()); + } + + public function testHttpProtocolForwardedSecure() { + $_SERVER['HTTPS'] = 'on'; + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; + $fb = new PersistentFBPublic(array( + 'appId' => self::APP_ID, + 'secret' => self::SECRET, + 'trustForwarded' => true, + )); + $this->assertEquals('https', $fb->publicGetHttpProtocol()); + } + + /** + * @dataProvider provideEndsWith + */ + public function testEndsWith($big, $small, $result) { + $this->assertEquals( + $result, + PersistentFBPublic::publicEndsWith($big, $small) + ); + } + + public function provideEndsWith() { + return array( + array('', '', true), + array('', 'a', false), + array('a', '', true), + array('a', 'b', false), + array('a', 'a', true), + array('aa', 'a', true), + array('ab', 'a', false), + array('ba', 'a', true), + ); + } + + /** + * @dataProvider provideIsAllowedDomain + */ + public function testIsAllowedDomain($big, $small, $result) { + $this->assertEquals( + $result, + PersistentFBPublic::publicIsAllowedDomain($big, $small) + ); + } + + public function provideIsAllowedDomain() { + return array( + array('fbrell.com', 'fbrell.com', true), + array('foo.fbrell.com', 'fbrell.com', true), + array('foofbrell.com', 'fbrell.com', false), + array('evil.com', 'fbrell.com', false), + array('foo.fbrell.com', 'bar.fbrell.com', false), + ); + } + + protected function generateMD5HashOfRandomValue() { + return md5(uniqid(mt_rand(), true)); + } + + protected function setUp() { + parent::setUp(); + } + + protected function tearDown() { + $this->clearSuperGlobals(); + parent::tearDown(); + } + + protected function clearSuperGlobals() { + unset($_SERVER['HTTPS']); + unset($_SERVER['HTTP_HOST']); + unset($_SERVER['REQUEST_URI']); + $_SESSION = array(); + $_COOKIE = array(); + $_REQUEST = array(); + $_POST = array(); + $_GET = array(); + if (session_id()) { + session_destroy(); + } + } + + /** + * Checks that the correct args are a subset of the returned obj + * @param array $correct The correct array values + * @param array $actual The values in practice + * @param string $message to be shown on failure + */ + protected function assertIsSubset($correct, $actual, $msg='') { + foreach ($correct as $key => $value) { + $actual_value = $actual[$key]; + $newMsg = (strlen($msg) ? ($msg.' ') : '').'Key: '.$key; + $this->assertEquals($value, $actual_value, $newMsg); + } + } +} + +class TransientFacebook extends BaseFacebook { + protected function setPersistentData($key, $value) {} + protected function getPersistentData($key, $default = false) { + return $default; + } + protected function clearPersistentData($key) {} + protected function clearAllPersistentData() {} +} + +class FBRecordURL extends TransientFacebook { + private $url; + + protected function _oauthRequest($url, $params) { + $this->url = $url; + } + + public function getRequestedURL() { + return $this->url; + } +} + +class FBRecordMakeRequest extends TransientFacebook { + private $requests = array(); + + protected function makeRequest($url, $params, $ch=null) { + $this->requests[] = array( + 'url' => $url, + 'params' => $params, + ); + return parent::makeRequest($url, $params, $ch); + } + + public function publicGetRequests() { + return $this->requests; + } +} + +class FBPublic extends TransientFacebook { + public static function publicBase64UrlDecode($input) { + return self::base64UrlDecode($input); + } + public static function publicBase64UrlEncode($input) { + return self::base64UrlEncode($input); + } + public function publicParseSignedRequest($input) { + return $this->parseSignedRequest($input); + } + public function publicMakeSignedRequest($data) { + return $this->makeSignedRequest($data); + } +} + +class PersistentFBPublic extends Facebook { + public function publicParseSignedRequest($input) { + return $this->parseSignedRequest($input); + } + + public function publicSetPersistentData($key, $value) { + $this->setPersistentData($key, $value); + } + + public function publicGetPersistentData($key, $default = false) { + return $this->getPersistentData($key, $default); + } + + public function publicClearPersistentData($key) { + return $this->clearPersistentData($key); + } + + public function publicClearAllPersistentData() { + return $this->clearAllPersistentData(); + } + + public function publicGetSharedSessionID() { + return $this->sharedSessionID; + } + + public static function publicIsAllowedDomain($big, $small) { + return self::isAllowedDomain($big, $small); + } + + public static function publicEndsWith($big, $small) { + return self::endsWith($big, $small); + } + + public function publicGetSharedSessionCookieName() { + return $this->getSharedSessionCookieName(); + } + + public function publicGetHttpHost() { + return $this->getHttpHost(); + } + + public function publicGetHttpProtocol() { + return $this->getHttpProtocol(); + } +} + +class FBCode extends Facebook { + public function publicGetCode() { + return $this->getCode(); + } + + public function setCSRFStateToken() { + $this->establishCSRFTokenState(); + } + + public function getCSRFStateToken() { + return $this->getPersistentData('state'); + } +} + +class FBAccessToken extends TransientFacebook { + public function publicGetApplicationAccessToken() { + return $this->getApplicationAccessToken(); + } +} + +class FBGetCurrentURLFacebook extends TransientFacebook { + public function publicGetCurrentUrl() { + return $this->getCurrentUrl(); + } +} + +class FBPublicCookie extends TransientFacebook { + public function publicGetSignedRequest() { + return $this->getSignedRequest(); + } + + public function publicGetSignedRequestCookieName() { + return $this->getSignedRequestCookieName(); + } + + public function publicGetMetadataCookie() { + return $this->getMetadataCookie(); + } + + public function publicGetMetadataCookieName() { + return $this->getMetadataCookieName(); + } +} + +class FBRewrite extends Facebook{ + + public function uncacheSignedRequest(){ + $this->signedRequest = null; + } + + public function uncache() + { + $this->user = null; + $this->signedRequest = null; + $this->accessToken = null; + } +} + + +class FBPublicGetAccessTokenFromCode extends TransientFacebook { + public function publicGetAccessTokenFromCode($code, $redirect_uri = null) { + return $this->getAccessTokenFromCode($code, $redirect_uri); + } +} + +class FBPublicState extends TransientFacebook { + const STATE = 'foo'; + protected function getPersistentData($key, $default = false) { + if ($key === 'state') { + return self::STATE; + } + return parent::getPersistentData($key, $default); + } + + public function publicGetState() { + return $this->state; + } +} diff --git a/AvocadoEdition/plugin/sns/icon/facebook.png b/AvocadoEdition/plugin/sns/icon/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..b9d733963ba81f9914f5f7ed1e08d79a2089b9ad GIT binary patch literal 1052 zcmV+%1mpXOP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#zDYzuRCwB?l{;)4MI6SznVr4&*||I0 z3U+eH21F8GNhG8|kPrnFG|(Z@LqneeQAZ-8LP<lAfC35{svyxIQ4lD2DMA8;B!Gi0 zpTnKw%f0qyXC~jwoo(b-q_EQHRx`7|`R4mSPCfJLJ8>k{n-9;=ovBtPYSud3&m*Nk zbFJOH{@3z3WAq0~%IJ+#C!aX~$U+^7Huyi!k%g!@U8$bG{L>Yurfapgqqu}`e*6>3 zFa^YYQhCvAM&a<xBxcA|#>v{^$~ux%LkJNz?Dm8ut{LOtwr%oSl#&<>H9X5R6-Amv zr{ODyz5TTqL8}LHc=`DSJXEg)U=&IGyVl41pZvgg0nhSGWeGG4m~;CFEj1QXgueCq z2|RgZ4h(p>1!IKe)pclV;e_OzgJ&vZ4Z)mrc5nN5rq7lapPR>tV|Btt(2anU^4Y-f zbAEWH@*mtwv0saoz_Z8eyl%`xEN-oJ@%=CVgm2rOLD=KpgJK&L+j}bZ8_UHkDig)9 zPfCfezq^6=KKeFztmtj2kl9r2f0grU?Z}rMnZPk%B(%1{jwp&Y*OnS>^tm?413k@* z3rmU-Pi<sFYIiF3z*k<F$Lvfoq+&LX!bd_noIW{=a><~O&ER$?!RKFH=S_e(8s()5 z88*((?X}TQG+sJ=6vvMqB9O{ci!^0*3WKK~ujABH5AvN^(YTGzE?s4&2*k`1&kKr0 z0Mk3M-CKG#&TStQW6WkSCDnWAfA@Oxgu__zxGcOCQtYhfD_2)T4r?kswlE!<jaPQ# zW($p07de*kO0&ai^VzUbxB)zZrCf-%LE}t}cR#*NuMLX%3@%-G4aHo{k-?{5{)!L3 z_!$!no<FR>`E)Y@1e8wtyio_;JH4P}*FIrGg}|gK)yr@LXNQ~{aE<yny3A#t872Df znW{WhL9zM(^!nalpNjdc3O;(c9tz|q%9uJlhca)n@py1`vVd-j!ONGcC{<_Cj(Sl0 zfO8oc3dPWCHbSUe8O7QmTA;T2i7%uB1z4T1r1dbOb|k$X(tW@pjc5V;3Ik!Bz;HOk zpvx=Ut;qNQq7cE5DU+nvtmYL;3<y&>oVs(2=C#&gq<(niZfg&1M~TH!Axo2~)|!p8 zjmFIjkImN6(T)w@?$U%<bs74a%d+~|8#oSDN_g~O!pf6jPlmTG^L=S~5iK&6u=e7$ zYrl)N_12j}zEJa!-TroB!hZXM0RDRT(&7r*jTVOVe$+u7{_gjh&0DMIq_Y?A3NQe= WlqohV`EDKn0000<MNUMnLSTYD5&)$D literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/facebook_cmt.png b/AvocadoEdition/plugin/sns/icon/facebook_cmt.png new file mode 100644 index 0000000000000000000000000000000000000000..67d294ec8cfa4335bb0bd64f7c005af63ae1f135 GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5M?jcysy3fAP>{XE z)7O>#E*lGrw8D4x77ehFYeb1-X-P(Y5yQ%LXFPyHJS9LOm(=3qqRfJl%=|nCVNOM5 zpg0#u+&RCXvM4h>ql94%{~0TwC?8m~C^ZqJRG}m@H<iKkJ3l8-h7%+coS#-wo>-L1 z5L@scq?{XUcxG{OP9jig5ySQaTl#^*93bKF#G<^+ymW>G($Cs~V(bw8rA5i93}62@ zzlJGu&d<$F%`0K}c4pdspcorSSx9C{PAbEScbC)|7?>`3x;Tbd^r}wS*e#PP(LVqE z?ELhywC|hBx4*k9w_I__-V6usje;z#EZrhvf;l-N%3@0Y7{#JGg@QE20zcYs*tChm z$zfvv(=pe*-4E`n-m5a-ZoJv}{`b1|NB_=hUtUx9>|Wl=`}cRA{(E!&8Go-`W*6Rz zTNw3N9bjNu_Be-c@kH@?^?mC4u}A(Ed=IbtQ+X`qwas)r8{g2-h{=m)F|w^r5H!#g zaI8+4lD~g<^No(muV?*Ba;qA587IiBNSZ9S)?r%emQc@d{TY7YD_^tPNo>+Nd~;g8 z{J+MxM;;s%IwG`a@#GdgExosa`u-Dlq~yi~TrDp9o^~bISK4OLf~*21Cvl~<5^Dra z*e0zg$@NUKP2G9^%f{n7%l@Y7z3<^XQ2oBXIl{ZAOSHE|V~(MclpyDiROhUO>P^SC zuGar_=G+VxfyN^$9_+7p{ZxgLRb0BaCWI<D-RHBkoU_@o$fmloS>oYZY59xV^A@}n znsh`_@#xVN9U6v*B4@aUD!3(GHdycdVZyfsdi@J^PkiEZWR4S2U&OMWB~XYbP$Zir zUjF0P@b^Ix0gTxXzD<`;HmZ0$SO3F31)cMLJ%&n365MJ{=7$n24p?wFBsnrnp8N9> z`vsQ3qpnud-fDJACvtRDyjpkgdE51S`#QUi-}(23nIUffN5w_b9L{qB_lUo#KkokJ zv&enj$Pm?g<!gGbW$X!J_4elHuUOD+*}L5&PS7_Zg!f$a`HI>@ud4jCy*TC_R8W@} znImnnq`HMYU`Afv<R!wZT9<1G{kzG%W9?bqzJ9(J>wP-1E?&5J#XD$v@s4_jhf+ZY zBvzajo^`=6O4hi(!b6|6x~{tU=HK{?Q_Mlpn<sH^vRN2=Ml&a6mz|r<5x!-Q1uGwA zu6F<P@3z0q)?&fp{O#BL^J~w&S-<~g^@oO}3Bga8UukVJ($VPuCMm|(;JW$AonK<h kuQsg?k9+h>JN$>d%IewP%a_jX0;YEcPgg&ebxsLQ0AXaRGynhq literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/facebook_off.png b/AvocadoEdition/plugin/sns/icon/facebook_off.png new file mode 100644 index 0000000000000000000000000000000000000000..b26d4091e75d71de35757e559eac021bfd359e11 GIT binary patch literal 920 zcmV;J184k+P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#DoI2^RCwBA z?Ck7hWoBkhlai7u<Kf{E{`c=6137?^k&)rcmoIN$ym-;|=g*&600G3p#Ke@UrlvMU zLPCN8D8N7okd&0<=Hug=a^uF0{{R8RA|N181#~gPojZ3Je*gXrwiyKe|NjqX69Yi% zSy@>b`1$!6KxP625DQR1`2G9$41fRr1seoXfUW`AGF(9gavaEEAhSSb0t67tUkE_a z0J8v@1_6*7Zf<S{ZEbA^At52K7%(UqzJ2?~aNxiJxO$L*00G1Ta|N<NFxSCosA2|Q zUS0+p8yg03adEI(82<eEGguzvYM35?0Ac|dip^k{%V91BiEC(RFn}T%W*`i(v9ZC` zfy6;HKmf78Tm-}D;foxGa&mHDuY<%v-hce~F_``1#}5>>AT~e%;dL>xLJkfNFovnS zd-pEG?%lh=7J)2<$$<bUSO5YDuZuwd6w{#e4Uz*H0s|jEegw;La&p3h0Xg^p0tjv} zwqyh{P+wo40hs8)8bB_CSuQUx&%n;k4o<tEpg4E#99Ru3r~m?p1*Q;Nas#;tm@B~% z2D2O%LDJIF3^Fn@@KkZ?)G4r`Fkb-#5DP2}VHpJ3JLo|Jvm6#I$U%dgY(W?xfLM?< z!MuU27+9#lT`D3X0#*aE_``<}3}3%~1qTm^Mvfy84G=&q=&_G%Fev;$F%JrBP<W=M zrh>&l>Gr~f3k-)39|lJr$Rb!;hNW?U0Al&|>lZv*q8EecIS}S@n3rK}5cvN6J3J|Z z%mfG^7Ep|XFvw=~Fhe#R<WiVnp!fi#TQM;)l=KUtL1oFOPoEe70*D2~0F?otu)>x> zU}7vREGPzpybdZNK^7wG1DOYs2M8cg>BbCF3`&d0`5)P}Fc-rj7?yEhSsB^Iptt~; z2@pU`KY#vw3$h&+_{bRs7M93K5*ec>F_0M`gF$8j1P}`_YqkLk=c&TN!r<5kX}|_R zK>>0#D9At<SU-ZxWRMuFTn4e<zI_YI?ri`81S*7P14}7JU`1F4v`rXS)dMo@<;#~~ u8e|E`08niKGZ+LwE(MBp0bM^EAiw~GUtJZ+vU?@~0000<MNUMnLSTY7iDeN0 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/gplus.png b/AvocadoEdition/plugin/sns/icon/gplus.png new file mode 100644 index 0000000000000000000000000000000000000000..993cce99126a4e90c36864d472c993bb3dbbd522 GIT binary patch literal 1669 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 P00000NkvXXu0mjfN&e-$ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/gplus_off.png b/AvocadoEdition/plugin/sns/icon/gplus_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d1dad06e388bc2bc48ab956ddb7696cd2bde1609 GIT binary patch literal 1113 zcmV-f1g86mP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#>q$gGRCwBA zoIH85Br`MfR0akH>wo|LF)%VR!Z8Q{<-jydjERW}CdUk-L3%(KDh>h{fO6RY0mK3n zobl(+A3ttxZUzYn2?jnsK8FAQ|HBOfX#g1xVuR@C&!02AfBzmV4>FLGlaqmmhlk<w z=g$m3fBpmsI|1=@fB<3vDz>w>wq`IgGGci9_AS_8Ha0c}Y~c3o+YHyQUx!=z`}c1K zJv}`JEiEmEy?ggE+`D&=ft8gNB&`JyKrGqW*?&N+MT-`J4F+it6%}O&2?=3fXJ-c+ za`x<5hGWN$fi;1|Kx$yV0{I98Kzx`O5c~lMAh77xty>vhzI@5R!omX946<O}ym@e! z8XFrkXliQ04Fnkm!?3u31sRM62p|@a;KPRxVO{`h1X%zIubn%0GPt|DgT+lvO~GCT z0dH?_24P`glwfjla)PsO-n_{G5I|sqL1BgL6;PyrYz0{e1N{8_U@?#!C?4<uki!51 zhy~^iV9Ef~Aj4ta`}OM=I0Xm_3c`~fNNmA^1q^@x{srrCbaZ6U*4Ad&w{IWAjT<+> z5f73B2q176i-?GT6@gp>b2$iu6ny{w9qtlP@WAB2t^#6YUxEw;1t|vy2LnI=fekh> zF@YNj3uojY0D;q|Ps0s{83c<+Sn@;G2M|Eupios+1>;+{Zo!iiNFylOfiljQFJBl= zoHzjwD&(XFO4p!F^Z4;&a8SYI00M{!W&<eQDkvzx!w%%7z`#JT+`@$m8DQBRIjBJV zH*em6!xoePU~vNi00G1-BqUS{%$D5Z;^GXty1EQ<a&ipH%F5s*1#-cZDO13jVBv|Z z85RT}Ihb#tVxIv5h~?wQj|}VAuLoxmP%t<<J2U9(>w^{S-@l*X>({T~@&H!Qz-VLu zG7#n?Soi}35EHC$0ZD?w5@b6JsHv%e4FLrYOfzy&z%Z<YLzV{!ASRgeL7GAM&Ye4O zgXQJr89Y2Z;7JeJ5NsA8ml*&7!~{!1pk$@4u8xt5K*16b5dqIc$X>_iYJdP@1m>7m zhK7cspj7bS!2@tk0|k$?v@|%CzyK&YtzNwvtO-`wAeY%_mB2HA0Ad6xe7$YkHj#7Z z&cSmZtmKlBkzt68j08s>2wc8=nPL0(?ck({T%*7&LlS!i5J1epAgBVSLk?J3fL!!_ z`0xQ-7OSYJfNKd*l01L@JUIEmT#H<7A*GUU00G4G?%lhqpga!CZOD-TD?Zn(S%Z?r zv858^Fa`w$KmdWNrZga9G7xKmEC)*bNA@C!1|~zsA3uIDfeRNVrhgzcK)?t~voQ5g f@CYbY3=m)dB+FB_*;f+y00000NkvXXu0mjfCh5k2 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/kakaotalk.png b/AvocadoEdition/plugin/sns/icon/kakaotalk.png new file mode 100644 index 0000000000000000000000000000000000000000..78fe26ca7a44efcab004d7ae4fb634ad270f83f2 GIT binary patch literal 1532 zcmV<Y1q1qtP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%j!8s8RCwBA z{Qv(y!~17$|Ns5D$3P9h#G=F?D7A|bAb=R(KC%1H&2f`~jh&H!;Xk^v{|t<bKtaZT zK>Qyn4^qd(@c%y}gpCY<++RQcGkpD_&HxaAs&PvJ5QYI*=IkcQ?ti}>!O@RdDn4L> ze}O<UpI*s1d}0KN4k9;hm=+FOUX!FF>rR*y%)sMs@U)s%E&;^C$iNJ=9Vi8pV+0z= z&cg8JogBmY(^3q#u5&TGe#y-6{TmZd4HE+w&p!q+$^Q(h8ebU<44*J?3q59F`1uFu z0A`4jKxP5W1PCC;HxHHn3kiOO7|aY*z$nacXrDU6=GCkWFCYH`JBF2wnSq&^5vYa{ z6gUij{{jUWnHj{TSQxwle=yiMTmhQ+7U+5wu)*)%b29)05W--VzYKr>2{A03smZW? z-46zK*8dF5Y_JdlLa4z^OiVz`3=9fJV0Z$<^fx1en=dOvO!6fLW~R3c|Nk(94F(7x z7Klb*<gjrwY+R(mux{}u22RfZ4Bvr~!0_uI++bEVCZNTP3@pq*gPB2*#{>*dW(HPZ z2y9yYi-BKIlOZ7T90TK@?_fOu0R%Rf0qDBt_hlJYFZ{v4#rp;5(mxFU{{3h8^M{e) z%jbW<IAmh@_Jf6igA-`iFJ^F9v$6kY`1qQMfs>mF7);Cz>y|Szm|H0_NJ?J?8wn6V zOrTI>U}0xCbCQqY;l1|^n)?43${GY1%9{iklr?`dM5nMbB;~L(Jbm__Au@%9ft&vu z!#`k(2#)^Gz%TlqAtm=8(BSV3&mVteIDJ9@Y!)bq0t65XIHmk$Vz_hb7Xv#mMQz{s zjX_lAGce5mGaNnklfl{bA28DYFi0!>WZ)He2MpW)3_rdzGZ+~EW-zq)&oH&`Bg30F z+`#bq!*KgHFwp-nfn5v`KrAqKvj8LN-#=hd`_IDg``25B?_d5g*xIo$@bN!o_yJUJ z@65vR_0t!Iw;y;JK7M8ay7DtHSpG76`@#WK&jpOozYNSk$AHWN0e}Ev0p}*5ZCbiO zCL<#_+5P|b8yGP^8B8r17_MDmWBB@ok-@;=3j-T4Qu9i`F<igM!f^N2UxvB!co<4b z-!gPG@G(4j#Lb|o1#~SFBuxVZ5IDIBi+p7G`c0J~EuMwp-nDlOqEf#Y{`>_74KRWp zJm6sX3-q3n>Q@Ffw!aL@sy`W?Jz-^d|Bekvb2F%_{a|?YjFmw`UW#GX!e0#BoVOX? zzTsm42q0)W28JmYE5oUyh73jNj~IS@`N_b+#m4aa&p)7H|G~ca@dKDBfvN8|Fwd~E z1LFwjWgcLPc>5OUJ03QMsq^F*j4jVG{QvqJn2vcF00M{!S|$N?{$en*xx>&tQH?=D zjt3lO9Gw5bQXqr5xEL6Cco`Xlgc%uld4TDf^&i8_*Pj`LB-j`_C#e7pz0JVz?H9x> zAOHv;)GW;aj65EGhUX6)8A>wlGdz0q9O%k_4Bx;10cR2rVge}y<~|`2P6h{835K{N zHeiam0W|b2s7!!oX@CG?!6^6se`EOi@iW7_H$eRE8-tX*07GE3JOeAx>wo_IXW$cH zW>8aSWzf+0%^)uK44AwgL0!s>ViG_Ap&HD>#PI5g217&j6NV38J~Kq6Xfnjaax%!P zzW}Dizu<D1fe~cLCtzR$i_P!9AYy2Sf&f4OAq)l<m;V_=84m1~VlcP)#LzxLltESr z=%T+*85n?(2`_SCg*_NE<E%*l0tlF-|3bqT7>a*>G6V;|U|{BX4|LHBR2Tgxu4)43 z1E84z0mQ<{B+2me=RIJd0yN-1umEDb2&4$R2)n6}stIH!Kmaj<D$}=59f6iSrb=bX iz%0ukEWMu*Aix0aM&2J&IgRrG0000<MNUMnLSTaRXRd(& literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/kakaotalk_off.png b/AvocadoEdition/plugin/sns/icon/kakaotalk_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c3acc1337076b01ca5797e8e723f0959c7329912 GIT binary patch literal 1173 zcmV;G1Zw+<P)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$CrLy>RCwBA z{Qv(y!^4LU|Nr^(hk=oikpToiVlXy7fUFM2W@ct)ke8Qd1PCC;`}gnv=j7yMU}t9s zOQHjqMr4aX>i+%vht(m!e*I$j{{1@xKmaDk7zF?T1c43W{~y~HLR?c#VW*}f7y8YB zG)uZ2aAxj?#v`zJe*t5=y1P~Y0mOoCBZvk`zJLFo;oP}%3^#AyWO(!D4cKsy92XZC zgP52YgPNKegTB5#gMfel11K2LeG3pkjCb$e{Vyme2-d{J!~~`f95}$RY11Z#=g*&m z`K+w0U>|_k$iW~kF3#ZP<;7rYYYR3E<O7iWhYueZ00IbZFi0av!@PO(7`AWU4mJ#g zVZMP`icEvT6BI<QuC5I6@$q0Wkl`TT0t65X%nP8fTd`sV!@70rz+wLL=TERkm^>(W zKo)}>0Ky<~kQj))b?a7ekc5VYf(-@%fB-a-F$w@s2twuG|0WIHsph6A8b1j+Ify*O zcco?q5y3rVX_u_KNtK!0a%NCf^btXT&8aHfon5OhfWQWWY(0JYG}v%WO-+XK@^XgC z%1Q=hWo3q_s3?ZS#6*UdFJFS$+}zw?gMx#D!LCeBP6h|Tix)2#PMtahj|+eRVu6Lr zojZ5HF5R<d4}+wnBv`?jGiMka9UZ~0lai8R;OFNDYXZ62z`%gP#KeSQ%9JVKFa-q- zFuveH0T4i7cY_Rvg&{1FgS=>NZqC5R#|LKH*w}!B<KxGV;B*SI7^DssEU;V$G7AI% z0*DC~>sne`@N^8a0OWd8Q&Wa(*RC;Kx^#&_Pfw3QNJxkwCntx&-`}6%_U+pY&CSgW zDJdxopi~9&g@%R(JV^os;Fye!0DwUdXm+sn&gopq>F8`+A_;VS$se4r;JUjGP*n!N z$gIQ`Gou_4;>^^(xm9{6@2*sJw+_TZJplwZ7~~QT4i1Ln$B#3Vl$3xi0r5dzgryEp zaDZF_N+BQ%V7U-v0VpL+oH&ue%*+g|7Zm0I0mKB$${>waR#prxEiDWZ5)$CB0vQgH z2VszAP>KMh1P~jPtU$>P<fzuxR<NP4qzA$P0R(q3%mR=mP_ip7E@pW0<Ow*uVH#j@ z0K%YfwX?Hhh>ME@2NNiaVdW0U7XSgof?l?Q=ue+MF}!>C4x9o&VHX$}2##@3(14Ph zs;VkDqGV)bz+xba(Mv~w0AfLQ2}m<2vOuv7N=6Y85e$)$kzj*Bijhk}P*}rUiC$iV z06+k-pci)s4;}=k-}d%)aEyae1gyx!RuNzWAhiGi1P)_iVPSas1p!cOgS-eU+_6<f z_y8zU0Ro5x<b6;Wfszo+Hc-KXub#tZ8Hfg@Bv9~xXn+7>1PMHN@Zdkl%joqQJQpEF n3VN8L`vPRBf`S4gK!5=N24OAjEgNo|00000NkvXXu0mjfa0Tqe literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/twitter.png b/AvocadoEdition/plugin/sns/icon/twitter.png new file mode 100644 index 0000000000000000000000000000000000000000..9962ded1ee43f57bc45a0520e40576a6a3aefaf7 GIT binary patch literal 1030 zcmV+h1o``kP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#s7XXYRCwB)mA!8qMHt4Pot?egkNfnQ z7-37cMG+T7sgP13AtHegQW}*10E+wpDIy9giqwga;vS_%0@6@H0TM_^5kg=Jha|?1 z%^4qex4zq%o#B0F&gZj(P;@JeZf9=yH_trpGqdueuYZctYURU?ms&R$v$SK3#XOe~ z0sa~ucYizh`}S~L+>=olesJ~G<vW*`nwXP018-$3jqJ`>zdo{Zz1_IA-mYUmSI`Cs z=7h2)DS)+h4eJZdTQaLwI)g$J)Jz|ep+G=0SZg8ZrqJev;QW}TW!H!)>AjLW+Ik-% zns#fahmSvdh@FEWZoGF9@4vAI^@4ErlbJ%5rGq*+wMrP^%ZJbK-QF>tRTF&r%@gEf zjnbSx^S_N)%#=!(bYrGg@UlfxLEOqvi$lm*BB@HU#QQkCsLu%+jx_AdAAHYDsf_lD zC;uvI5R%7L$t{GXNjD#CdCzCKyn;?6#+#RyAnDmDoD~yOvTSF^M6oJ;GAdF!u%dyx z-~M?{E?a2{ZZM$n>sMYu&dT8n?yX=b$O=0Fn*fI7g#;C0h$^+0R~DYD5wD;-RM^cY z!sz{zxgA)W(s^~Fn2T>Hk2WG3B*!j5$^kuhu@#rvF|Ka3ajY~6@>q^1Go|LjIbZxA zMQKTYz+r|WuNPv0d)L<768~#s=B2_=nd!z7f<zKivQPBuzyW-~6&H$Bib!BEQut-R zhviO;v9_mP2YAkRxBCp7_kv}Y*2j$-M<uIp%p!t^=m#P0|F};RXi)NyMgbCTGH`t} z^DZ~favpQXd(0xJ9=LQN#^RF#U4kXG1m7R_@y8dBvAPf=6h5mgubzZ>d!vbVDxK#% ze8Tcp&@7x^1{buHP9pHuS`GJqAAkg-b)ks^I;0*SYQNrzq4~H#6z919S{<X(Ou)uj zAvq>oH?8@=vF@d#QGs_>QxriHpKlMGytE!8ZQzW@RYi57-O0r&OXg5iBe>{Iif2*S z62hJyn!AG`uB~Rcvb2Z?Pe(4Vp*VYztz;7KE?XQGIZa4Vc$QPFlnPw|_=udXF!i^4 zeYC0(Zd}Z$V2K+$-5>!*l;5qR9wmwwz%eDC*;Zo8!#wYnS}oI;1i8{UbE43-HymSU zaD0B)Il>2%6vA818!3`xsRA?Q{y+Use%O9=_x1HvG~z1Cc|S|6mbNmnz)VS7aP#M< zyTM+sce9?Roj{2BK279npOkj{`EB|FZT>6302R|;hYG@@<p2Nx07*qoM6N<$f_>=Z A0RR91 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/twitter_cmt.png b/AvocadoEdition/plugin/sns/icon/twitter_cmt.png new file mode 100644 index 0000000000000000000000000000000000000000..f064d1cbb6b9f7ed8160f04930268c91572e0c71 GIT binary patch literal 1022 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F5M?jcysy3fAP>{XE z)7O>#E*lGrwCwu)6P92h*N76w(vpn)B8HXg&UgTYcuIgmE~&-IMVSR9nfZAP!kmiA zKyfaRxO09%Wl?5&MhU|j{xeoUQ9iI}QEDPcsX|F+ZYqQ6cYaQw3@1n?I6tkVJh3R1 zA-3Q@NI5sy@XX@moJ63~B8Ke;w)6vqIY7eUiA8ytdFc!Xq@T3|#n>VGON)|I8NU8+ zehpLRoS&PUnpeW`?aZ|OKruFuvXIP@oK%Jt?=Gn`Ffg6;ba4!^=w&^4I!`)O=D@@I zme1|QtB=VEA744!NpX?F#sxvDVQUx<N_CpQp2wbWkXgaZW9lx}kWSv97pA>)Ew(*B z^YqRSyRYe9FRy-$-j+!wi5<yZ&5*iv^BUPYFq9*v~|UWq*m*JVHZD)aTY{q8L> zQ=g<Nu=UEfPT_fK^6;_T;<P1G1O#0URByO;sZ{n}^^>ASJC0qtdv}wS?QyH#V$RYx z7iS)SA@*EGQ+3NVjinc&oK<_0UD)QI2vj(9cJ9;b@pX^Cp4OF*zw`L`{C$Z$vYzP~ zYdH;tl3f;aC>G>YtL*IH>U84HYk0dm`d0Musdo~}m0vIlI;OXYDC}x@!nWv`ORrps zW5<FTXOqsi5k_?Z7t)H|j2%T;?VgtCK2dY;Iov0m#KtW7=n-Ro`-%%Y7inlOyV~@3 z+4Gl|=Ue{rXj`~a%WiMPr?=(t6Q?#^nw9rv!oBSpf`<%*nwXTIxSp-rd+eR?=4W<$ zWhHhq|KEGd&`t4+Y@}SFosyl@u>~KK9hRgN?s~LsukyD>f4O<Z<(m_C&Iq=TxNOo@ zX`6U`+m0y(87`jAAq$Qq9PdlAO4RB*`jgYX=6^@Aq{7oLu?LpVI~QlTi*d2Ig7A~S z-%hO2%3Ni+P5y({Lhk0npWmO>y}IhK_2CQZr?i&y+bXe5PpIE=qD1Y5&BZeI8m=?q z>Jsr6-rJs^|NrRw-@2)0OZB*~y|#?EtLsQ%nE0al$%R~xU5Ou*pYC~9a@8Pj-NZ=0 zg+-r!$15`??SFpvUzhq<$-TAxh7)}pa_(=~9a)q=E3wQrUgz7Kv_ntp9$X7OvqRa{ zKQi;&H1QjJCh2!#@;}D5&6)G=#trk5iyN}iLPC$W`<{F*KR3Xa#aPB5vhnM@#pN=0 zOxK%7mwoftIb-3xrBmkZ-SO!C_USk72=q8wA2msR;<#CNSxBne7Wb5lnKO@=^x8zs f`|#vr`XBzC>b3jr#Ctk{$(+H{)z4*}Q$iB}k9NHU literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/icon/twitter_off.png b/AvocadoEdition/plugin/sns/icon/twitter_off.png new file mode 100644 index 0000000000000000000000000000000000000000..08cccb2426ef5f6d842460f0f77f6c93b519452e GIT binary patch literal 969 zcmV;)12+7LP)<h;3K|Lk000e1NJLTq000&M000&U1^@s6#I$TX00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#TS-JgRCwBA z+^}H-D?2-TnuLTz880ud@V|fm7>EIkjEoHb|Nn>cnV6UuzI^%e_WASYT|a;RoCOd- zEX>TzshXOaQ)Fdj8HhC$7XTX0Eg&E;<<g}~{{aGsMOaw4N>o&o;q&LuV1r?<fVl{n z1_5MO!o*<WKu0o&h=?!%&8q?kAQlb|4&fg^e!vX{DF!KkX#&xI|Ng}=962apY>*is z3=CRffB<3v3jT!&fB?wQ$B!Q~EL*mW;qBYE3?3dH433VD41fOoL2)fMHi!mcV37O; z2p}eqYhVV0FbfL{!};^)8D715#lXhK#&G1w5e8snfaPFnK{Pss=?57Mas)sCvHbr1 z8_WO+g1iLc1HHn)$HxbzL571cDAv(a1xU~L@82<k2V@>V0I|Sqfnk`dK|un-ApX{^ zTQMRLBo4CN(9jU99_BC*0QmqQfLK7L!@L6%1Obp@5C-|+*s)_M5e0K0ELg0qt>JM1 zatufeAb?nq!x!cfSR{hH4+;)RNlBE*f&ox4eEs?r#bK~i1Q0+hu%raTAU;SE7921( zIsmB!W(Ec=EiJIGU=9K~24n_60I?v)G|XU_i$NF^aiO817|9D3<{<T;R0HF~3<d}w z6oZk&7-T5Or65huo;?HSC|EdR%Y`ri3s!&tVuGa#m;lIIAXkFI78VqzPoHK0<xY@A zAURf6RxlexBkM(WBtQVclN&5-K?Z{&>&cTRV8gh%xf$NSf6uUa^JWG?K|#2eL70=1 zlL1(Ofz==<HxL^jfKXBeOcNIu7lXXKJj3nVx52Ik7F1wMKo%ey@bcwLu+Q}M^})de z3rdh0fB<4a&W5nu1xiNB%F1B&g9i`bmVsP`9C;u;AcK)3AI1j=AQt32j$CYlicwWn zRR(EkX|UnnzI_85hMc>2czD1*1NjD~4`v=f0D;O1X5^qi&Q+k&4Opx)=;`T!BMn&% zi2n8K7sH!3Z%`@-5F6+dW`F=<0lMTZkRc6ATIc{+-GE&Wi!k&;9ux;KKFD&APe4@^ zKmf6P`t+&o&Ye3`Ra8{KUc;6)@d5OL2^8TVGXVk!RM5``CN0JfA3l@;BS#n%f#@{@ ruF4eIV3468-vbTp0{VV7K!5=NJb=6%Z@fD<00000NkvXXu0mjfvNL~e literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/twitter/LICENSE b/AvocadoEdition/plugin/sns/twitter/LICENSE new file mode 100644 index 0000000..233854f --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2009 Abraham Williams - http://abrah.am - abraham@poseurte.ch + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/AvocadoEdition/plugin/sns/twitter/README.md b/AvocadoEdition/plugin/sns/twitter/README.md new file mode 100644 index 0000000..c9a17ce --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/README.md @@ -0,0 +1,114 @@ +TwitterOAuth +------------ + +PHP library for working with Twitter's OAuth API. + +Flow Overview +============= + +1. Build TwitterOAuth object using client credentials. +2. Request temporary credentials from Twitter. +3. Build authorize URL for Twitter. +4. Redirect user to authorize URL. +5. User authorizes access and returns from Twitter. +6. Rebuild TwitterOAuth object with client credentials and temporary credentials. +7. Get token credentials from Twitter. +8. Rebuild TwitterOAuth object with client credentials and token credentials. +9. Query Twitter API. + +Terminology +=========== + +The terminology has changed since 0.1.x to better match the draft-hammer-oauth IETF +RFC. You can read that at http://tools.ietf.org/html/draft-hammer-oauth. Some of the +terms will differ from those Twitter uses as well. + +client credentials - Consumer key/secret you get when registering an app with Twitter. +temporary credentials - Previously known as the request token. +token credentials - Previously known as the access token. + +Parameters +========== + +There are a number of parameters you can modify after creating a TwitterOAuth object. + +Switch an existing TwitterOAuth install to use version 1.1 of the API. + + $connection->$host = "https://api.twitter.com/1.1/"; + +Custom useragent. + + $connection->useragent = 'Custom useragent string'; + +Verify Twitters SSL certificate. + + $connection->ssl_verifypeer = TRUE; + +There are several more you can find in TwitterOAuth.php. + +Extended flow using example code +================================ + +To use TwitterOAuth with the Twitter API you need *TwitterOAuth.php*, *OAuth.php* and +client credentials. You can get client credentials by registering your application at +[dev.twitter.com/apps](https://dev.twitter.com/apps). + +Users start out on connect.php which displays the "Sign in with Twitter" image hyperlinked +to redirect.php. This button should be displayed on your homepage in your login section. The +client credentials are saved in config.php as `CONSUMER_KEY` and `CONSUMER_SECRET`. You can +save a static callback URL in the app settings page, in the config file or use a dynamic +callback URL later in step 2. In example use https://example.com/callback.php. + +1) When a user lands on redirect.php we build a new TwitterOAuth object using the client credentials. +If you have your own configuration method feel free to use it instead of config.php. + + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); // Use config.php client credentials + $connection = new TwitterOAuth('abc890', '123xyz'); + +2) Using the built $connection object you will ask Twitter for temporary credentials. The `oauth_callback` value is required. + + $temporary_credentials = $connection->getRequestToken(OAUTH_CALLBACK); // Use config.php callback URL. + +3) Now that we have temporary credentials the user has to go to Twitter and authorize the app +to access and updates their data. You can also pass a second parameter of FALSE to not use [Sign +in with Twitter](https://dev.twitter.com/docs/auth/sign-twitter). + + $redirect_url = $connection->getAuthorizeURL($temporary_credentials); // Use Sign in with Twitter + $redirect_url = $connection->getAuthorizeURL($temporary_credentials, FALSE); + +4) You will now have a Twitter URL that you must send the user to. + + https://api.twitter.com/oauth/authenticate?oauth_token=xyz123 + +5) The user is now on twitter.com and may have to login. Once authenticated with Twitter they will +will either have to click on allow/deny, or will be automatically redirected back to the callback. + +6) Now that the user has returned to callback.php and allowed access we need to build a new +TwitterOAuth object using the temporary credentials. + + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'], + $_SESSION['oauth_token_secret']); + +7) Now we ask Twitter for long lasting token credentials. These are specific to the application +and user and will act like password to make future requests. Normally the token credentials would +get saved in your database but for this example we are just using sessions. + + $token_credentials = $connection->getAccessToken($_REQUEST['oauth_verifier']); + +8) With the token credentials we build a new TwitterOAuth object. + + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token_credentials['oauth_token'], + $token_credentials['oauth_token_secret']); + +9) And finally we can make requests authenticated as the user. You can GET, POST, and DELETE API +methods. Directly copy the path from the API documentation and add an array of any parameter +you wish to include for the API method such as curser or in_reply_to_status_id. + + $account = $connection->get('account/verify_credentials'); + $status = $connection->post('statuses/update', array('status' => 'Text of status here', 'in_reply_to_status_id' => 123456)); + $status = $connection->delete('statuses/destroy/12345'); + +Contributors +============ + +* [Abraham Williams](https://twitter.com/abraham) - Main developer, current maintainer. diff --git a/AvocadoEdition/plugin/sns/twitter/_common.php b/AvocadoEdition/plugin/sns/twitter/_common.php new file mode 100644 index 0000000..0319f1f --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/_common.php @@ -0,0 +1,3 @@ +<?php +include_once("../../../common.php"); +?> \ No newline at end of file diff --git a/AvocadoEdition/plugin/sns/twitter/callback-sample.php b/AvocadoEdition/plugin/sns/twitter/callback-sample.php new file mode 100644 index 0000000..fe55f88 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/callback-sample.php @@ -0,0 +1,40 @@ +<?php +/** + * @file + * Take the user when they return from Twitter. Get access tokens. + * Verify credentials and redirect to based on response from Twitter. + */ + +/* Start session and load lib */ +session_start(); +require_once('twitteroauth/twitteroauth.php'); +require_once('config.php'); + +/* If the oauth_token is old redirect to the connect page. */ +if (isset($_REQUEST['oauth_token']) && $_SESSION['oauth_token'] !== $_REQUEST['oauth_token']) { + $_SESSION['oauth_status'] = 'oldtoken'; + header('Location: ./clearsessions.php'); +} + +/* Create TwitteroAuth object with app key/secret and token key/secret from default phase */ +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'], $_SESSION['oauth_token_secret']); + +/* Request access tokens from twitter */ +$access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); + +/* Save the access tokens. Normally these would be saved in a database for future use. */ +$_SESSION['access_token'] = $access_token; + +/* Remove no longer needed request tokens */ +unset($_SESSION['oauth_token']); +unset($_SESSION['oauth_token_secret']); + +/* If HTTP response is 200 continue otherwise send to connect page to retry */ +if (200 == $connection->http_code) { + /* The user has been verified and the access tokens can be saved for future use */ + $_SESSION['status'] = 'verified'; + header('Location: ./index.php'); +} else { + /* Save HTTP status for error dialog on connnect page.*/ + header('Location: ./clearsessions.php'); +} diff --git a/AvocadoEdition/plugin/sns/twitter/callback.php b/AvocadoEdition/plugin/sns/twitter/callback.php new file mode 100644 index 0000000..ef42110 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/callback.php @@ -0,0 +1,88 @@ +<?php +include_once("./_common.php"); + +/** + * @file + * Take the user when they return from Twitter. Get access tokens. + * Verify credentials and redirect to based on response from Twitter. + */ + +/* Start session and load lib */ +//session_start(); +require_once(G5_SNS_PATH.'/twitter/twitteroauth/twitteroauth.php'); +require_once(G5_SNS_PATH.'/twitter/twitterconfig.php'); + +//print_r2($_SESSION); print_r2($_REQUEST); exit; + +/* If the oauth_token is old redirect to the connect page. */ +if (isset($_REQUEST['oauth_token']) && $_SESSION['oauth_token'] !== $_REQUEST['oauth_token']) { + $_SESSION['oauth_status'] = 'oldtoken'; + header('Location: ./clearsessions.php'); +} + +/* Create TwitteroAuth object with app key/secret and token key/secret from default phase */ +$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'], $_SESSION['oauth_token_secret']); + +/* Request access tokens from twitter */ +$access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); + +/* Save the access tokens. Normally these would be saved in a database for future use. */ +$_SESSION['access_token'] = $access_token; + +/* Remove no longer needed request tokens */ +unset($_SESSION['oauth_token']); +unset($_SESSION['oauth_token_secret']); + +/* +if (200 == $connection->http_code) { + $_SESSION['status'] = 'verified'; + header('Location: ./index.php'); +} else { + header('Location: ./clearsessions.php'); +} +exit; +*/ + +$g5['title'] = '트위터 콜백'; +include_once(G5_PATH.'/head.sub.php'); + +if (200 == $connection->http_code) { + $content = $connection->get('account/verify_credentials'); + $sns_name = $content->name; + $sns_user = $content->screen_name; + + set_cookie('ck_sns_name', $sns_name, 86400); + set_session('ss_twitter_user', $sns_user); + + $g5_sns_url = G5_SNS_URL; + + echo <<<EOT + <script> + $(function() { + document.write("<strong>트위터에 승인이 되었습니다.</strong>"); + + var opener = window.opener; + opener.$("#wr_name").val("{$sns_name}"); + opener.$("#twitter_icon").attr("src", "{$g5_sns_url}/icon/twitter.png"); + opener.$("#twitter_checked").attr("disabled", false); + opener.$("#twitter_checked").attr("checked", true); + window.close(); + }); + </script> +EOT; + +} else { + + echo <<<EOT + <script> + $(function() { + alert("트위터에 승인이 되지 않았습니다."); + window.close(); + }); + </script> +EOT; + +} + +include_once(G5_PATH.'/tail.sub.php'); +?> diff --git a/AvocadoEdition/plugin/sns/twitter/clearsessions.php b/AvocadoEdition/plugin/sns/twitter/clearsessions.php new file mode 100644 index 0000000..2947d62 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/clearsessions.php @@ -0,0 +1,14 @@ +<?php +include_once("./_common.php"); + +/** + * @file + * Clears PHP sessions and redirects to the connect page. + */ + +/* Load and clear sessions */ +session_start(); +session_destroy(); + +/* Redirect to page with the connect to Twitter option. */ +header('Location: ./connect.php'); diff --git a/AvocadoEdition/plugin/sns/twitter/config-sample.php b/AvocadoEdition/plugin/sns/twitter/config-sample.php new file mode 100644 index 0000000..1f1eeb0 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/config-sample.php @@ -0,0 +1,10 @@ +<?php + +/** + * @file + * A single location to store configuration. + */ + +define('CONSUMER_KEY', 'CONSUMER_KEY_HERE'); +define('CONSUMER_SECRET', 'CONSUMER_SECRET_HERE'); +define('OAUTH_CALLBACK', 'http://example.com/twitteroauth/callback.php'); diff --git a/AvocadoEdition/plugin/sns/twitter/connect.php b/AvocadoEdition/plugin/sns/twitter/connect.php new file mode 100644 index 0000000..6aad4db --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/connect.php @@ -0,0 +1,22 @@ +<?php +include_once("./_common.php"); + +/** + * @file + * Check if consumer token is set and if so send user to get a request token. + */ + +/** + * Exit with an error message if the CONSUMER_KEY or CONSUMER_SECRET is not defined. + */ +require_once(G5_SNS_PATH.'/twitter/twitterconfig.php'); +if (CONSUMER_KEY === '' || CONSUMER_SECRET === '' || CONSUMER_KEY === 'CONSUMER_KEY_HERE' || CONSUMER_SECRET === 'CONSUMER_SECRET_HERE') { + echo 'You need a consumer key and secret to test the sample code. Get one from <a href="https://dev.twitter.com/apps">dev.twitter.com/apps</a>'; + exit; +} + +/* Build an image link to start the redirect process. */ +$content = '<a href="./redirect.php"><img src="./images/lighter.png" alt="Sign in with Twitter"/></a>'; + +/* Include HTML to display on the page. */ +include('html.inc'); diff --git a/AvocadoEdition/plugin/sns/twitter/html.inc b/AvocadoEdition/plugin/sns/twitter/html.inc new file mode 100644 index 0000000..e093e35 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/html.inc @@ -0,0 +1,39 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> + <head> + <title>Twitter OAuth in PHP + + + + +
    +

    Welcome to a Twitter OAuth PHP example.

    + +

    This site is a basic showcase of Twitters OAuth authentication method. If you are having issues try clearing your session.

    + +

    + Links: + Source Code & + Documentation | + Contact @abraham +

    +
    + + + +
    + + '.$status_text.''; ?> + +

    +

    +        
    +      
    +

    + + + diff --git a/AvocadoEdition/plugin/sns/twitter/images/darker.png b/AvocadoEdition/plugin/sns/twitter/images/darker.png new file mode 100644 index 0000000000000000000000000000000000000000..746b6b9f80c71049f2a4eb84ff72d5d1bf77c62c GIT binary patch literal 2370 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/plugin/sns/twitter/images/lighter.png b/AvocadoEdition/plugin/sns/twitter/images/lighter.png new file mode 100644 index 0000000000000000000000000000000000000000..297bb03404f2d7462ee9355aae38f5f5f3e47fbd GIT binary patch literal 2490 zcmV;r2}SmaP)dbVG7wVRUJ4ZXi@?ZDjy8FEKeU zFgbGL({lg-0338hSaefwW^{L9a%BKPWN%_+AVz6&Wp{6KYjYq&Q#1y$)1UwV2@^>~ zK~!jg?VEdWl+_u=f8X9WA)72QVM!vF1VSK4AZQ?nK}o}NseS3JN$f zgRQMIo!W~OJ6`ZouvAJ_K&eH%O=zU35Dd9+OGJ}EvYTu++57IdU;kJVc9XpY6B?a; zX3k{ZIp=-eC+|7m`<-)kR{+>vQ7sWi9D|5ebEgWz_KIq$s4!>9f*d_|j-lj_V|e1| zv2!Q@e7>PCTvsDT9K#C=07>!<2 zJRT3v{^4m(e0B`AMuXes=AQD^+;C$tPj22q>4H*zdfz>`#KAid3>9xAeo+*W%jE#P zv+pgwyLbU*^X6iX@D|vxdJPV{BV^y=rMIzo>FtA}CzL%H7|@3PC-uR0k{o`MEpT&+ zmiCUwd$DjaD&G5mR^R=5Ugy>A zFL6`pd;osE=`rd~)-ZEc5shchvh}x5aZ~9nJpS;;UjCggyhMFX4IM@k^;K2OnpeX9 zJ+G59W-M>Ndx+<@J`*QB2?^MN1N-(fead7?=HEi6T!B@Box5IR=L;`>Ej{PX zHuTf??pp_V_K#2V&%f=WuDXUP)2>6K(eP;bS}ruV@b7*5sr;ydIrB8I2tIsDgsYdEB~aA*X6k7? zxX|2;qp^|Gwe@`Y#d&IupCC)EqUw`l7)GU&uTKu*U$o?QG#U*z%qZYj8`hDRoCLu8 zhbzgOI5DbLyT^;&?d{E@=<{Loc(HlBWQ@7?YwIarxgyB6oH@guS9eiXI-mWozJlq( z1uEY@fC2%N(MZ*iqs%Lw&3$(-XHs%f#Ci8GF3A_N^~J`q@N(Yec4#`>p8;Rm>`^(w z^()mX);zY6A1}KTOQ(hBpZ+tI2M_vvC6EgOasg^TuSW9u`2L~=xMTvlF=IdirA&q( z01}jz+(`M#6-+Id=Jypvl2wZSngV!x>{xvBuA7QRt)c4kYU--0D3~!Fhr>aA^+`_G z)iHDWG@POs#IMsQgCL+*sYp&si#>KieJ zAZPaXZl!3>9M-SjNX7dfvh?=bdf)$&1YWO*1jqy#ZFVPakM~lt{ns24pi(Mnce*e+ zoV|U5)IWA0uWtapa=C)>xf3{EU4zZ(WX19y(%RC@hySVMd_x1@*}REPr@KGD1PCBr zszd|P3jULJU(P|*6JUEpf1ZUYMN@b5y{gO~R0`R^ zzo2^1b1iYS>vBugsL9qPM&yVTyCwWp(Uo=ev@y*W7rS{ZmOePbh#j}_&X%YtxeZa(=9L5<&(e8Bi z<5wsYm^&^0MKr*8(egMLdIIf9`S}2Jn9Y=xl~T570XoAdF4!DlHH6a}anEJ-cv*VQ z<;7KRgYq-}Q)5qi@;qcECS38JtLDV#Y+3g(n;(3LUp}&dB%O}ct5)I-xFV2%>k11g zTUf@C&yKTa*KVdw^(R50loR*{_b2SKCHeZt4jkLpj^;ZlKOe6sQZ!>aT9uM(b0*;N zdYL_=0IS=B(gj7|CTgIo3w=s5DLNgUE;lDl z=6*ck(9~r1FRqNt5);TzP2p%4ylH~wfExv!+`pk8s}?!j(i+mgrP)GJVGd2L zrifxR3OQ=I9MLCX4Ray;#3LJ#2{HtkfT^vG#S0hk#JUIhwAC2&WDQrS)2nfk*V=iQ!Y2K(sVlqHpM%x^1{ck;y4Kin5jc`W;@8<8AFx4+YWs z?QSo2A}4+Q<6F?#y0F{rget('account/verify_credentials'); + +/* Some example calls */ +//$connection->get('users/show', array('screen_name' => 'abraham')); +//$connection->post('statuses/update', array('status' => date(DATE_RFC822))); +//$connection->post('statuses/destroy', array('id' => 5437877770)); +//$connection->post('friendships/create', array('id' => 9436992)); +//$connection->post('friendships/destroy', array('id' => 9436992)); + +/* Include HTML to display on the page */ +include('html.inc'); diff --git a/AvocadoEdition/plugin/sns/twitter/redirect.php b/AvocadoEdition/plugin/sns/twitter/redirect.php new file mode 100644 index 0000000..4bc1586 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/redirect.php @@ -0,0 +1,31 @@ +getRequestToken(OAUTH_CALLBACK); + +/* Save temporary credentials to session. */ +$_SESSION['oauth_token'] = $token = $request_token['oauth_token']; +$_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; + +//print_r2($_SESSION); exit; + +/* If last connection failed don't display authorization link. */ +switch ($connection->http_code) { + case 200: + /* Build authorize URL and redirect user to Twitter. */ + $url = $connection->getAuthorizeURL($token); + header('Location: ' . $url); + break; + default: + /* Show notification if something went wrong. */ + echo 'Could not connect to Twitter. Refresh the page or try again later.'; +} diff --git a/AvocadoEdition/plugin/sns/twitter/twitterconfig.php b/AvocadoEdition/plugin/sns/twitter/twitterconfig.php new file mode 100644 index 0000000..84c49a0 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/twitterconfig.php @@ -0,0 +1,10 @@ +key = $key; + $this->secret = $secret; + $this->callback_url = $callback_url; + } + + function __toString() { + return "OAuthConsumer[key=$this->key,secret=$this->secret]"; + } +} + +class OAuthToken { + // access tokens and request tokens + public $key; + public $secret; + + /** + * key = the token + * secret = the token secret + */ + function __construct($key, $secret) { + $this->key = $key; + $this->secret = $secret; + } + + /** + * generates the basic string serialization of a token that a server + * would respond to request_token and access_token calls with + */ + function to_string() { + return "oauth_token=" . + OAuthUtil::urlencode_rfc3986($this->key) . + "&oauth_token_secret=" . + OAuthUtil::urlencode_rfc3986($this->secret); + } + + function __toString() { + return $this->to_string(); + } +} + +/** + * A class for implementing a Signature Method + * See section 9 ("Signing Requests") in the spec + */ +abstract class OAuthSignatureMethod { + /** + * Needs to return the name of the Signature Method (ie HMAC-SHA1) + * @return string + */ + abstract public function get_name(); + + /** + * Build up the signature + * NOTE: The output of this function MUST NOT be urlencoded. + * the encoding is handled in OAuthRequest when the final + * request is serialized + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @return string + */ + abstract public function build_signature($request, $consumer, $token); + + /** + * Verifies that a given signature is correct + * @param OAuthRequest $request + * @param OAuthConsumer $consumer + * @param OAuthToken $token + * @param string $signature + * @return bool + */ + public function check_signature($request, $consumer, $token, $signature) { + $built = $this->build_signature($request, $consumer, $token); + return $built == $signature; + } +} + +/** + * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] + * where the Signature Base String is the text and the key is the concatenated values (each first + * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&' + * character (ASCII code 38) even if empty. + * - Chapter 9.2 ("HMAC-SHA1") + */ +class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod { + function get_name() { + return "HMAC-SHA1"; + } + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + + return base64_encode(hash_hmac('sha1', $base_string, $key, true)); + } +} + +/** + * The PLAINTEXT method does not provide any security protection and SHOULD only be used + * over a secure channel such as HTTPS. It does not use the Signature Base String. + * - Chapter 9.4 ("PLAINTEXT") + */ +class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod { + public function get_name() { + return "PLAINTEXT"; + } + + /** + * oauth_signature is set to the concatenated encoded values of the Consumer Secret and + * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is + * empty. The result MUST be encoded again. + * - Chapter 9.4.1 ("Generating Signatures") + * + * Please note that the second encoding MUST NOT happen in the SignatureMethod, as + * OAuthRequest handles this! + */ + public function build_signature($request, $consumer, $token) { + $key_parts = array( + $consumer->secret, + ($token) ? $token->secret : "" + ); + + $key_parts = OAuthUtil::urlencode_rfc3986($key_parts); + $key = implode('&', $key_parts); + $request->base_string = $key; + + return $key; + } +} + +/** + * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in + * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for + * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a + * verified way to the Service Provider, in a manner which is beyond the scope of this + * specification. + * - Chapter 9.3 ("RSA-SHA1") + */ +abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod { + public function get_name() { + return "RSA-SHA1"; + } + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // (2) fetch via http using a url provided by the requester + // (3) some sort of specific discovery code based on request + // + // Either way should return a string representation of the certificate + protected abstract function fetch_public_cert(&$request); + + // Up to the SP to implement this lookup of keys. Possible ideas are: + // (1) do a lookup in a table of trusted certs keyed off of consumer + // + // Either way should return a string representation of the certificate + protected abstract function fetch_private_cert(&$request); + + public function build_signature($request, $consumer, $token) { + $base_string = $request->get_signature_base_string(); + $request->base_string = $base_string; + + // Fetch the private key cert based on the request + $cert = $this->fetch_private_cert($request); + + // Pull the private key ID from the certificate + $privatekeyid = openssl_get_privatekey($cert); + + // Sign using the key + $ok = openssl_sign($base_string, $signature, $privatekeyid); + + // Release the key resource + openssl_free_key($privatekeyid); + + return base64_encode($signature); + } + + public function check_signature($request, $consumer, $token, $signature) { + $decoded_sig = base64_decode($signature); + + $base_string = $request->get_signature_base_string(); + + // Fetch the public key cert based on the request + $cert = $this->fetch_public_cert($request); + + // Pull the public key ID from the certificate + $publickeyid = openssl_get_publickey($cert); + + // Check the computed signature against the one passed in the query + $ok = openssl_verify($base_string, $decoded_sig, $publickeyid); + + // Release the key resource + openssl_free_key($publickeyid); + + return $ok == 1; + } +} + +class OAuthRequest { + private $parameters; + private $http_method; + private $http_url; + // for debug purposes + public $base_string; + public static $version = '1.0'; + public static $POST_INPUT = 'php://input'; + + function __construct($http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters); + $this->parameters = $parameters; + $this->http_method = $http_method; + $this->http_url = $http_url; + } + + + /** + * attempt to build up a request from what was passed to the server + */ + public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) { + $scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on") + ? 'http' + : 'https'; + @$http_url or $http_url = $scheme . + '://' . $_SERVER['HTTP_HOST'] . + ':' . + $_SERVER['SERVER_PORT'] . + $_SERVER['REQUEST_URI']; + @$http_method or $http_method = $_SERVER['REQUEST_METHOD']; + + // We weren't handed any parameters, so let's find the ones relevant to + // this request. + // If you run XML-RPC or similar you should use this to provide your own + // parsed parameter-list + if (!$parameters) { + // Find request headers + $request_headers = OAuthUtil::get_headers(); + + // Parse the query-string to find GET parameters + $parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']); + + // It's a POST request of the proper content-type, so parse POST + // parameters and add those overriding any duplicates from GET + if ($http_method == "POST" + && @strstr($request_headers["Content-Type"], + "application/x-www-form-urlencoded") + ) { + $post_data = OAuthUtil::parse_parameters( + file_get_contents(self::$POST_INPUT) + ); + $parameters = array_merge($parameters, $post_data); + } + + // We have a Authorization-header with OAuth data. Parse the header + // and add those overriding any duplicates from GET or POST + if (@substr($request_headers['Authorization'], 0, 6) == "OAuth ") { + $header_parameters = OAuthUtil::split_header( + $request_headers['Authorization'] + ); + $parameters = array_merge($parameters, $header_parameters); + } + + } + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + /** + * pretty much a helper function to set up the request + */ + public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) { + @$parameters or $parameters = array(); + $defaults = array("oauth_version" => OAuthRequest::$version, + "oauth_nonce" => OAuthRequest::generate_nonce(), + "oauth_timestamp" => OAuthRequest::generate_timestamp(), + "oauth_consumer_key" => $consumer->key); + if ($token) + $defaults['oauth_token'] = $token->key; + + $parameters = array_merge($defaults, $parameters); + + return new OAuthRequest($http_method, $http_url, $parameters); + } + + public function set_parameter($name, $value, $allow_duplicates = true) { + if ($allow_duplicates && isset($this->parameters[$name])) { + // We have already added parameter(s) with this name, so add to the list + if (is_scalar($this->parameters[$name])) { + // This is the first duplicate, so transform scalar (string) + // into an array so we can add the duplicates + $this->parameters[$name] = array($this->parameters[$name]); + } + + $this->parameters[$name][] = $value; + } else { + $this->parameters[$name] = $value; + } + } + + public function get_parameter($name) { + return isset($this->parameters[$name]) ? $this->parameters[$name] : null; + } + + public function get_parameters() { + return $this->parameters; + } + + public function unset_parameter($name) { + unset($this->parameters[$name]); + } + + /** + * The request parameters, sorted and concatenated into a normalized string. + * @return string + */ + public function get_signable_parameters() { + // Grab all parameters + $params = $this->parameters; + + // Remove oauth_signature if present + // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.") + if (isset($params['oauth_signature'])) { + unset($params['oauth_signature']); + } + + return OAuthUtil::build_http_query($params); + } + + /** + * Returns the base string of this request + * + * The base string defined as the method, the url + * and the parameters (normalized), each urlencoded + * and the concated with &. + */ + public function get_signature_base_string() { + $parts = array( + $this->get_normalized_http_method(), + $this->get_normalized_http_url(), + $this->get_signable_parameters() + ); + + $parts = OAuthUtil::urlencode_rfc3986($parts); + + return implode('&', $parts); + } + + /** + * just uppercases the http method + */ + public function get_normalized_http_method() { + return strtoupper($this->http_method); + } + + /** + * parses the url and rebuilds it to be + * scheme://host/path + */ + public function get_normalized_http_url() { + $parts = parse_url($this->http_url); + + $port = @$parts['port']; + $scheme = $parts['scheme']; + $host = $parts['host']; + $path = @$parts['path']; + + $port or $port = ($scheme == 'https') ? '443' : '80'; + + if (($scheme == 'https' && $port != '443') + || ($scheme == 'http' && $port != '80')) { + $host = "$host:$port"; + } + return "$scheme://$host$path"; + } + + /** + * builds a url usable for a GET request + */ + public function to_url() { + $post_data = $this->to_postdata(); + $out = $this->get_normalized_http_url(); + if ($post_data) { + $out .= '?'.$post_data; + } + return $out; + } + + /** + * builds the data one would send in a POST request + */ + public function to_postdata() { + return OAuthUtil::build_http_query($this->parameters); + } + + /** + * builds the Authorization: header + */ + public function to_header($realm=null) { + $first = true; + if($realm) { + $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"'; + $first = false; + } else + $out = 'Authorization: OAuth'; + + $total = array(); + foreach ($this->parameters as $k => $v) { + if (substr($k, 0, 5) != "oauth") continue; + if (is_array($v)) { + throw new OAuthException('Arrays not supported in headers'); + } + $out .= ($first) ? ' ' : ','; + $out .= OAuthUtil::urlencode_rfc3986($k) . + '="' . + OAuthUtil::urlencode_rfc3986($v) . + '"'; + $first = false; + } + return $out; + } + + public function __toString() { + return $this->to_url(); + } + + + public function sign_request($signature_method, $consumer, $token) { + $this->set_parameter( + "oauth_signature_method", + $signature_method->get_name(), + false + ); + $signature = $this->build_signature($signature_method, $consumer, $token); + $this->set_parameter("oauth_signature", $signature, false); + } + + public function build_signature($signature_method, $consumer, $token) { + $signature = $signature_method->build_signature($this, $consumer, $token); + return $signature; + } + + /** + * util function: current timestamp + */ + private static function generate_timestamp() { + return time(); + } + + /** + * util function: current nonce + */ + private static function generate_nonce() { + $mt = microtime(); + $rand = mt_rand(); + + return md5($mt . $rand); // md5s look nicer than numbers + } +} + +class OAuthServer { + protected $timestamp_threshold = 300; // in seconds, five minutes + protected $version = '1.0'; // hi blaine + protected $signature_methods = array(); + + protected $data_store; + + function __construct($data_store) { + $this->data_store = $data_store; + } + + public function add_signature_method($signature_method) { + $this->signature_methods[$signature_method->get_name()] = + $signature_method; + } + + // high level functions + + /** + * process a request_token request + * returns the request token on success + */ + public function fetch_request_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // no token required for the initial token request + $token = NULL; + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $callback = $request->get_parameter('oauth_callback'); + $new_token = $this->data_store->new_request_token($consumer, $callback); + + return $new_token; + } + + /** + * process an access_token request + * returns the access token on success + */ + public function fetch_access_token(&$request) { + $this->get_version($request); + + $consumer = $this->get_consumer($request); + + // requires authorized request token + $token = $this->get_token($request, $consumer, "request"); + + $this->check_signature($request, $consumer, $token); + + // Rev A change + $verifier = $request->get_parameter('oauth_verifier'); + $new_token = $this->data_store->new_access_token($token, $consumer, $verifier); + + return $new_token; + } + + /** + * verify an api call, checks all the parameters + */ + public function verify_request(&$request) { + $this->get_version($request); + $consumer = $this->get_consumer($request); + $token = $this->get_token($request, $consumer, "access"); + $this->check_signature($request, $consumer, $token); + return array($consumer, $token); + } + + // Internals from here + /** + * version 1 + */ + private function get_version(&$request) { + $version = $request->get_parameter("oauth_version"); + if (!$version) { + // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present. + // Chapter 7.0 ("Accessing Protected Ressources") + $version = '1.0'; + } + if ($version !== $this->version) { + throw new OAuthException("OAuth version '$version' not supported"); + } + return $version; + } + + /** + * figure out the signature with some defaults + */ + private function get_signature_method(&$request) { + $signature_method = + @$request->get_parameter("oauth_signature_method"); + + if (!$signature_method) { + // According to chapter 7 ("Accessing Protected Ressources") the signature-method + // parameter is required, and we can't just fallback to PLAINTEXT + throw new OAuthException('No signature method parameter. This parameter is required'); + } + + if (!in_array($signature_method, + array_keys($this->signature_methods))) { + throw new OAuthException( + "Signature method '$signature_method' not supported " . + "try one of the following: " . + implode(", ", array_keys($this->signature_methods)) + ); + } + return $this->signature_methods[$signature_method]; + } + + /** + * try to find the consumer for the provided request's consumer key + */ + private function get_consumer(&$request) { + $consumer_key = @$request->get_parameter("oauth_consumer_key"); + if (!$consumer_key) { + throw new OAuthException("Invalid consumer key"); + } + + $consumer = $this->data_store->lookup_consumer($consumer_key); + if (!$consumer) { + throw new OAuthException("Invalid consumer"); + } + + return $consumer; + } + + /** + * try to find the token for the provided request's token key + */ + private function get_token(&$request, $consumer, $token_type="access") { + $token_field = @$request->get_parameter('oauth_token'); + $token = $this->data_store->lookup_token( + $consumer, $token_type, $token_field + ); + if (!$token) { + throw new OAuthException("Invalid $token_type token: $token_field"); + } + return $token; + } + + /** + * all-in-one function to check the signature on a request + * should guess the signature method appropriately + */ + private function check_signature(&$request, $consumer, $token) { + // this should probably be in a different method + $timestamp = @$request->get_parameter('oauth_timestamp'); + $nonce = @$request->get_parameter('oauth_nonce'); + + $this->check_timestamp($timestamp); + $this->check_nonce($consumer, $token, $nonce, $timestamp); + + $signature_method = $this->get_signature_method($request); + + $signature = $request->get_parameter('oauth_signature'); + $valid_sig = $signature_method->check_signature( + $request, + $consumer, + $token, + $signature + ); + + if (!$valid_sig) { + throw new OAuthException("Invalid signature"); + } + } + + /** + * check that the timestamp is new enough + */ + private function check_timestamp($timestamp) { + if( ! $timestamp ) + throw new OAuthException( + 'Missing timestamp parameter. The parameter is required' + ); + + // verify that timestamp is recentish + $now = time(); + if (abs($now - $timestamp) > $this->timestamp_threshold) { + throw new OAuthException( + "Expired timestamp, yours $timestamp, ours $now" + ); + } + } + + /** + * check that the nonce is not repeated + */ + private function check_nonce($consumer, $token, $nonce, $timestamp) { + if( ! $nonce ) + throw new OAuthException( + 'Missing nonce parameter. The parameter is required' + ); + + // verify that the nonce is uniqueish + $found = $this->data_store->lookup_nonce( + $consumer, + $token, + $nonce, + $timestamp + ); + if ($found) { + throw new OAuthException("Nonce already used: $nonce"); + } + } + +} + +class OAuthDataStore { + function lookup_consumer($consumer_key) { + // implement me + } + + function lookup_token($consumer, $token_type, $token) { + // implement me + } + + function lookup_nonce($consumer, $token, $nonce, $timestamp) { + // implement me + } + + function new_request_token($consumer, $callback = null) { + // return a new token attached to this consumer + } + + function new_access_token($token, $consumer, $verifier = null) { + // return a new access token attached to this consumer + // for the user associated with this token if the request token + // is authorized + // should also invalidate the request token + } + +} + +class OAuthUtil { + public static function urlencode_rfc3986($input) { + if (is_array($input)) { + return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input); + } else if (is_scalar($input)) { + return str_replace( + '+', + ' ', + str_replace('%7E', '~', rawurlencode($input)) + ); + } else { + return ''; + } +} + + + // This decode function isn't taking into consideration the above + // modifications to the encoding process. However, this method doesn't + // seem to be used anywhere so leaving it as is. + public static function urldecode_rfc3986($string) { + return urldecode($string); + } + + // Utility function for turning the Authorization: header into + // parameters, has to do some unescaping + // Can filter out any non-oauth parameters if needed (default behaviour) + public static function split_header($header, $only_allow_oauth_parameters = true) { + $pattern = '/(([-_a-z]*)=("([^"]*)"|([^,]*)),?)/'; + $offset = 0; + $params = array(); + while (preg_match($pattern, $header, $matches, PREG_OFFSET_CAPTURE, $offset) > 0) { + $match = $matches[0]; + $header_name = $matches[2][0]; + $header_content = (isset($matches[5])) ? $matches[5][0] : $matches[4][0]; + if (preg_match('/^oauth_/', $header_name) || !$only_allow_oauth_parameters) { + $params[$header_name] = OAuthUtil::urldecode_rfc3986($header_content); + } + $offset = $match[1] + strlen($match[0]); + } + + if (isset($params['realm'])) { + unset($params['realm']); + } + + return $params; + } + + // helper to try to sort out headers for people who aren't running apache + public static function get_headers() { + if (function_exists('apache_request_headers')) { + // we need this to get the actual Authorization: header + // because apache tends to tell us it doesn't exist + $headers = apache_request_headers(); + + // sanitize the output of apache_request_headers because + // we always want the keys to be Cased-Like-This and arh() + // returns the headers in the same case as they are in the + // request + $out = array(); + foreach( $headers AS $key => $value ) { + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("-", " ", $key))) + ); + $out[$key] = $value; + } + } else { + // otherwise we don't have apache and are just going to have to hope + // that $_SERVER actually contains what we need + $out = array(); + if( isset($_SERVER['CONTENT_TYPE']) ) + $out['Content-Type'] = $_SERVER['CONTENT_TYPE']; + if( isset($_ENV['CONTENT_TYPE']) ) + $out['Content-Type'] = $_ENV['CONTENT_TYPE']; + + foreach ($_SERVER as $key => $value) { + if (substr($key, 0, 5) == "HTTP_") { + // this is chaos, basically it is just there to capitalize the first + // letter of every word that is not an initial HTTP and strip HTTP + // code from przemek + $key = str_replace( + " ", + "-", + ucwords(strtolower(str_replace("_", " ", substr($key, 5)))) + ); + $out[$key] = $value; + } + } + } + return $out; + } + + // This function takes a input like a=b&a=c&d=e and returns the parsed + // parameters like this + // array('a' => array('b','c'), 'd' => 'e') + public static function parse_parameters( $input ) { + if (!isset($input) || !$input) return array(); + + $pairs = explode('&', $input); + + $parsed_parameters = array(); + foreach ($pairs as $pair) { + $split = explode('=', $pair, 2); + $parameter = OAuthUtil::urldecode_rfc3986($split[0]); + $value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : ''; + + if (isset($parsed_parameters[$parameter])) { + // We have already recieved parameter(s) with this name, so add to the list + // of parameters with this name + + if (is_scalar($parsed_parameters[$parameter])) { + // This is the first duplicate, so transform scalar (string) into an array + // so we can add the duplicates + $parsed_parameters[$parameter] = array($parsed_parameters[$parameter]); + } + + $parsed_parameters[$parameter][] = $value; + } else { + $parsed_parameters[$parameter] = $value; + } + } + return $parsed_parameters; + } + + public static function build_http_query($params) { + if (!$params) return ''; + + // Urlencode both keys and values + $keys = OAuthUtil::urlencode_rfc3986(array_keys($params)); + $values = OAuthUtil::urlencode_rfc3986(array_values($params)); + $params = array_combine($keys, $values); + + // Parameters are sorted by name, using lexicographical byte value ordering. + // Ref: Spec: 9.1.1 (1) + uksort($params, 'strcmp'); + + $pairs = array(); + foreach ($params as $parameter => $value) { + if (is_array($value)) { + // If two or more parameters share the same name, they are sorted by their value + // Ref: Spec: 9.1.1 (1) + natsort($value); + foreach ($value as $duplicate_value) { + $pairs[] = $parameter . '=' . $duplicate_value; + } + } else { + $pairs[] = $parameter . '=' . $value; + } + } + // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61) + // Each name-value pair is separated by an '&' character (ASCII code 38) + return implode('&', $pairs); + } +} diff --git a/AvocadoEdition/plugin/sns/twitter/twitteroauth/twitteroauth.php b/AvocadoEdition/plugin/sns/twitter/twitteroauth/twitteroauth.php new file mode 100644 index 0000000..af87122 --- /dev/null +++ b/AvocadoEdition/plugin/sns/twitter/twitteroauth/twitteroauth.php @@ -0,0 +1,241 @@ +http_status; } + function lastAPICall() { return $this->last_api_call; } + + /** + * construct TwitterOAuth object + */ + function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) { + $this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1(); + $this->consumer = new OAuthConsumer($consumer_key, $consumer_secret); + if (!empty($oauth_token) && !empty($oauth_token_secret)) { + $this->token = new OAuthConsumer($oauth_token, $oauth_token_secret); + } else { + $this->token = NULL; + } + } + + + /** + * Get a request_token from Twitter + * + * @returns a key/value array containing oauth_token and oauth_token_secret + */ + function getRequestToken($oauth_callback) { + $parameters = array(); + $parameters['oauth_callback'] = $oauth_callback; + $request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * Get the authorize URL + * + * @returns a string + */ + function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) { + if (is_array($token)) { + $token = $token['oauth_token']; + } + if (empty($sign_in_with_twitter)) { + return $this->authorizeURL() . "?oauth_token={$token}"; + } else { + return $this->authenticateURL() . "?oauth_token={$token}"; + } + } + + /** + * Exchange request token and secret for an access token and + * secret, to sign API calls. + * + * @returns array("oauth_token" => "the-access-token", + * "oauth_token_secret" => "the-access-secret", + * "user_id" => "9436992", + * "screen_name" => "abraham") + */ + function getAccessToken($oauth_verifier) { + $parameters = array(); + $parameters['oauth_verifier'] = $oauth_verifier; + $request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * One time exchange of username and password for access token and secret. + * + * @returns array("oauth_token" => "the-access-token", + * "oauth_token_secret" => "the-access-secret", + * "user_id" => "9436992", + * "screen_name" => "abraham", + * "x_auth_expires" => "0") + */ + function getXAuthToken($username, $password) { + $parameters = array(); + $parameters['x_auth_username'] = $username; + $parameters['x_auth_password'] = $password; + $parameters['x_auth_mode'] = 'client_auth'; + $request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters); + $token = OAuthUtil::parse_parameters($request); + $this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']); + return $token; + } + + /** + * GET wrapper for oAuthRequest. + */ + function get($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'GET', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * POST wrapper for oAuthRequest. + */ + function post($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'POST', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * DELETE wrapper for oAuthReqeust. + */ + function delete($url, $parameters = array()) { + $response = $this->oAuthRequest($url, 'DELETE', $parameters); + if ($this->format === 'json' && $this->decode_json) { + return json_decode($response); + } + return $response; + } + + /** + * Format and sign an OAuth / API request + */ + function oAuthRequest($url, $method, $parameters) { + if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) { + $url = "{$this->host}{$url}.{$this->format}"; + } + $request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters); + $request->sign_request($this->sha1_method, $this->consumer, $this->token); + switch ($method) { + case 'GET': + return $this->http($request->to_url(), 'GET'); + default: + return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata()); + } + } + + /** + * Make an HTTP request + * + * @return API results + */ + function http($url, $method, $postfields = NULL) { + $this->http_info = array(); + $ci = curl_init(); + /* Curl settings */ + curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent); + curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout); + curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout); + curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:')); + curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer); + curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader')); + curl_setopt($ci, CURLOPT_HEADER, FALSE); + + switch ($method) { + case 'POST': + curl_setopt($ci, CURLOPT_POST, TRUE); + if (!empty($postfields)) { + curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields); + } + break; + case 'DELETE': + curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE'); + if (!empty($postfields)) { + $url = "{$url}?{$postfields}"; + } + } + + curl_setopt($ci, CURLOPT_URL, $url); + $response = curl_exec($ci); + $this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE); + $this->http_info = array_merge($this->http_info, curl_getinfo($ci)); + $this->url = $url; + curl_close ($ci); + return $response; + } + + /** + * Get the header info to store. + */ + function getHeader($ch, $header) { + $i = strpos($header, ':'); + if (!empty($i)) { + $key = str_replace('-', '_', strtolower(substr($header, 0, $i))); + $value = trim(substr($header, $i + 2)); + $this->http_header[$key] = $value; + } + return strlen($header); + } +} diff --git a/AvocadoEdition/plugin/sns/view.sns.skin.php b/AvocadoEdition/plugin/sns/view.sns.skin.php new file mode 100644 index 0000000..5a44dbe --- /dev/null +++ b/AvocadoEdition/plugin/sns/view.sns.skin.php @@ -0,0 +1,41 @@ + + + + + + + + +
      +
    • 페이스북으로 보내기
    • +
    • 트위터로 보내기
    • +
    • 구글플러스로 보내기
    • + +
    • 카카오톡으로 보내기
    • + +
    diff --git a/AvocadoEdition/plugin/sns/view_comment_list.sns.skin.php b/AvocadoEdition/plugin/sns/view_comment_list.sns.skin.php new file mode 100644 index 0000000..1136ddb --- /dev/null +++ b/AvocadoEdition/plugin/sns/view_comment_list.sns.skin.php @@ -0,0 +1,15 @@ + + +페이스북에도 등록됨 + + +트위터에도 등록됨 + diff --git a/AvocadoEdition/plugin/sns/view_comment_write.sns.skin.php b/AvocadoEdition/plugin/sns/view_comment_write.sns.skin.php new file mode 100644 index 0000000..ba0031c --- /dev/null +++ b/AvocadoEdition/plugin/sns/view_comment_write.sns.skin.php @@ -0,0 +1,108 @@ + + +
      + $config['cf_facebook_appid'], + 'secret' => $config['cf_facebook_secret'] + )); + + $facebook_user = $facebook->getUser(); + + if ($facebook_user) { + try { + $facebook_user_profile = $facebook->api('/me'); + } catch (FacebookApiException $e) { + error_log($e); + $facebook_user = null; + } + } + } + + echo '
    • '; + if ($facebook_user) { + echo ''; + echo ''; + echo ''; + } else { + $facebook_url = $facebook->getLoginUrl(array("redirect_uri"=>G5_SNS_URL."/facebook/callback.php", "scope"=>"publish_stream,read_stream,offline_access", "display"=>"popup")); + + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
    • '; +} +//============================================================================ + + +//============================================================================ +// 트위터 +//---------------------------------------------------------------------------- +if ($config['cf_twitter_key']) { + $twitter_user = get_session("ss_twitter_user"); + if (!$twitter_user) { + include_once(G5_SNS_PATH."/twitter/twitteroauth/twitteroauth.php"); + include_once(G5_SNS_PATH."/twitter/twitterconfig.php"); + + $twitter_user = false; + /* + if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) { + $twitter_url = G5_SNS_URL."/twitter/redirect.php"; + } else { + $access_token = $_SESSION['access_token']; + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); + $content = $connection->get('account/verify_credentials'); + + switch ($connection->http_code) { + case 200: + $twitter_user = true; + $twitter_url = $connection->getAuthorizeURL($token); + break; + default : + $twitter_url = G5_SNS_URL."/twitter/redirect.php"; + } + } + */ + $access_token = $_SESSION['access_token']; + $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); + $content = $connection->get('account/verify_credentials'); + + switch ($connection->http_code) { + case 200: + $twitter_user = true; + $twitter_url = $connection->getAuthorizeURL($token); + break; + default : + $twitter_url = G5_SNS_URL."/twitter/redirect.php"; + } + } + + echo '
    • '; + if ($twitter_user) { + echo ''; + echo ''; + echo ''; + } else { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
    • '; +} +//============================================================================ +?> +
    \ No newline at end of file diff --git a/AvocadoEdition/plugin/syndi/_common.php b/AvocadoEdition/plugin/syndi/_common.php new file mode 100644 index 0000000..bad54a5 --- /dev/null +++ b/AvocadoEdition/plugin/syndi/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/plugin/syndi/ping.php b/AvocadoEdition/plugin/syndi/ping.php new file mode 100644 index 0000000..57e5683 --- /dev/null +++ b/AvocadoEdition/plugin/syndi/ping.php @@ -0,0 +1,65 @@ + 1) + die("비회원 읽기가 가능한 게시판만 신디케이션을 지원합니다."); + +if (strstr($write['wr_option'], 'secret')) + die("비밀글은 신디케이션을 지원하지 않습니다."); + +if (preg_match('#^('.$config['cf_syndi_except'].')$#', $bo_table)) + die("신디케이션에서 제외된 게시판입니다."); + +$title = htmlspecialchars($write['wr_subject']); +$author = htmlspecialchars($write['wr_name']); +$published = date('Y-m-d\TH:i:s\+09:00', strtotime($write['wr_datetime'])); +$updated = $published; +$link_href = G5_BBS_URL . "/board.php?bo_table={$bo_table}"; +$id = $link_href . htmlspecialchars("&wr_id={$wr_id}"); +$cf_title = htmlspecialchars($config['cf_title']); +$link_title = htmlspecialchars($board['bo_subject']); +$feed_updated = date('Y-m-d\TH:i:s\+09:00', G5_SERVER_TIME); + +$find = array('&', ' '); # 찾아서 +$replace = array('&', ' '); # 바꾼다 + +$content = str_replace( $find, $replace, $write['wr_content'] ); +$summary = str_replace( $find, $replace, strip_tags($write['wr_content']) ); + +Header("Content-type: text/xml"); +header("Cache-Control: no-cache, must-revalidate"); +header("Pragma: no-cache"); + +echo "\n"; +echo "\n"; +echo "" . G5_URL . "\n"; +echo "naver syndication feed document\n"; +echo "\n"; + echo "webmaster\n"; +echo "\n"; + +echo "{$feed_updated}\n"; + +echo "\n"; +echo "\n"; + echo "{$id}\n"; + echo "<![CDATA[{$title}]]>\n"; + echo "\n"; + echo "{$author}\n"; + echo "\n"; + echo "{$updated}\n"; + echo "{$published}\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; +echo "\n"; +echo ""; +?> \ No newline at end of file diff --git a/AvocadoEdition/shop/_ajax.shop_item.php b/AvocadoEdition/shop/_ajax.shop_item.php new file mode 100644 index 0000000..7282357 --- /dev/null +++ b/AvocadoEdition/shop/_ajax.shop_item.php @@ -0,0 +1,31 @@ +(".$item['it_content2'].")"; + } +} + +if(defined('G5_THEME_PATH') && is_file(G5_THEME_PATH."/shop/shop.item.skin.php")) { + include(G5_THEME_PATH."/shop/shop.item.skin.php"); +} else { + include(G5_PATH."/shop/skin/shop.item.skin.php"); +} + +?> diff --git a/AvocadoEdition/shop/_ajax.shop_update.php b/AvocadoEdition/shop/_ajax.shop_update.php new file mode 100644 index 0000000..e428bb4 --- /dev/null +++ b/AvocadoEdition/shop/_ajax.shop_update.php @@ -0,0 +1,171 @@ +"; + $is_able_buy = false; + + } else if($item['sh_use_money']) { + // 소지금 소모 + $use_point += $item['sh_money']; + } + } + + if($item['sh_exp']) { + // 구매 경험치 존재 시 + if($character['ch_exp'] < $item['sh_exp']) { + // 경험치 부족 + $msg .= $config['cf_exp_name']." 부족합니다.
    "; + $is_able_buy = false; + + } else if($item['sh_use_exp']) { + // 경험치 소모 + $use_exp_point += $item['sh_exp']; + } + } + + if($item['sh_has_item']) { + // 구매 아이템 존재 시 + $in = sql_fetch("select in_id from {$g5['inventory_table']} where ch_id = '{$character['ch_id']}' and it_id = '{$item['sh_has_item']}'"); + if(!$in['in_id']) { + // 필요 아이템 미소유 + $has_item_name = get_item_name($item['sh_has_item']); + $msg .= $has_item_name.j($has_item_name, '이')." 있어야 살 수 있습니다.
    "; + $is_able_buy = false; + } else if($item['sh_use_has_item']) { + // 아이템 소모 + $use_inventory_item = $in['in_id']; + } + } + + if($item['sh_has_title']) { + // 구매 타이틀 존재 시 + $ti = sql_fetch("select hi_id from {$g5['title_has_table']} where ch_id = '{$character['ch_id']}' and ti_id = '{$item['sh_has_title']}'"); + if(!$ti['hi_id']) { + // 필요 타이틀 미소유 + $has_title = get_title($item['sh_has_item']); + $msg .= $has_title['ti_title'].j($has_title['ti_title'], '이')." 있어야 살 수 있습니다.
    "; + $is_able_buy = false; + } else if($item['sh_use_has_title']) { + // 타이틀 소모 + $use_has_title = $ti['hi_id']; + } + } + + //------------------------------------------------- + // 구매 가능 여부 체크 + //------------------------------------------------- + + if($item['sh_limit']) { + // 구매 갯수 제한이 존재 시 + // 구매 내역 정보를 가져온다 + $order = sql_fetch("select count(*) as cnt from {$g5['order_table']} where ch_id = '{$character['ch_id']}' and it_id = '{$item['it_id']}'"); + if($order['cnt'] >= $item['sh_limit']) { + $msg .= "너무 많이 구매했습니다. 더이상 구매할 수 없습니다.
    "; + $is_able_buy = false; + } + } + + if($item['sh_qty']) { + // 재고가 존재시 + // 구매 내역 정보를 가져온다 + $order = sql_fetch("select count(*) as cnt from {$g5['order_table']} where it_id = '{$item['it_id']}'"); + if($order['cnt'] >= $item['sh_qty']) { + $msg .= "재고가 모두 소진되었습니다. 더이상 구매할 수 없습니다.
    "; + $is_able_buy = false; + } + } + + if($item['sh_class']) { + // 종족 구매 제한이 존재시 + if(!strstr($item['sh_class'], '||'.$character['ch_class'].'||')) { + $msg .= "구매할 수 없는 ".$config['cf_class_title']."입니다.
    "; + $is_able_buy = false; + } + } + if($item['sh_side']) { + // 세력 구매 제한이 존재시 + if(!strstr($item['sh_side'], '||'.$character['ch_side'].'||')) { + $msg .= "구매할 수 없는 ".$config['cf_side_title']."입니다.
    "; + $is_able_buy = false; + } + } + + if($is_able_buy) { + + // 구매 성공 시 아이템 인벤토리에 추가 + // 인벤에 집어넣기 + $inven_sql = " insert into {$g5['inventory_table']} + set ch_id = '{$character['ch_id']}', + it_id = '{$item['it_id']}', + it_name = '{$item['it_name']}', + ch_name = '{$character['ch_name']}'"; + sql_query($inven_sql); + + // 구매내역 기록 + $inven_sql = " insert into {$g5['order_table']} + set ch_id = '{$character['ch_id']}', + it_id = '{$item['it_id']}', + or_datetime = '".G5_TIME_YMDHIS."', + mb_id = '{$member['mb_id']}'"; + sql_query($inven_sql); + + if($use_point) { + // 소지금 차감 + $insert_point = $use_point * -1; + insert_point($member['mb_id'], $insert_point, $item['it_name'].' 구매 ( '.$use_point.$config['cf_money_pice'].' 소모 )', 'shop', time(), '구매'); + } + if($use_exp_point) { + // 경험치 차감 + $action = '차감'; + $ex_content = $item['it_name'].' 구매 ( '.$use_exp_point.$config['cf_exp_pice'].' 소모 )'; + $ex_point = $use_exp_point * -1; + insert_exp($character['ch_id'], $ex_point, $ex_content, $action); + } + if($use_inventory_item) { + // 아이템 제거 + sql_query("delete from {$g5['inventory_table']} where in_id = '{$use_inventory_item}'"); + } + if($use_has_title) { + // 타이틀 제거 + sql_query("delete from {$g5['title_has_table']} where hi_id = '{$use_has_title}'"); + } + + $msg = "《 ".$item['it_name']." 》 구매 되었습니다."; + } + } +} else { + $msg = "

    부정사용 적발 시, 접근 차단이 될 수 있습니다.

    "; +} + +if(defined('G5_THEME_PATH') && is_file(G5_THEME_PATH."/shop/shop.result.skin.php")) { + include(G5_THEME_PATH."/shop/shop.result.skin.php"); +} else { + include(G5_PATH."/shop/skin/shop.result.skin.php"); +} + +?> diff --git a/AvocadoEdition/shop/_common.php b/AvocadoEdition/shop/_common.php new file mode 100644 index 0000000..b556cc9 --- /dev/null +++ b/AvocadoEdition/shop/_common.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/AvocadoEdition/shop/_head.php b/AvocadoEdition/shop/_head.php new file mode 100644 index 0000000..c9bf5a4 --- /dev/null +++ b/AvocadoEdition/shop/_head.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/shop/_head.sub.php b/AvocadoEdition/shop/_head.sub.php new file mode 100644 index 0000000..0067cf7 --- /dev/null +++ b/AvocadoEdition/shop/_head.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/shop/_tail.php b/AvocadoEdition/shop/_tail.php new file mode 100644 index 0000000..ab638fe --- /dev/null +++ b/AvocadoEdition/shop/_tail.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/shop/_tail.sub.php b/AvocadoEdition/shop/_tail.sub.php new file mode 100644 index 0000000..392cf17 --- /dev/null +++ b/AvocadoEdition/shop/_tail.sub.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/shop/index.php b/AvocadoEdition/shop/index.php new file mode 100644 index 0000000..0d18090 --- /dev/null +++ b/AvocadoEdition/shop/index.php @@ -0,0 +1,160 @@ += '".date('Ymd')."' OR sh_date_e = '') "; + +// 2. 시간 +$sql_search .= " AND (sh_time_s <= '".DATE('H')."' OR sh_time_s = '') "; +$sql_search .= " AND (sh_time_e >= '".DATE('H')."' OR sh_time_e = '') "; + +// 3. 요일 +$sql_search .= " AND (sh_week LIKE '%||".DATE('w')."||%' OR sh_week = '') "; + +// -- 구매 제한 사용 시 +// -- (구매갯수 / 재고 설정은 리스트 출력 시 계산한다.) +// 1. 세력 제한 +$sql_search .= " AND ((sh_side LIKE '%||".$character['ch_side']."||%' AND sh_use_side = '1') OR sh_use_side = '0') "; + +// 2. 종족 제한 +$sql_search .= " AND ((sh_class LIKE '%||".$character['ch_class']."||%' AND sh_use_class = '1') OR sh_use_class = '0') "; + + +// --- 페이징 처리 + +$sql = " select count(*) as cnt {$sql_common} {$sql_search} {$sql_order} "; +$row = sql_fetch($sql); +$total_count = $row['cnt']; + +$page_rows = 10; +$total_page = ceil($total_count / $page_rows); // 전체 페이지 계산 +if ($page < 1) { $page = 1; } // 페이지가 없으면 첫 페이지 (1 페이지) +$from_record = ($page - 1) * $page_rows; // 시작 열을 구함 + +$sql_limit = " limit {$from_record}, {$page_rows} "; +$write_pages = get_paging(5, $page, $total_page, './index.php?cate='.$cate.$qstr.'&page='); + + +$shop_sql = " select * {$sql_common} {$sql_search} {$sql_order} {$sql_limit} "; +$shop_result = sql_query($shop_sql); +$shop_list = array(); + +for($i = 0; $shop = sql_fetch_array($shop_result); $i++) { + $shop_list[$i] = $shop; + $shop_list[$i]['item'] = get_item($shop['it_id']); +} + + +if(defined('G5_THEME_PATH') && is_file(G5_THEME_PATH."/shop/shop.skin.php")) { + include(G5_THEME_PATH."/shop/shop.skin.php"); +} else { + include(G5_PATH."/shop/skin/shop.skin.php"); +} +?> + + + + + diff --git a/AvocadoEdition/shop/skin/shop.item.skin.php b/AvocadoEdition/shop/skin/shop.item.skin.php new file mode 100644 index 0000000..f9bfe92 --- /dev/null +++ b/AvocadoEdition/shop/skin/shop.item.skin.php @@ -0,0 +1,38 @@ + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + 구매하기 + + +
    + +
    +

    + 오류가 발생했습니다. 다시 한번 선택해 주시길 바랍니다. +

    +
    + \ No newline at end of file diff --git a/AvocadoEdition/shop/skin/shop.result.skin.php b/AvocadoEdition/shop/skin/shop.result.skin.php new file mode 100644 index 0000000..93eeb85 --- /dev/null +++ b/AvocadoEdition/shop/skin/shop.result.skin.php @@ -0,0 +1,7 @@ + + +
    +

    +
    \ No newline at end of file diff --git a/AvocadoEdition/shop/skin/shop.skin.php b/AvocadoEdition/shop/skin/shop.skin.php new file mode 100644 index 0000000..dda0ab9 --- /dev/null +++ b/AvocadoEdition/shop/skin/shop.skin.php @@ -0,0 +1,58 @@ +', 0); +?> + +
    +
    + +
    + +
    +
    +
    + +
    + + +
    + + + +
    +
    + +
    + + + diff --git a/AvocadoEdition/skin/banner/basic/banner.skin.php b/AvocadoEdition/skin/banner/basic/banner.skin.php new file mode 100644 index 0000000..4420d74 --- /dev/null +++ b/AvocadoEdition/skin/banner/basic/banner.skin.php @@ -0,0 +1,98 @@ +', 0); + +if (count($banner) > 0) { +?> +
    +
    + +
      + ".$bn[ +
    • + "; } + echo $banner_image; + if($is_link) { echo ""; } + ?> +
    • + +
    + +
    +
    + + +
    +
    +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/banner/basic/style.css b/AvocadoEdition/skin/banner/basic/style.css new file mode 100644 index 0000000..612648e --- /dev/null +++ b/AvocadoEdition/skin/banner/basic/style.css @@ -0,0 +1,59 @@ +@charset "utf-8"; +@import url('../../../css/swiper.css'); + +.ban-basic { position: relative; opacity: 1; } + +.ban-basic .slides li img { width: 100%; } + +.ban-basic .flex-direction-nav a { + display: block; + position: absolute; + top: 50%; + margin-top: -20px; + overflow: hidden; + width: 40px; + height: 40px; + text-indent: -999px; + background: rgba(0, 0, 0, 0.5); + z-index: 5; +} +.ban-basic .flex-direction-nav a:before { + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + text-indent: 0; + text-align: center; + line-height: 40px; + color: #fff; + font-size: 15px; + font-family: 'icon'; +} + +.ban-basic .flex-prev { left: 0; } +.ban-basic .flex-prev:before { content: "\ea38"; } +.ban-basic .flex-next { right: 0; } +.ban-basic .flex-next:before { content: "\ea34"; } + +.ban-basic .flex-control-paging { + display: block; + position: absolute; + left: 0; + right: 0; + bottom: 10px; + z-index: 5; + text-align: center; + padding: 0; +} +.ban-basic .flex-control-paging li { display: inline-block; margin: 3px; } +.ban-basic .flex-control-paging a { + display: block; + position: relative; + width: 15px; + height: 15px; + overflow: hidden; + text-indent: -999px; + border-radius: 100%; +} \ No newline at end of file diff --git a/AvocadoEdition/skin/board/basic/img/btn_close.gif b/AvocadoEdition/skin/board/basic/img/btn_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..040b180ac6584ae612ef2886487110f0ad079963 GIT binary patch literal 211 zcmZ?wbhEHbC>lw|Nj2|^XJd+Ki|K7yLIc<@85r}UAy+@_wT|Ns9P2m!^PEMO%%AQEIJ18abSL2rs@7wgh> zI-xzeYYr882T$7a>~-(!J@=MOy}Z$ltNl`73Cq0Bi3wIGB-b=ECVhGFY*&ANIg94( d^Unm859R4|2rw-)wA%9i`(c-qSMQw}tN}eeW+eas literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/img/icon_file.gif b/AvocadoEdition/skin/board/basic/img/icon_file.gif new file mode 100644 index 0000000000000000000000000000000000000000..cca47f566ac0db655fb2ab0f56628b64958e48b2 GIT binary patch literal 107 zcmZ?wbhEHb-Wqsc#^P~2x#@rVooH@5wHB9i@BozKb;P9uI^*c|UyXO5@>VyLmgEat< Cr6(f* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/img/icon_hot.gif b/AvocadoEdition/skin/board/basic/img/icon_hot.gif new file mode 100644 index 0000000000000000000000000000000000000000..c95b839aeef0c1e26a4bab4ea50cd6d3f1969d7f GIT binary patch literal 97 zcmZ?wbhEHbzHen|7VvwFnzUPlarEA ZqW~YXyUO~T+#YkUoJ%V_>ib05Q5F AasU7T literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/img/icon_mobile.gif b/AvocadoEdition/skin/board/basic/img/icon_mobile.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad934d23c440c83db0c4589596465cb087353e01 GIT binary patch literal 62 zcmZ?wbhEHbZ% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/img/icon_reply.gif b/AvocadoEdition/skin/board/basic/img/icon_reply.gif new file mode 100644 index 0000000000000000000000000000000000000000..91c135977b4f445a90c849310dc80efde1983830 GIT binary patch literal 77 zcmZ?wbhEHb&!1E4^4&ClEzh)PmWxV3{9A~!gB2-%RL5bHcgg3Zp^!+W)H2^A_AxQuL literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/img/icon_sound.gif b/AvocadoEdition/skin/board/basic/img/icon_sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5188318a5cdc394b984125c0ddd376c5f57bbe4 GIT binary patch literal 113 zcmZ?wbhEHbE1CJY$zMikVi`-#gIi|DbmsXBWf6U5szE@->A`0*`&<;b@XASRrB8=E6~=S>Pbm I%fes{0AXt-SpWb4 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/basic/list.skin.php b/AvocadoEdition/skin/board/basic/list.skin.php new file mode 100644 index 0000000..91da2ac --- /dev/null +++ b/AvocadoEdition/skin/board/basic/list.skin.php @@ -0,0 +1,217 @@ +', 0); +?> + +
    +
    + + +
    + +
    + + + +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "> + + + + + + + + '; } ?> + +
    목록
    No제목작성자작성일조회
    + 공지'; + else if ($wr_id == $list[$i]['wr_id']) + echo "열람중"; + else + echo $list[$i]['num']; + ?> + + + [] + + + + + 댓글 + + + '; } + + if (isset($list[$i]['icon_new'])) echo $list[$i]['icon_new']; + if (isset($list[$i]['icon_secret'])) echo $list[$i]['icon_secret']; + ?> +
    게시물이 없습니다.
    + + + +
    + + 목록 + 글쓰기 + +
    + +
    +
    + + + + + + + + + +
    + 게시물 검색 + +
    + + + + + + + + +
    +
    + + + + + + +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/board/basic/style.css b/AvocadoEdition/skin/board/basic/style.css new file mode 100644 index 0000000..2ae69e2 --- /dev/null +++ b/AvocadoEdition/skin/board/basic/style.css @@ -0,0 +1,120 @@ + +.board-list { width: 100%; text-align: left; border-bottom: 1px solid rgba(255, 255, 255, .4); } + +.empty_table { text-align: center; line-height: 150px; } + +#bo_v_con img { width: auto !important; } + +.board-category { + display: block; + position: relative; + text-align: right; + padding: 0 20px; + font-family: 'Nanum Myeongjo'; +} +.board-category li { display: inline-block; color: #fff; font-size: 14px; } +.board-category li + li:before { content: " / "; padding: 0 10px; } +.board-category li a { color: #fff; } + +.board-list thead th { font-family: 'Nanum Myeongjo'; background: rgba(0, 0, 0, .5); text-align: center; font-size: 13px; padding: 10px; } +.board-list tbody .td_chk, +.board-list tbody .td_num, +.board-list tbody .td_name, +.board-list tbody .td_hit, +.board-list tbody .td_date { text-align: center; } +.board-list tbody td { padding: 10px; } + +.board-list tbody .bo_notice * { color: yellow; } + +.board-list tbody .bg-1 td { background: rgba(255, 255, 255, .1); } +.board-list a { color: #fff; } + +.bo_fx { text-align: right; padding: 20px 0; } + +#bo_sch { text-align: center; padding-top: 30px; } +#bo_sch button { position: relative; width: 30px; height: 30px; background: none; border: none; overflow: hidden; text-indent: -999px; } +#bo_sch button:before { + content: "\e986"; + font-family: 'icon'; + display: block; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + line-height: 30px; + text-align: center; + text-indent: 0; + color: #fff; + font-size: 20px; +} + +@media all and (max-width: 1000px) { + .board-list, + .board-list thead, + .board-list tbody, + .board-list tr, + .board-list th, + .board-list td { display: block; position: relative; } + .board-list thead { display: none; } + + .board-list tbody .bg-1 td { background: none; } + .board-list tbody .bg-1 { background: rgba(255, 255, 255, .1); } + + .board-list .td_num { display: none; } + .board-list .td_name, + .board-list .td_date, + .board-list .td_hit { display: inline-block; padding-top: 0; opacity: .7; } + .board-list .td_subject { text-align: left; } + +} + + +.btn_confirm { text-align: center; padding: 30px 0; } + + + +/* 게시판 댓글 */ +#bo_vc {margin:0 0 20px;padding:20px 0px 10px;} +#bo_vc h2 {margin-bottom:10px} +#bo_vc article {padding:0 0 10px;border-top:1px solid rgba(255, 255, 255, .4);} +#bo_vc header {position:relative;padding:15px 0 5px} +#bo_vc header .icon_reply {position:absolute;top:15px;left:-20px} +#bo_vc .sv_wrap {margin-right:15px} +#bo_vc .member, #bo_vc .guest, #bo_vc .sv_member, #bo_vc .sv_guest {font-weight:bold} +.bo_vc_hdinfo {display:inline-block;margin:0 15px 0 5px} +#bo_vc h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc a {color:#fff;text-decoration:none} +#bo_vc p {padding:0 0 5px;line-height:1.8em} +#bo_vc p a {text-decoration:underline} +#bo_vc p a.s_cmt {text-decoration:none} +#bo_vc_empty {margin:0;padding:20px !important;text-align:center} +#bo_vc #bo_vc_winfo {float:left} +#bo_vc footer {zoom:1} +#bo_vc footer:after {display:block;visibility:hidden;clear:both;content:""} + +.bo_vc_act {float:right;margin:0;list-style:none;zoom:1} +.bo_vc_act a { color: #fff; } +.bo_vc_act:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_act li {float:left;margin-left:5px} + +#bo_vc_w {position:relative;margin:0 0 10px;padding:0 0 20px;border-bottom:1px solid #cfded8} +#bo_vc_w h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc_w #char_cnt {display:block;margin:0 0 5px} + +#bo_vc_sns {margin:0;padding:0;list-style:none;zoom:1} +#bo_vc_sns:after {display:block;visibility:hidden;clear:both;content:""} +#bo_vc_sns li {float:left;margin:0 20px 0 0} +#bo_vc_sns input {margin:0 0 0 5px} + + +#bo_v { padding-top: 20px; } +#bo_v_title { font-size: 16px; text-align: center; margin-bottom: 20px; padding: 20px 0; border-bottom: 1px solid rgba(255, 255, 255, .5); } +#bo_v_info { text-align: right; } +#bo_v_info strong { display: inline-block; } +#bo_v_info strong + strong { margin-left: 15px; } + +#bo_v_img { text-align: center; } +#bo_v_img img { display: block; margin: 0 auto; } +#bo_v_con { margin-top: 30px; } +#bo_v_atc { display: block; margin: 20px 0; padding: 10px; line-height: 1.8em; } \ No newline at end of file diff --git a/AvocadoEdition/skin/board/basic/view.skin.php b/AvocadoEdition/skin/board/basic/view.skin.php new file mode 100644 index 0000000..eb3b8a7 --- /dev/null +++ b/AvocadoEdition/skin/board/basic/view.skin.php @@ -0,0 +1,202 @@ +', 0); +?> + +
    +
    + + + + +
    +
    +

    +
    +
    + +
    +
    +

    +
    + +
    + + + +
    + + + + + +
    +

    첨부파일

    + +
    + + + +
    + \n"; + + for ($i=0; $i<=count($view['file']); $i++) { + if ($view['file'][$i]['view']) { + //echo $view['file'][$i]['view']; + echo get_view_thumbnail($view['file'][$i]['view']); + } + } + + echo "
    \n"; + } + ?> + + +
    + + + + + + + + + + +
    + +
    + + + + +



    + + + + + +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/board/basic/view_comment.skin.php b/AvocadoEdition/skin/board/basic/view_comment.skin.php new file mode 100644 index 0000000..77fe255 --- /dev/null +++ b/AvocadoEdition/skin/board/basic/view_comment.skin.php @@ -0,0 +1,334 @@ + + + + + +
    + \]/i", "", $comment); + $cmt_sv = $cmt_amt - $i + 1; // 댓글 헤더 z-index 재설정 ie8 이하 사이드뷰 겹침 문제 해결 + ?> + +
    style="margin-left:px;border-top-color:rgba(255, 255, 255, .2)"> +
    + + 댓글의 댓글 + + + + + +
    + + +

    + 비밀글 + +

    + + + + + " id="secret_comment_"> + + + + + +
    + +

    등록된 댓글이 없습니다.

    + +
    + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/basic/write.skin.php b/AvocadoEdition/skin/board/basic/write.skin.php new file mode 100644 index 0000000..b0c329c --- /dev/null +++ b/AvocadoEdition/skin/board/basic/write.skin.php @@ -0,0 +1,270 @@ +', 0); +?> + +
    +
    + + +
    + +
    + + +
    + +
    + + + + + + + + + + + + '."\n".''; + } + + if ($is_html) { + if ($is_dhtml_editor) { + $option_hidden .= ''; + } else { + $option .= "\n".''."\n".''; + } + } + + if ($is_secret) { + if ($is_admin || $is_secret==1) { + $option .= "\n".''."\n".''; + } else { + $option_hidden .= ''; + } + } + + if ($is_mail) { + $option .= "\n".''."\n".''; + } + } + + echo $option_hidden; + ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    class="frm_input " maxlength="20">
    옵션
    + +
    +
    + +
    +
    + + +

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    + + + + +
    글자
    + +
    " id="wr_link" class="frm_input" size="50">
    파일 # + + + + + + + +
    자동등록방지 + +
    + +
    + + 목록 +
    +
    + + +
    + +


    +
    +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/board/caculate/delete_comment.tail.skin.php b/AvocadoEdition/skin/board/caculate/delete_comment.tail.skin.php new file mode 100644 index 0000000..2d54722 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/delete_comment.tail.skin.php @@ -0,0 +1,4 @@ + diff --git a/AvocadoEdition/skin/board/caculate/img/btn_close.gif b/AvocadoEdition/skin/board/caculate/img/btn_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..040b180ac6584ae612ef2886487110f0ad079963 GIT binary patch literal 211 zcmZ?wbhEHbC>lw|Nj2|^XJd+Ki|K7yLIc<@85r}UAy+@_wT|Ns9P2m!^PEMO%%AQEIJ18abSL2rs@7wgh> zI-xzeYYr882T$7a>~-(!J@=MOy}Z$ltNl`73Cq0Bi3wIGB-b=ECVhGFY*&ANIg94( d^Unm859R4|2rw-)wA%9i`(c-qSMQw}tN}eeW+eas literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/img/icon_file.gif b/AvocadoEdition/skin/board/caculate/img/icon_file.gif new file mode 100644 index 0000000000000000000000000000000000000000..cca47f566ac0db655fb2ab0f56628b64958e48b2 GIT binary patch literal 107 zcmZ?wbhEHb-Wqsc#^P~2x#@rVooH@5wHB9i@BozKb;P9uI^*c|UyXO5@>VyLmgEat< Cr6(f* literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/img/icon_hot.gif b/AvocadoEdition/skin/board/caculate/img/icon_hot.gif new file mode 100644 index 0000000000000000000000000000000000000000..c95b839aeef0c1e26a4bab4ea50cd6d3f1969d7f GIT binary patch literal 97 zcmZ?wbhEHbzHen|7VvwFnzUPlarEA ZqW~YXyUO~T+#YkUoJ%V_>ib05Q5F AasU7T literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/img/icon_mobile.gif b/AvocadoEdition/skin/board/caculate/img/icon_mobile.gif new file mode 100644 index 0000000000000000000000000000000000000000..ad934d23c440c83db0c4589596465cb087353e01 GIT binary patch literal 62 zcmZ?wbhEHbZ% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/img/icon_reply.gif b/AvocadoEdition/skin/board/caculate/img/icon_reply.gif new file mode 100644 index 0000000000000000000000000000000000000000..91c135977b4f445a90c849310dc80efde1983830 GIT binary patch literal 77 zcmZ?wbhEHb&!1E4^4&ClEzh)PmWxV3{9A~!gB2-%RL5bHcgg3Zp^!+W)H2^A_AxQuL literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/img/icon_sound.gif b/AvocadoEdition/skin/board/caculate/img/icon_sound.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5188318a5cdc394b984125c0ddd376c5f57bbe4 GIT binary patch literal 113 zcmZ?wbhEHbE1CJY$zMikVi`-#gIi|DbmsXBWf6U5szE@->A`0*`&<;b@XASRrB8=E6~=S>Pbm I%fes{0AXt-SpWb4 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/caculate/list.skin.php b/AvocadoEdition/skin/board/caculate/list.skin.php new file mode 100644 index 0000000..627b77c --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/list.skin.php @@ -0,0 +1,287 @@ +', 0); + +if($is_member) { + set_session('ss_bo_table', $_REQUEST['bo_table']); +} + +// 기본 설정 불러오기 +$commu_conf = sql_fetch(" select * from {$g5['article_default_table']} "); + +$write_action_url = G5_BBS_URL."/write_update.php"; +?> + + +
    + +

    + + + +
    + 정산글 등록하기 + + +
    + + + +
    + + + + + + + +
    + +
    +
    + +
    +
    +
    +

    + + + + [ ] + + + + + 수정 + 삭제 + + +

    +
    + +
    + + +
    +
    + + + + + + + + +
    +
    + + + + +
    + +
    + +
    +
    +
    + + + +
    + + + + + +
    + 게시물 검색 + +
    + + + + + + +
    +
    + +
    + + + +
    + + + + + + + + + + + + +
    diff --git a/AvocadoEdition/skin/board/caculate/style.css b/AvocadoEdition/skin/board/caculate/style.css new file mode 100644 index 0000000..20fdb78 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/style.css @@ -0,0 +1,185 @@ +@charset "utf-8"; + +.wr_content textarea { height: 200px !important; } + +.board-notice { height: auto !important; background-size: 100% 100% !important; margin: 0 auto !important; } + + +.board-category { + display: block; + position: relative; + margin-bottom: 10px; + +} +.board-category select { + +} + +@media all and (max-width: 640px) { + .board-category { + display: block; + width: 100%; + box-sizing: border-box; + padding: 0 10px; + } + .board-category select { + width: 100%; + } + + .bo_fx { + display: block; + width: 100%; + box-sizing: border-box; + padding: 20px 10px !important; + } + .bo_fx a { + display: block; + width: 100%; + } +} + +.list-write-area { + position: relative; + padding-bottom: 30px; +} +.list-write-area .btn-write { + display: block; + max-width: 150px; + margin: 0 auto 20px; + text-align: center; + font-size: 14px; + border-radius: 9.0em; + padding: 0px 10px; + line-height: 33px; + height: 35px; + background: #02121e !important; + border: none !important; +} + + +#write_box { + position: relative; + padding: 15px; +} +#write_box select, +#write_box button { width: 100%; } +#write_box textarea { height: 100px; } + +.board-list { padding: 0 10px; } + +.calc-item { + position: relative; + padding-left: 80px; + padding-right: 5px; +} +.calc-item .thumb { + position: absolute; + top: 0; + left: 0; + width: 65px; +} + + +.calc-item .con-box { + display: block; + position: relative; + margin: 10px 0; + box-sizing: border-box; + padding: 0; +} +.calc-item .con-box .inner { + position: relative; + padding: 10px; + height: 100%; + box-sizing: border-box; + z-index: 1; +} +.calc-item .name { + font-weight: 600; +} +.calc-item .name i { + display: inline-block; + margin-right: 5px; + color: #fff; + padding: 2px 10px; + border-radius: 9.0em; +} +.calc-item .name i[data-item="정산완료"] { background-color: #417d31; } +.calc-item .name i[data-item="반려"] { background-color: #ab2323; } +.calc-item .con { + word-break:break-all; + padding: 10px 0; + margin: 10px 0 0; + border-top: 1px solid rgba(255, 255, 255, .2); +} + +.calc-item .name span { + display: inline-block; + padding-right: 10px; + vertical-align: middle; +} +.calc-item .name sup { + display: inline-block; + vertical-align: middle; +} +.calc-item .name sup a { + display: inline-block; + vertical-align: middle; + font-weight: 400; + padding: 1px 10px; + color: #fff; + border-radius: 9.0em; +} +.calc-item .name sup a.btn-mod { background: #14526b; } +.calc-item .name sup a.btn-del { background: #611a1a; } + + +.modify-con { display: none; } + +.comment-box { padding: 10px 0; margin-top: 10px; } +.comment-box .theme-box + .theme-box { margin-top: 5px; } +.comment-box .co-footer { + font-size: 11px; + text-align: right; + overflow: hidden; +} +.comment-box .co-footer .f-box { + display: inline-block; + padding: 4px 10px; + border-radius: 9.0em; + border: 1px solid rgba(255, 255, 255, .2); +} + +.board-list .bo_vc_w { position: relative; margin-top: 10px; padding-right: 75px; } +.board-list .bo_vc_w .input-comment { position: relative; margin-bottom: 5px; } +.board-list .bo_vc_w .input-comment textarea { display: block; width: 100%; height: 80px; box-sizing: border-box; margin: 0;} + +.board-list .bo_vc_w .btn_confirm { display: block; position: absolute; top: 0; right: 0; bottom: 0; width: 70px; } +.board-list .bo_vc_w .btn_confirm .ui-comment-submit { display: block; width: 100%; height: 100%; } + +.board-list .modify_area { display: none; position: relative; padding-right: 60px; } +.board-list .modify_area textarea { display: block; width: 100%; min-height: 100px; padding: 10px; } +.board-list .modify_area button { display: block; position: absolute; top: 0; right: 0; width: 60px; height: 100%; bottom: 0; } + + +.comment-box { border-top: 1px solid rgba(255, 255, 255, .2); } +.comment-form-box { border-top: 1px solid rgba(255, 255, 255, .2); } + +.admin-comment { position: relative; } +.admin-comment p { position: relative; padding: 4px 10px; } +.admin-comment p label { margin-right: 5px; } +.admin-comment p.input { padding: 0 0 0 210px; } +.admin-comment p.input input.point { position: absolute; top: 0; left: 110px; width: 100px; } +.admin-comment p.input input { width: 100%; } +.admin-comment p.input select, +.admin-comment p.input strong { position: absolute; top: 0; left: 0; width: 110px; } +.admin-comment p.input strong { display: block; line-height: 30px; padding-left: 15px; } + +.admin-comment.event-pannel input { width: 100%; } + + + +.con-box .modify-con { padding-bottom: 10px; } +.con-box .modify-con select { width: 100%; } +.con-box .modify-con textarea { height: 150px; } +.con-box .modify-con button { width: 100%; } \ No newline at end of file diff --git a/AvocadoEdition/skin/board/caculate/view.skin.php b/AvocadoEdition/skin/board/caculate/view.skin.php new file mode 100644 index 0000000..0f09cf7 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/view.skin.php @@ -0,0 +1,3 @@ + diff --git a/AvocadoEdition/skin/board/caculate/view_comment.php b/AvocadoEdition/skin/board/caculate/view_comment.php new file mode 100644 index 0000000..0395eec --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/view_comment.php @@ -0,0 +1,116 @@ += $board['bo_comment_level']) + $is_comment_write = true; + +// 코멘트 출력 +//$sql = " select * from {$write_table} where wr_parent = '{$wr_id}' and wr_is_comment = 1 order by wr_comment desc, wr_comment_reply "; +$sql = " select * from $write_table where wr_parent = '{$data['wr_id']}' and wr_is_comment = 1 order by wr_comment, wr_comment_reply "; +$result = sql_query($sql); +for ($c_i=0; $c_row=sql_fetch_array($result); $c_i++) +{ + $comment[$c_i] = $c_row; + + //$comment[$c_i]['name'] = get_sideview($c_row['mb_id'], cut_str($c_row['wr_name'], 20, ''), $c_row['wr_email'], $c_row['wr_homepage']); + + $tmp_name = get_text(cut_str($c_row['wr_name'], $config['cf_cut_name'])); // 설정된 자리수 만큼만 이름 출력 + if ($board['bo_use_sideview']) + $comment[$c_i]['name'] = get_sideview($c_row['mb_id'], $tmp_name, $c_row['wr_email'], $c_row['wr_homepage']); + else + $comment[$c_i]['name'] = ''.$tmp_name.''; + + + + // 공백없이 연속 입력한 문자 자르기 (way 보드 참고. way.co.kr) + //$comment[$c_i]['content'] = eregi_replace("[^ \n<>]{130}", "\\0\n", $c_row['wr_content']); + + $comment[$c_i]['content'] = $comment[$c_i]['content1']= '비밀글 입니다.'; + if (!strstr($c_row['wr_option'], 'secret') || + $is_admin || + ($write['mb_id']==$member['mb_id'] && $member['mb_id']) || + ($c_row['mb_id']==$member['mb_id'] && $member['mb_id'])) { + $comment[$c_i]['content1'] = $c_row['wr_content']; + $comment[$c_i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $comment[$c_i]['content'] = search_font($stx, $comment[$c_i]['content']); + } else { + $ss_name = 'ss_secret_comment_'.$bo_table.'_'.$comment[$c_i]['wr_id']; + + if(!get_session($ss_name)) + $comment[$c_i]['content'] = '댓글내용 확인'; + else { + $comment[$c_i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $comment[$c_i]['content'] = search_font($stx, $comment[$c_i]['content']); + } + } + + $comment[$c_i]['datetime'] = substr($c_row['wr_datetime'],2,14); + + // 관리자가 아니라면 중간 IP 주소를 감춘후 보여줍니다. + $comment[$c_i]['ip'] = $c_row['wr_ip']; + if (!$is_admin) + $comment[$c_i]['ip'] = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $c_row['wr_ip']); + + $comment[$c_i]['is_reply'] = false; + $comment[$c_i]['is_edit'] = false; + $comment[$c_i]['is_del'] = false; + if ($is_comment_write || $is_admin) + { + $token = ''; + + if ($member['mb_id']) + { + if ($c_row['mb_id'] == $member['mb_id'] || $is_admin) + { + set_session('ss_delete_comment_'.$c_row['wr_id'].'_token', $token = uniqid(time())); + $comment[$c_i]['del_link'] = './delete_comment.php?bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&token='.$token.'&page='.$page.$qstr; + $comment[$c_i]['is_edit'] = true; + $comment[$c_i]['is_del'] = true; + } + } + else + { + if (!$c_row['mb_id']) { + $comment[$c_i]['del_link'] = './password.php?w=x&bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&page='.$page.$qstr; + $comment[$c_i]['is_del'] = true; + } + } + + if (strlen($c_row['wr_comment_reply']) < 5) + $comment[$c_i]['is_reply'] = true; + } + + // 05.05.22 + // 답변있는 코멘트는 수정, 삭제 불가 + if ($i > 0 && !$is_admin) + { + if ($c_row['wr_comment_reply']) + { + $tmp_comment_reply = substr($c_row['wr_comment_reply'], 0, strlen($c_row['wr_comment_reply']) - 1); + if ($tmp_comment_reply == $comment[$c_i-1]['wr_comment_reply']) + { + $comment[$c_i-1]['is_edit'] = false; + $comment[$c_i-1]['is_del'] = false; + } + } + } +} + +// 코멘트수 제한 설정값 +if ($is_admin) +{ + $comment_min = $comment_max = 0; +} +else +{ + $comment_min = (int)$board['bo_comment_min']; + $comment_max = (int)$board['bo_comment_max']; +} + +include($board_skin_path.'/view_comment.skin.php'); + +?> \ No newline at end of file diff --git a/AvocadoEdition/skin/board/caculate/view_comment.skin.php b/AvocadoEdition/skin/board/caculate/view_comment.skin.php new file mode 100644 index 0000000..93e4e58 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/view_comment.skin.php @@ -0,0 +1,79 @@ +\]/i", "", $content); + + + if($log_comment['wr_id'] != $log_comment['wr_id'] && ($log_comment['is_reply'] || $log_comment['is_edit'] || $log_comment['is_del'])) { + // 답변, 수정, 삭제가 가능할 경우 + // 또한, 본문의 id와 코멘트의 id가 다를 경우 (같을 경우엔 로그의 상단에 있는 컨트롤을 통해 액션 수행이 가능하다) + $query_string = str_replace("&", "&", $_SERVER['QUERY_STRING']); + if($w == 'cu') { + $sql = " select wr_id, wr_content from $write_table where wr_id = '$indexd' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w_'.$data['wr_id']; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w_'.$data['wr_id']; + } + + if($index == 0) { + echo '
    '; + } +?> + + +
    +
    +
    + [비밀글]
    '; + // 코멘트 출력 부분 + $log_comment['content'] = autolink($log_comment['content'], $bo_table, $stx); // 자동 링크 및 해시태그, 로그 링크 등 컨트롤 함수 + echo $log_comment['content']; + } else { + echo '비밀글입니다.'; + } + } else { + // 코멘트 출력 부분 + $log_comment['content'] = autolink($log_comment['content'], $bo_table, $stx); // 자동 링크 및 해시태그, 로그 링크 등 컨트롤 함수 + echo $log_comment['content']; + } + ?> +
    + +
    + + +
    + +
    + + +
    + 0) { + echo '
    '; +} + +?> + + diff --git a/AvocadoEdition/skin/board/caculate/write.skin.php b/AvocadoEdition/skin/board/caculate/write.skin.php new file mode 100644 index 0000000..55cefae --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/write.skin.php @@ -0,0 +1,183 @@ +', 0); + +if($w == '') $write['wr_subject'] = $character['ch_name']; +?> + + +
    + +

    + + +
    + + +
    + + + + + + + + + + + + + '."\n".''; + } + + if ($is_html) { + if ($is_dhtml_editor) { + $option_hidden .= ''; + } else { + $option .= "\n".''."\n".''; + } + } + + if ($is_secret) { + if ($is_admin || $is_secret==1) { + $option .= "\n".''."\n".''; + } else { + $option_hidden .= ''; + } + } + + if ($is_mail) { + $option .= "\n".''."\n".''; + } + } + echo $option_hidden; + ?> + +
    + + + + +
    + + +

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    + + + + +
    글자
    + +
    + +
    + +
    +
    + + 취소 +
    +
    + + +
    + diff --git a/AvocadoEdition/skin/board/caculate/write_comment.php b/AvocadoEdition/skin/board/caculate/write_comment.php new file mode 100644 index 0000000..5574512 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/write_comment.php @@ -0,0 +1,69 @@ + + + + + diff --git a/AvocadoEdition/skin/board/caculate/write_comment_update.skin.php b/AvocadoEdition/skin/board/caculate/write_comment_update.skin.php new file mode 100644 index 0000000..e20cdf9 --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/write_comment_update.skin.php @@ -0,0 +1,27 @@ + 0) { + insert_exp($comment_ch_id, $ex_value, $ex_content); + } + // ----- 금액 변동 + if($mo_value && $mo_value > 0) { + insert_point($comment_mb_id, $mo_value, $mo_content, '@passive', $comment_mb_id, 'admin-'.uniqid(''), 0); + } +} + +goto_url('./board.php?bo_table='.$bo_table.'&'.$qstr.'&#c_'.$comment_id); +?> diff --git a/AvocadoEdition/skin/board/caculate/write_update.skin.php b/AvocadoEdition/skin/board/caculate/write_update.skin.php new file mode 100644 index 0000000..dd0d7fa --- /dev/null +++ b/AvocadoEdition/skin/board/caculate/write_update.skin.php @@ -0,0 +1,19 @@ + diff --git a/AvocadoEdition/skin/board/mmb/_action.data.php b/AvocadoEdition/skin/board/mmb/_action.data.php new file mode 100644 index 0000000..0a545c6 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/_action.data.php @@ -0,0 +1,30 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/_common.php b/AvocadoEdition/skin/board/mmb/_common.php new file mode 100644 index 0000000..626acc9 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/_common.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/action/log.H.skin.php b/AvocadoEdition/skin/board/mmb/action/log.H.skin.php new file mode 100644 index 0000000..76817f7 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/action/log.H.skin.php @@ -0,0 +1,22 @@ + + +
    + + + + + +

    + 제작했습니다! +

    + + +

    + 제작에 실패하였습니다. +

    + +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/action/log.S.skin.php b/AvocadoEdition/skin/board/mmb/action/log.S.skin.php new file mode 100644 index 0000000..b2ae9a3 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/action/log.S.skin.php @@ -0,0 +1,22 @@ + + +
    + + + + + +

    + 탐색하여 획득했습니다! +

    + + +

    + 탐색했지만 아무것도 얻지 못했습니다. +

    + +
    \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/action/log.item.skin.php b/AvocadoEdition/skin/board/mmb/action/log.item.skin.php new file mode 100644 index 0000000..e6544f5 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/action/log.item.skin.php @@ -0,0 +1,41 @@ + + + +
    + + + +

    + 사용했습니다! () +

    +
    + +
    + + + +

    + 사용해서 획득하였습니다! +

    +
    + + +
    + +

    + 사용했지만 아무것도 획득하지 못했습니다... +

    +
    + + diff --git a/AvocadoEdition/skin/board/mmb/ajax/_common.php b/AvocadoEdition/skin/board/mmb/ajax/_common.php new file mode 100644 index 0000000..db035a8 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/ajax/_common.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/ajax/add_favorite.php b/AvocadoEdition/skin/board/mmb/ajax/add_favorite.php new file mode 100644 index 0000000..96e459c --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/ajax/add_favorite.php @@ -0,0 +1,18 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/delete_comment.tail.skin.php b/AvocadoEdition/skin/board/mmb/delete_comment.tail.skin.php new file mode 100644 index 0000000..2d54722 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/delete_comment.tail.skin.php @@ -0,0 +1,4 @@ + diff --git a/AvocadoEdition/skin/board/mmb/emoticon_list.php b/AvocadoEdition/skin/board/mmb/emoticon_list.php new file mode 100644 index 0000000..e0c5e1e --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/emoticon_list.php @@ -0,0 +1,45 @@ +', 0); +?> + +
    +
    +
    + 이모티콘 + +
    + +
    +
      + +
    • + + + + +
    • + +
    • + 등록된 이모티콘이 없습니다. +
    • + +
    +
    + +
    + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/img/d1.png b/AvocadoEdition/skin/board/mmb/img/d1.png new file mode 100644 index 0000000000000000000000000000000000000000..08c056b69795cbb3d254263dab8f538e39fe57e9 GIT binary patch literal 2841 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/mmb/img/d4.png b/AvocadoEdition/skin/board/mmb/img/d4.png new file mode 100644 index 0000000000000000000000000000000000000000..2310c5e55b9563538a94f3871e67b23d9f784489 GIT binary patch literal 2844 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 WFIM(_{@|am18A!1snjUhqyGzdN_W2i literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/mmb/img/no_image.png b/AvocadoEdition/skin/board/mmb/img/no_image.png new file mode 100644 index 0000000000000000000000000000000000000000..10a5aeacb2659e1009f8f2913f8ef35d4688d57e GIT binary patch literal 3191 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/mmb/js/load.board.js b/AvocadoEdition/skin/board/mmb/js/load.board.js new file mode 100644 index 0000000..e3c1c60 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/js/load.board.js @@ -0,0 +1,103 @@ +// 레이아웃 셋팅 - 반응형 +fn_layout_setting(); + +// 화면 사이즈가 변경 될 시, 레이아웃 셋팅 실행 +window.onresize = function() { fn_layout_setting(); }; + +// 즐겨찾기 추가 - Ajax +$('a[data-function="favorite"]').on('click', function() { + var formData = new FormData(); + var idx = $(this).data('idx'); + var obj = $(this); + formData.append("wr_id", idx); + formData.append("bo_table", g5_bo_table); + formData.append("mb_id", avo_mb_id); + + $.ajax({ + url:avo_board_skin_url + '/ajax/add_favorite.php' + , data: formData + , processData: false + , contentType: false + , type: 'POST' + , success: function(data){ + if(data == 'on') { + obj.removeClass('on'); + obj.addClass(data); + }else if(data == 'off') { + obj.removeClass('on'); + } + } + }); + + return false; +}); + + +$('a.ui-open-log').on('click', function() { + + var obj = $(this).closest('.pic-data').children('div'); + var state = $(obj).hasClass('on'); + var original_height = $(obj).find('img').height(); + var setting_height = 470; + + if(state){ + //닫기 + $(obj).stop().animate({height: setting_height + "px"}, 1000); + $(obj).removeClass('on'); + $(this).text("OPEN"); + } else { + // 열기 + $(obj).stop().animate({height: original_height + "px"}, 1000); + $(obj).addClass('on'); + $(this).text("CLOSE"); + } + + return false; +}); + +$('a.ui-remove-blind').on('click', function() { + $(this).closest('.pic-data').removeClass('ui-blind'); + $(this).fadeOut(); + return false; +}); + +$('.send_memo').on('click', function() { + var target = $(this).attr('href'); + window.open(target, 'memo', "width=500, height=300"); + return false; +}); + +$('.btn-search-guide').on('click', function() { + $('#searc_keyword').toggleClass('on'); + return false; +}); + +$(window).ready(function() { + $('#load_log_board').css('opacity', '1.0'); +}); + +function fn_layout_setting() { + $('#log_list > .item').each(function(){ + var log_data_width = $(this).find('.ui-pic').data('width'); + var log_width = $(this).find('.pic-data').find('img').width(); + + if(log_data_width < log_width && log_width > 300) { + log_data_width = log_width; + } + + var comment_width = $('#log_list .item-inner').width() - log_data_width + 10; + if(comment_width > 320) { + $(this).removeClass('both'); + $(this).find('.ui-comment').css('width', comment_width - 20 + "px"); + } else { + $(this).addClass('both'); + $(this).find('.ui-comment').css('width', "auto"); + } + }); +}; + +$('.new_win').on('click', function() { + var target = $(this).attr('href'); + window.open(target, 'emoticon', "width=400, height=600"); + return false; +}); \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/list.log.skin.php b/AvocadoEdition/skin/board/mmb/list.log.skin.php new file mode 100644 index 0000000..bd56a79 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/list.log.skin.php @@ -0,0 +1,180 @@ + 0 ? true : false; + +if($list_item['wr_type'] == 'UPLOAD') { + // Upload 형태로 로그를 등록 하였을 때 + $thumb = get_mmb_image($bo_table, $list_item['wr_id']); + $image_url = ''; + $image_width = $thumb['width']; + $image_height = $thumb['height']; +} else if($list_item['wr_type'] == 'URL') { + // URL 형태로 로그를 등록 하였을 때 + $image_url = ''; + $image_width = $list_item['wr_width']; + $image_height = $list_item['wr_height']; +} + +$log_class = ''; +$blind_class =''; +$h_class = ''; + +// 멤버공개 데이터일 시 +$is_viewer = true; +$data_width = 300; +$no_member_class = ''; + +if($list_item['wr_secret'] == '1' && !$is_member) { + $is_viewer = false; + $no_member_class = ' empty '; +} else { + $data_width = $image_width < 300 ? 300 : $image_width; +} + +if($is_viewer) { + + // 접기 여부 설정 + if($board['bo_gallery_height'] && ($image_height >= $board['bo_gallery_height'] || $list_item['wr_plip'] == '1')) { + if(G5_IS_MOBILE) { + $log_class .= "ui-slide-mobile"; + if($list_item['wr_type'] == 'UPLOAD') { + $thumb = get_list_thumbnail($bo_table, $list_item['wr_id'], $image_width, 200, true, true); + $ori = explode("/", $thumb['ori']); + $ori = $ori[count($ori) -1]; + $image_url = ''; + $image_url .= ''.$content.''; + $image_url .= ''; + $image_width = $thumb['width']; + $image_height = $thumb['height']; + } else if($list_item['wr_type'] == 'URL') { + $image_url = ''; + $image_url .= ''.$content.''; + $image_url .= ''; + } + } else { + $log_class .= "ui-slide"; + } + } + // 블라인드 (19금 필터링) 여부 설정 + if($list_item['wr_adult'] == '1') { + $blind_class = "ui-blind"; + } + // 리플 아래로 내리기 여부 설정 + if($list_item['wr_wide'] == '1') { + $h_class = "ui-wrap"; + } +} + + + + + +// 알람 내역이 있을 경우, 확인으로체크 +sql_query("update {$g5['call_table']} set bc_check = 1 where re_mb_id = '{$member['mb_id']}' and bo_table ='{$bo_table}' and wr_id = '{$list_item['wr_id']}'"); +?> + +
    +
    + +
    + + +
    +

    + + + No. + + + + + + + + + +

    + + 삭제 + 로그링크 + ' data-function="favorite" class="fav ">관심 + 수정 + +
    + + + + + + +
    + + + +
    + +
    + +
    +
    + +
    + + 멤버 공개용 로그 입니다. + +
    + +
    +
    diff --git a/AvocadoEdition/skin/board/mmb/list.skin.php b/AvocadoEdition/skin/board/mmb/list.skin.php new file mode 100644 index 0000000..9cc5860 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/list.skin.php @@ -0,0 +1,358 @@ +', 0); + +set_session('ss_bo_table', $_REQUEST['bo_table']); +set_session('ss_wr_id', $_REQUEST['wr_id']); + +if($character['ch_id']) { + // 사용가능 아이템 검색 + $temp_sql = "select it.it_id, it.it_name, inven.in_id from {$g5['inventory_table']} inven, {$g5['item_table']} it where it.it_id = inven.it_id and it.it_use_mmb_able = '1' and inven.ch_id = '{$character['ch_id']}' order by it_id asc"; + $mmb_item_result = sql_query($temp_sql); + $mmb_item = array(); + for($i = 0; $row = sql_fetch_array($mmb_item_result); $i++) { + $mmb_item[$i] = $row; + } +} + + +$owner_front = get_style('mmb_owner_name', 'cs_etc_2'); // 자기 로그 접두문자 +$owner_front = $owner_front['cs_etc_2']; +$owner_behind = get_style('mmb_owner_name', 'cs_etc_3'); // 자기 로그 접미문자 +$owner_behind = $owner_behind['cs_etc_3']; + +?> + +
    + + + + +
    + +
    + + +'.$wiget['cs_value'].'
    '; } +?> + + +
    + +
    + + + + + + + + +
    + +
    +
    + + + + + + + + + + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    > + +
    +
    > + +
    +
    + +
    +
    + + + /> + + + + /> + + + + + /> + + + + + /> + + + + + /> + + +
    +
    + +
    + + 등록하기 + + 새로고침 + 이모티콘 +
    + + +
    + + + +
    + 등록된 로그가 없습니다.
    "; } + ?> +
    + + +
    + +
    + + +
    + +
    + + + + + + + + + + +
    +
    + +
    + + + +
    + + + + + + + + + + + + +
    + + diff --git a/AvocadoEdition/skin/board/mmb/style.css b/AvocadoEdition/skin/board/mmb/style.css new file mode 100644 index 0000000..5c64853 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/style.css @@ -0,0 +1,234 @@ +@charset "utf-8"; +/* SIR 지운아빠 */ + + +.error { position:relative; text-align: center; line-height: 1.8em; padding-top: 70px; } +.error:before { content:"\ea0e"; display:block; position: absolute; font-family: 'icon'; font-size: 50px; line-height: 50px; top: 0;left:0; right: 0; text-align: center; } +.error .btn-group { padding: 20px 0 0; } + +.ui-mmb-list-category { text-align: center; } +.ui-mmb-list-category a { display: inline-block; position: relative; padding: 6px 10px; font-weight: bold; border-radius: 3px; } +.ui-mmb-list-category a.on:before { content: "\ea10"; font-family: 'icon'; padding-right: 5px; } + +.ui-mmb-button { text-align: center; padding-top: 10px; } + +.help.ui-btn { width: 100%; padding: 8px; line-height: 1.2em; border-radius: 3px; } +.ui-paging { margin-bottom:0; padding-bottom:0;} + + +/*************************************** + List Page +****************************************/ + +.connect-wiget { min-height: 40px; text-align: center; line-height: 40px; } + + +/** Notice Box **/ +.board-notice { width: 264px; padding: 10px; margin: 0 auto; text-align: center; box-sizing: border-box; } + + +/** Category List **/ +#navi_category { text-align: center; padding: 20px 0; } +#navi_category li { display: inline-block; padding: 0 20px; } + + +#log_list { position: relative; margin-top: 30px; } + +#log_list .empty_list { text-align: center; line-height: 100px; } + +#log_list .item { clear: both; margin: 0 0 35px 0; padding-bottom: 10px; } +#log_list .item:after { content: ""; display: block; clear: both; } +#log_list .item .ui-pic, +#log_list .item .ui-comment { float: left; box-sizing: border-box; } +#log_list .item .ui-comment { padding: 30px 0px 0px; margin-left: 10px; overflow: hidden; } +#log_list .item-comment-box { overflow: hidden; } + +#log_list .item.ui-wrap .ui-pic, +#log_list .item.ui-wrap .ui-comment, +#log_list .item.both .ui-pic, +#log_list .item.both .ui-comment { float: none; clear: both; } +#log_list .item.ui-wrap .ui-comment, +#log_list .item.both .ui-comment { margin-left: 0px; padding-top: 20px; width: 100% !important; box-sizing: border-box; } + + +/** Picture */ +#log_list .item .ui-pic { position: relative; min-width: 300px; } +#log_list .item .ui-pic .pic-header { position: relative; line-height: 30px; padding: 0 10px; } + +#log_list .item .ui-pic .pic-header .no { display: inline-block; vertical-align: middle; font-weight: bold; font-size: 14px; } +#log_list .item .ui-pic .pic-header .del { display: inline-block; vertical-align: middle; position: relative; width: 14px; height: 14px; line-height: 14px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item .ui-pic .pic-header .del:before { content: 'X'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 14px; text-indent: 0; text-align: center; font-size: 11px; font-weight: bold;} +#log_list .item .ui-pic .pic-header .mod { display: inline-block; float: right; vertical-align: middle; position: relative; width: 14px; height: 30px; line-height: 30px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item .ui-pic .pic-header .mod:before { content: 'M'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 30px; text-indent: 0; text-align: center; font-size: 11px; font-weight: bold;} +#log_list .item .ui-pic .pic-header .fav { display: inline-block; float: right; vertical-align: middle; position: relative; width: 14px; height: 30px; line-height: 30px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item .ui-pic .pic-header .fav:before { content: '\e9d9'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 30px; text-indent: 0; text-align: center; font-size: 11px; font-family: 'icon'; font-weight: bold;} +#log_list .item .ui-pic .pic-header .fav.on:before { color: yellow; } +#log_list .item .ui-pic .pic-header .new { display: inline-block; float: right; vertical-align: middle; position: relative; width: 14px; height: 30px; line-height: 30px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item .ui-pic .pic-header .new:before { content: '\ea7e'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 30px; text-indent: 0; text-align: center; font-size: 11px; font-family: 'icon'; font-weight: bold;} + +/* 카테고리 */ +#log_list .item .ui-pic .ico-category { font-size: 11px; font-family: 'Dotum'; font-weight: 400; } + +#log_list .item .ui-pic .pic-data { text-align: center; } +#log_list .item .ui-pic .pic-data.ui-blind { overflow: hidden; height: 250px; } +#log_list .item .ui-pic .pic-data.ui-slide > div { overflow: hidden; height: 470px; } +#log_list .item .ui-pic .pic-data.ui-slide > div { -webkit-transition: none; -moz-transition: none; -ms-transition: none; -o-transition: none; } +#log_list .item .ui-pic .pic-data.ui-slide > .ui-open-log { display: block; height: 25px; background: rgba(0, 0, 0, 0.7); text-align: center; line-height: 25px; } + +#log_list .item .ui-pic .pic-data.ui-slide-mobile > div { overflow: hidden; height: auto; } +#log_list .item .ui-pic .pic-data.ui-slide-mobile > div > a { display: block; position: relative; overflow: hidden; } +#log_list .item .ui-pic .pic-data.ui-slide-mobile > div > a:before { content: ""; display: block; position: absolute; line-height: 300px; font-size: 18px; top: 0; left: 0; right: 0; bottom: 0; color: #fff; background: rgba(0, 0, 0, 0.5); } +#log_list .item .ui-pic .pic-data.ui-slide-mobile > div > a:after { content: "클릭 시 원본 이미지를 확인할 수 있습니다."; display: block; position: absolute; top: 50%; left: 0; right: 0; color: #fff; transform: translateY(-50%); font-size: 15px; } + +#log_list .item .ui-pic .pic-data .ui-remove-blind { display: block; position: absolute; top: 30px; left: 0; right: 0; bottom: 0; background: #000; overflow: hidden; text-align: center; } +#log_list .item .ui-pic .pic-data .ui-remove-blind:before { content: ""; display: inline-block; width: 0px; height: 100%; vertical-align: middle; } +#log_list .item .ui-pic .pic-data .ui-remove-blind span { display: inline-block; font-size: 14px; line-height: 1.5em; vertical-align: middle; color: #999; } + + +/** Comment */ +#log_list .item-comment { position: relative; margin-bottom: 5px;; } +#log_list .item-comment .co-header { position: relative; line-height: 30px; padding: 5px 15px 0; } +#log_list .item-comment .co-header:after { content: ""; display: block; clear: both; } +#log_list .item-comment .co-header p { float: left; } +#log_list .item-comment .co-header .link { float: right; padding-right: 5px; } +#log_list .item-comment .co-header i { display: inline-block; height: 25px; } +#log_list .item-comment .co-header i img { max-height: 100%; } + +#log_list .item-comment .co-content { padding: 10px 15px; line-height: 1.6em; font-family: 'Dotum'; } +#log_list .item-comment .co-content .log_link_tag:before { content: "\e936"; font-family: 'icon'; padding-right: 5px; } +#log_list .item-comment .co-content .member_call { padding: 0 5px; } +#log_list .item-comment .co-content .member_call:before { content: "\e951"; font-family: 'icon'; padding-right: 3px; } +#log_list .item-comment .co-content .other-site-link { font-weight: bold; } +#log_list .item-comment .co-content .other-site-link:before { content: "\e9cb"; font-family: 'icon'; padding-right: 2px; } + +#log_list .item-comment .dice { display: block; padding-bottom: 10px; } +#log_list .item-comment .dice img { border-radius: 3px; overflow: hidden; } + +#log_list .item-comment .link-box { display: block; padding-bottom: 10px; } + +#log_list .item-comment .co-footer { line-height: 25px; padding: 0 15px; } +#log_list .item-comment .co-footer:after { content: ""; display: block; clear: both; } +#log_list .item-comment .co-footer .date { } + +#log_list .item-comment .co-footer .del { display: inline-block; float: right; vertical-align: middle; position: relative; width: 14px; height: 30px; line-height: 30px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item-comment .co-footer .del:before { content: 'X'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 30px; text-indent: 0; text-align: center; font-size: 11px; font-weight: bold;} +#log_list .item-comment .co-footer .mod { display: inline-block; float: right; vertical-align: middle; position: relative; width: 14px; height: 30px; line-height: 30px; overflow: hidden; text-indent: -999px; padding-left: 10px; } +#log_list .item-comment .co-footer .mod:before { content: 'M'; display: block; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 30px; text-indent: 0; text-align: center; font-size: 11px; font-weight: bold; } + +#log_list .item-comment-form-box { padding: 15px 0 0; } +#log_list .bo_vc_w { position: relative; padding-right: 70px; } +#log_list .bo_vc_w .input-comment { position: relative; margin-bottom: 5px; } +#log_list .bo_vc_w .input-comment textarea { display: block; width: 100%; height: 80px; box-sizing: border-box; margin: 0;} + +#log_list .bo_vc_w .btn_confirm { display: block; position: absolute; top: 0; right: 0; bottom: 0; width: 70px; } +#log_list .bo_vc_w .btn_confirm .ui-comment-submit { display: block; width: 100%; height: 100%; } + +#log_list .modify_area { display: none; position: relative; padding-right: 60px; } +#log_list .modify_area textarea { display: block; width: 100%; min-height: 100px; padding: 10px; } +#log_list .modify_area button { display: block; position: absolute; top: 0; right: 0; width: 60px; height: 100%; bottom: 0; } + + +.log-item-box { + position: relative; + padding-left: 70px; + min-height: 60px; + margin-bottom: 10px; +} +.log-item-box em { + display: block; + position: absolute; + width: 60px; + height: 60px; + overflow: hidden; + top: 0; + left: 0; +} +.log-item-box p { padding: 10px 0; } +.log-item-box p span { display: block; } + + + +/*************************************** + Write Page +****************************************/ + +#bo_w { max-width: 640px; margin: 0 auto; padding: 20px 0; } + +#bo_w dl, +#bo_w dt, +#bo_w dd { display: block; position: relative; margin: 0; padding: 0; } +#bo_w dl { overflow: hidden; } + +#bo_w label { cursor: pointer; } + +#bo_w dt { position: absolute; top: 0; left: 0; line-height: 30px; width: 70px; padding: 5px 0; font-size: 12px; } +#bo_w dt select { box-sizing: border-box; width:100%; font-size: 12px; } +#bo_w dd { padding: 5px 0; min-height: 30px; line-height: 30px; margin-left: 70px; } +#bo_w dd fieldset { display: inline-block; padding-right: 12px; } + +#view_image + dl dt { width:100px; } +#view_image + dl dd { margin-left:100px; } + +#bo_w .frm_input { width: 100%; } +#bo_w #wr_content { height: 170px; padding: 10px; } + + +#view_image { position: relative; width: 100%; height: 330px; line-height: 330px; overflow: hidden; margin: 0 auto; text-align: center; } +#view_image img { max-width: 100%; max-height: 330px; } +#view_image em { display: none; position: absolute; top: 0; left: 0; right: 0; bottom: 0; line-height: 330px; text-align: center; } +#view_image em img { width: 50px; height: 50px; } +#view_image > span { position: absolute; left: 0; right: 0; bottom: 0; height: 30px; line-height: 30px; text-align: center; } + + +#board_category { text-align: center; } +#board_category input { display: none; } +#board_category li { display: inline-block; line-height: 31px; } +#board_category li label { display: inline-block; cursor: pointer; padding: 0 15px;} +#board_category input:checked + label { } +#board_category input:checked + label:before { content: "《 "; } +#board_category input:checked + label:after { content: " 》"; } + +#board_action { padding-top: 15px; } + +#load_log_board .inner { padding: 0 30px 0; } +@media all and (max-width: 640px) { + #load_log_board .inner { padding: 0 0 0; } +} + +.comment-data { display: none; padding: 10px 0 10px 20px; border-left: 1px solid #996c33; margin-left: 5px; } +.comment-data.on { display: block; } +.comment-data select, +.comment-data input[type="text"] { width: 100%; box-sizing: border-box; } + + +.ui-mmb-list-write { + position: relative; + max-width: 400px; + margin: 0 auto; +} +.ui-mmb-list-write span { display: inline-block; margin: 3px; } +.upload-box + fieldset { padding: 10px 0; } +.upload-box { + position: relative; + padding-left: 95px; + padding-right: 80px; + box-sizing: border-box; +} +.upload-box select { + position: absolute; + top: 0; + left: 0; + width: 95px; +} +.upload-box fieldset { display: block; position: relative; } +.upload-box input[type="file"], +.upload-box input[type="text"] { width: 100%; box-sizing: border-box; } +.upload-box button { display: block; position: absolute; top: 0; right: 0; width: 80px; height: 30px; } + +.guest-box { position: relative; padding-left: 50%; margin-bottom: 3px; } +.guest-box input { width: 100%; } +.guest-box .name { position: absolute; top: 0; left: 0; width: 50%; padding-left: 60px; box-sizing: border-box; } +.guest-box .name label { display: block; position: absolute; top: 0; left: 0; width: 60px; line-height: 30px; } +.guest-box .pw { position: relative; padding-left: 60px; box-sizing: border-box; } +.guest-box .pw label { display: block; position: absolute; top: 0; left: 0; width: 60px; line-height: 30px; } + diff --git a/AvocadoEdition/skin/board/mmb/view.skin.php b/AvocadoEdition/skin/board/mmb/view.skin.php new file mode 100644 index 0000000..0f09cf7 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/view.skin.php @@ -0,0 +1,3 @@ + diff --git a/AvocadoEdition/skin/board/mmb/view_comment.php b/AvocadoEdition/skin/board/mmb/view_comment.php new file mode 100644 index 0000000..0e8c9cf --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/view_comment.php @@ -0,0 +1,117 @@ += $board['bo_comment_level']) + $is_comment_write = true; + +// 코멘트 출력 +//$sql = " select * from {$write_table} where wr_parent = '{$wr_id}' and wr_is_comment = 1 order by wr_comment desc, wr_comment_reply "; +$sql = " select * from $write_table where wr_parent = '{$list_item['wr_id']}' and wr_content != '' order by wr_datetime asc "; +$result = sql_query($sql); +for ($c_i=0; $c_row=sql_fetch_array($result); $c_i++) +{ + $comment[$c_i] = $c_row; + + //$comment[$c_i]['name'] = get_sideview($c_row['mb_id'], cut_str($c_row['wr_name'], 20, ''), $c_row['wr_email'], $c_row['wr_homepage']); + + $tmp_name = get_text(cut_str($c_row['wr_name'], $config['cf_cut_name'])); // 설정된 자리수 만큼만 이름 출력 + if ($board['bo_use_sideview']) + $comment[$c_i]['name'] = get_sideview($c_row['mb_id'], $tmp_name, $c_row['wr_email'], $c_row['wr_homepage']); + else + $comment[$c_i]['name'] = ''.$tmp_name.''; + + + + // 공백없이 연속 입력한 문자 자르기 (way 보드 참고. way.co.kr) + //$comment[$c_i]['content'] = eregi_replace("[^ \n<>]{130}", "\\0\n", $c_row['wr_content']); + + $comment[$c_i]['content'] = $comment[$c_i]['content1']= '비밀글 입니다.'; + if (!strstr($c_row['wr_option'], 'secret') || + $is_admin || + ($write['mb_id']==$member['mb_id'] && $member['mb_id']) || + ($c_row['mb_id']==$member['mb_id'] && $member['mb_id'])) { + $comment[$c_i]['content1'] = $c_row['wr_content']; + $comment[$c_i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $comment[$c_i]['content'] = search_font($stx, $comment[$c_i]['content']); + } else { + $ss_name = 'ss_secret_comment_'.$bo_table.'_'.$comment[$c_i]['wr_id']; + + if(!get_session($ss_name)) + $comment[$c_i]['content'] = '댓글내용 확인'; + else { + $comment[$c_i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $comment[$c_i]['content'] = search_font($stx, $comment[$c_i]['content']); + } + } + + $comment[$c_i]['datetime'] = substr($c_row['wr_datetime'],2,14); + + // 관리자가 아니라면 중간 IP 주소를 감춘후 보여줍니다. + $comment[$c_i]['ip'] = $c_row['wr_ip']; + if (!$is_admin) + $comment[$c_i]['ip'] = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $c_row['wr_ip']); + + $comment[$c_i]['is_reply'] = false; + $comment[$c_i]['is_edit'] = false; + $comment[$c_i]['is_del'] = false; + if ($is_comment_write || $is_admin) + { + $token = ''; + + if ($member['mb_id']) + { + if ($c_row['mb_id'] == $member['mb_id'] || $is_admin) + { + set_session('ss_delete_comment_'.$c_row['wr_id'].'_token', $token = uniqid(time())); + $comment[$c_i]['del_link'] = './delete_comment.php?bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&token='.$token.'&page='.$page.$qstr; + $comment[$c_i]['is_edit'] = true; + $comment[$c_i]['is_del'] = true; + } + } + else + { + if (!$c_row['mb_id']) { + $comment[$c_i]['del_link'] = './password.php?w=x&bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&page='.$page.$qstr; + $comment[$c_i]['is_del'] = true; + } + } + + if (strlen($c_row['wr_comment_reply']) < 5) + $comment[$c_i]['is_reply'] = true; + } + + // 05.05.22 + // 답변있는 코멘트는 수정, 삭제 불가 + if ($i > 0 && !$is_admin) + { + if ($c_row['wr_comment_reply']) + { + $tmp_comment_reply = substr($c_row['wr_comment_reply'], 0, strlen($c_row['wr_comment_reply']) - 1); + if ($tmp_comment_reply == $comment[$c_i-1]['wr_comment_reply']) + { + $comment[$c_i-1]['is_edit'] = false; + $comment[$c_i-1]['is_del'] = false; + } + } + } +} + +// 코멘트수 제한 설정값 +if ($is_admin) +{ + $comment_min = $comment_max = 0; +} +else +{ + $comment_min = (int)$board['bo_comment_min']; + $comment_max = (int)$board['bo_comment_max']; +} + +//array_unshift($comment, $list_item); +include($board_skin_path.'/view_comment.skin.php'); + +?> \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/view_comment.skin.php b/AvocadoEdition/skin/board/mmb/view_comment.skin.php new file mode 100644 index 0000000..ecde2c9 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/view_comment.skin.php @@ -0,0 +1,157 @@ +\]/i", "", $content); + + if($log_comment['wr_log'] && !$is_admin) { + // 로그 (탐색 / 조합 등의 액션 수행)의 흔적이 있을 경우 + // 관리자가 아니면 삭제 불가 + $is_delete = false; + } + + if($log_comment['wr_id'] != $log_comment['wr_id'] && ($log_comment['is_reply'] || $log_comment['is_edit'] || $log_comment['is_del'])) { + // 답변, 수정, 삭제가 가능할 경우 + // 또한, 본문의 id와 코멘트의 id가 다를 경우 (같을 경우엔 로그의 상단에 있는 컨트롤을 통해 액션 수행이 가능하다) + $query_string = str_replace("&", "&", $_SERVER['QUERY_STRING']); + if($w == 'cu') { + $sql = " select wr_id, wr_content from $write_table where wr_id = '$indexd' and wr_is_comment = '1' "; + $cmt = sql_fetch($sql); + $c_wr_content = $cmt['wr_content']; + } + + $c_reply_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=c#bo_vc_w_'.$list_item['wr_id']; + $c_edit_href = './board.php?'.$query_string.'&c_id='.$comment_id.'&w=cu#bo_vc_w_'.$list_item['wr_id']; + } + + // 캐릭터 정보 출력 + $is_comment_owner = false; + $comment_owner_front = ""; // 자기 로그 접두문자 + $comment_owner_behind = ""; // 자기 로그 접미문자 + + if(!$log_comment['wr_noname']) { + if(is_file(G5_DATA_PATH."/site/ico_admin") && $config['cf_admin'] == $log_comment['mb_id']) { + // 관리자 아이콘이 존재하고, 관리자와 작성자가 동일 할 경우 + // 관리자 아이콘을 출력한다. + $log_comment['ch_name'] = "관리자"; + } else { + // 캐릭터 정보 로드 + $ch = get_character($log_comment['ch_id']); + if($ch['ch_id']) { + // 캐릭터 정보가 존재할 경우, 캐릭터 정보를 추가한다. + // 캐릭터 링크 + // + 캐릭터 소속 아이콘 + // + 캐릭터 종족 아이콘 + // + 캐릭터 이름 + /*$log_comment['ch_name'] = " + + ".get_side_icon($ch['ch_side']).get_class_icon($ch['ch_class'])." + ".get_title_image($log_comment['ti_id'])." + ".($log_comment['wr_subject'] ? $log_comment['wr_subject'] : "GUEST")." + ";*/ + $log_comment['ch_name'] = " + + ".get_side_icon($ch['ch_side'])." + ".get_title_image($log_comment['ti_id'])." + ".($ch['ch_name'] ? $ch['ch_name'] : "GUEST")." + "; + } else { + // 캐릭터 정보가 존재하지 않을 경우, 빈값을 출력한다. + $log_comment['ch_name'] = ""; + } + } + + // 오너 정보 출력 + if($log_comment['mb_id']) { + $log_comment['name'] = "{$log_comment['wr_name']}"; + } else { + $log_comment['name'] = $log_comment['wr_name']; + } + + if(!$list_item['wr_noname'] && $list_item['mb_id'] == $log_comment['mb_id']) { + $is_comment_owner = true; + $comment_owner_front = $owner_front; + $comment_owner_behind = $owner_behind; + } + } else { + $is_comment_owner = false; + + } +?> + + +
    +
    + + +

    > + + + [] + +

    + +

    익명의 누군가

    + +
    + +
    +
    + + + + + + + + + LINK + + + LINK + + + +
    + +
    + + +
    + +
    + + +
    + + + diff --git a/AvocadoEdition/skin/board/mmb/write.skin.php b/AvocadoEdition/skin/board/mmb/write.skin.php new file mode 100644 index 0000000..23ba184 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/write.skin.php @@ -0,0 +1,686 @@ +', 0); + +if($board['bo_use_chick'] && $w == '') { + goto_url(G5_HTTP_BBS_URL.'/board.php?bo_table='.$bo_table.$qstr); +} + +$is_error = false; +$option = ''; +$option_hidden = ''; +if ($is_notice || $is_html || $is_secret || $is_mail) { + $option = ''; + if ($is_notice) { + $option .= "\n".''."\n".''; + } + + if ($is_html) { + if ($is_dhtml_editor) { + $option_hidden .= ''; + } else { + $option .= "\n".''."\n".''; + } + } + + if ($is_secret) { + if ($is_admin || $is_secret==1) { + $option .= "\n".''."\n".''; + } else { + $option_hidden .= ''; + } + } + + if ($is_mail) { + $option .= "\n".''."\n".''; + } +} + +/*if(!$character['ch_id']) { +?> +
    + + 작성권한이 없습니다.
    + 계정로그인을 해주시길 바랍니다. + + + + 대표캐릭터가 설정되지 않았습니다.
    + 마이페이지에서 대표 캐릭터를 선택해 주시길 바랍니다. + + + +
    +"; + + $category_option .= " + + + \n"; + } + + $is_category = true; + } + + $image_url = $board_skin_url."/img/no_image.png"; + if($w == 'u') { + if($write['wr_type'] == 'URL') { + $image_url = $write['wr_url']; + $img_data = "width : ".$write['wr_width']."px / height : ".$write['wr_height']."px"; + } else if($file[0]['file']) { + $image_url = $file[0]['path']."/".$file[0]['file']; + $img_data = "width : ".$file[0]['wr_width']."px / height : ".$file[0]['wr_height']."px"; + } + + if($write['wr_subject'] == "--|UPLOADING|--") { + $write['wr_subject'] = $character['ch_name']; + if(!$write['wr_subject']) $write['wr_subject'] = 'GUEST'; + } + + } else { + $write['wr_subject'] = $character['ch_name']; + if(!$write['wr_subject']) $write['wr_subject'] = 'GUEST'; + } + + $temp_sql = "select ch_thumb, mb_id, ch_id, ch_name from {$g5['character_table']} where ch_state = '승인' and ch_type != 'test' and ch_id != '{$character['ch_id']}' order by ch_type asc, ch_name asc"; + $re_ch_result = sql_query($temp_sql); + $re_ch = array(); + for($i = 0; $row = sql_fetch_array($re_ch_result); $i++) { + $re_ch[$i] = $row; + } + + ?> + +
    +
    + +
    + + + + + + + + + + + + + + + + + +
    + + ...LOADING... + + + +
    + +
    +
    + +
    +
    +
    > + + + + +
    +
    > + +
    +
    +
    + +
    + +
      + +
    + + + +
    +
    +
    + +
    +
    + +
    +
    + +
    + +
    +
    다이스 개수
    +
    + 개 굴립니다. +
    +
    + +
    + +
    + +
    +
    ITEM 1
    +
    + +
    +
    +
    +
    ITEM 2
    +
    + +
    +
    +
    +
    ITEM 3
    +
    + +
    +
    +
    + +
    + + +
    + + 0) { ?> +
    +
    + +
    +
    + +
    +
    + + + +
    +
    + Option +
    +
    +
    + + + + + + +
    + +
    + /> + +
    +
    + /> + +
    + +
    + /> + +
    +
    + /> + +
    + +
    + /> + +
    + +
    +
    + + +
    +
    + +
    +
    + +
    +
    + + + +
    +
    + +
    +
    + +
    +
    + + + +
    +
    + +
    +
    + " id="wr_link" class="frm_input" size="50"> +
    +
    + + +
    +
    + +
    + +
    + + +

    이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

    + + + + +
    글자
    + +

    해시태그 : #해시태그내용 / 로그링크 : @로그번호 / 멤버알람 : [[닉네임]]

    +
    + +
    + +
    + + +
    +
    + +
    +
    +
    +
    + +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/mmb/write_comment.php b/AvocadoEdition/skin/board/mmb/write_comment.php new file mode 100644 index 0000000..d6844b8 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/write_comment.php @@ -0,0 +1,68 @@ + + + + + diff --git a/AvocadoEdition/skin/board/mmb/write_comment_update.skin.php b/AvocadoEdition/skin/board/mmb/write_comment_update.skin.php new file mode 100644 index 0000000..30788c2 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/write_comment_update.skin.php @@ -0,0 +1,39 @@ + diff --git a/AvocadoEdition/skin/board/mmb/write_update.inc.php b/AvocadoEdition/skin/board/mmb/write_update.inc.php new file mode 100644 index 0000000..269985e --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/write_update.inc.php @@ -0,0 +1,226 @@ + 0) { + // -- 괄호를 치환한다. + $memo = str_replace("[[", "", $wr_content); + $memo = str_replace("]]", "", $memo); + + for($i=0; $i < count($mb_nick_array); $i++) { + // 회원 정보 있는지 여부 확인 + $memo_search = sql_fetch("select mb_id, mb_name from {$g5['member_table']} where mb_nick = '{$mb_nick_array[$i]}' or mb_name = '{$mb_nick_array[$i]}'"); + if($memo_search['mb_id']) { + // 회원정보가 있을 시, 알람테이블에 저장한다. + // 저장하기 전에 동일한 정보가 있는지 확인한다. + // 저장정보 : wr_id / wr_num / bo_table/ mb_id / mb_name / re_mb_id / re_mb_name / ch_side / memo / bc_datetime + + $bc_sql_common = " + wr_id = '{$temp_wr_id}', + wr_num = '{$wr_num}', + bo_table = '{$bo_table}', + mb_id = '{$member['mb_id']}', + mb_name = '{$member['mb_nick']}', + re_mb_id = '{$memo_search['mb_id']}', + re_mb_name = '{$memo_search['mb_name']}', + ch_side = '{$character['ch_side']}', + memo = '{$memo}', + bc_datetime = '".G5_TIME_YMDHIS."' + "; + + + // 동일 정보 있는지 확인 - wr_id/ bo_table / re_mb_id 로 판별 + $bc = sql_fetch(" select bc_id from {$g5['call_table']} where wr_id= '{$temp_wr_id}' and bo_table= '{$bo_table}' and re_mb_id = '{$memo_search['mb_id']}' and mb_id = '{$member['mb_id']}' "); + + if($bc['bc_id']) { + // 정보가 있을 경우 + $sql = " update {$g5['call_table']} set {$bc_sql_common} where bc_id = '{$bc['bc_id']}' "; + sql_query($sql); + } else { + // 정보가 없을 경우 + $sql = " insert into {$g5['call_table']} set {$bc_sql_common} "; + sql_query($sql); + + // 회원 테이블에서 알람 업데이트를 해준다. + // 실시간 호출 알림 기능 + $log_link = G5_BBS_URL."/board.php?bo_table=".$bo_table."&log=".($wr_num * -1); + $sql = " update {$g5['member_table']} + set mb_board_call = '".$member['mb_nick']."', + mb_board_link = '{$log_link}' + where mb_id = '".$memo_search['mb_id']."' "; + sql_query($sql); + } + } else { + // 회원정보가 없을 시, content 에 해당 닉네임을 블러 처리 하고 + // content 를 업데이트 한다. + $wr_content = str_replace("[[".$mb_nick_array[$i]."]]", "[[???]]", $wr_content); + $memo_custom_sql .= " , wr_content = '{$wr_content}' "; + } + } +} +// ******************** 호출 관련, 호출 시 해당 멤버에게 쪽지 보내기 기능 종료 + +if($w != 'cu') { + $customer_sql = " + {$memo_custom_sql} + "; + + if($use_item) { + $it = sql_fetch("select it.it_type, it.it_use_ever, it.it_name, it.it_id, it.it_value, it.it_content, it.it_content2 from {$g5['item_table']} it, {$g5['inventory_table']} inven where inven.in_id = '{$use_item}' and inven.it_id = it.it_id"); + + // 아이템 제거 + if(!$it['it_use_ever']) { + // 영구성 아이템이 아닐 시, 사용했을 때 인벤에서 제거한다. + delete_inventory($use_item); + } + + // 아이템이 뽑기 아이템의 경우 + if($it['it_type'] == '뽑기') { + $seed = rand(0, 100); + + // 템 검색 시작 + $item_result = sql_fetch(" + select re_it_id as it_id + from {$g5['explorer_table']} + where it_id = '".$it['it_id']."' + and (ie_per_s <= '{$seed}' and ie_per_e >= '{$seed}') + order by RAND() + limit 0, 1 + "); + + if($item_result['it_id']) { + // 아이템 획득에 성공한 경우, 해당 아이템을 인벤토리에 삽입 + // 아이템 획득에 성공 시 + $item_result['it_name'] = get_item_name($item_result['it_id']); + insert_inventory($character['ch_id'], $item_result['it_id']); + $item_log = "S||".$it['it_id']."||".$it['it_name']."||".$item_result['it_id']."||".$item_result['it_name']; + } else { + $item_log = "F||".$it['it_id']."||".$it['it_name']; + } + } else { + // 일반 아이템의 경우, 기본 사용 로그를 반환한다. + $item_log = "D||".$it['it_id']."||".$it['it_name']."||".$it['it_type']."||".$it['it_value']."||".$it['it_content']."||".$it['it_content2']; + } + $customer_sql .= " , wr_item = '{$it['it_id']}', wr_item_log = '{$item_log}'"; + + } + + if($game == "dice") { + // 주사위 굴리기 + $dice1 = rand(1, 6); + $dice2 = rand(1, 6); + $customer_sql .= " , wr_dice1 = '{$dice1}', wr_dice2 = '{$dice2}'"; + } + + $log = ""; + + //-------------------------------------------------------- + // 탐색 : 아이템 사용 없이 행위만으로 아이템 획득 가능 + // - 아이템 획득 제한 체크 필요 + //---------------------------------------------------------- + if($action == 'S') { + + if($character['ch_search'] < $config['cf_search_count']) { + // 탐색 횟수가 하루탐색 횟수를 초과하지 않은 경우 + // 주사위 굴리기 + $seed = rand(0, 100); + + // 나온 숫자의 구간에 해당하는 아이템 중, 하나를 선택한다. + $item_result = sql_fetch(" + select it_id, it_name + from {$g5['item_table']} + where + it_use = 'Y' + and it_seeker = '1' + and (it_seeker_per_s <= '{$seed}' and it_seeker_per_e >= '{$seed}') + order by RAND() + limit 0, 1 + "); + + if($item_result['it_id']) { + // 아이템 획득에 성공한 경우, 해당 아이템을 인벤토리에 삽입 + // 아이템 획득에 성공 시 + insert_inventory($character['ch_id'], $item_result['it_id']); + $log = $action."||S||".$item_result['it_id']."||".$item_result['it_name']."||".$in_id; + } else { + $log = $action."||F"; + } + + // 탐색 횟수 업데이트 + sql_query(" + update {$g5['character_table']} + set ch_search = ch_search + 1, + ch_search_date = '".G5_TIME_YMD."' + where ch_id = '{$character['ch_id']}' + "); + + $character['ch_search'] = $character['ch_search'] + 1; + $customer_sql .= " , wr_log = '{$log}' "; + } + } + + //-------------------------------------------------------- + // 조합 + //---------------------------------------------------------- + if($action == 'H') { + // 재료 정보 : make_1, make_2, make_3 + $make_1 = get_inventory_item($make_1); + $make_2 = get_inventory_item($make_2); + $make_3 = get_inventory_item($make_3); + + $re_item[0] = $make_1['it_id']; + $re_item[1] = $make_2['it_id']; + $re_item[2] = $make_3['it_id']; + sort($re_item); + $re_item_order = implode("||", $re_item); + + $re = sql_fetch("select it_id from {$g5['item_table']}_recepi where re_item_order = '{$re_item_order}' and re_use = '1'");; + if(!$re['it_id']) { + // 레시피 조합 실패 + $log = $action."||F||NON||NON||".$re_item_order; + } else { + // 레시피 조합 성공 + $item = get_item($re['it_id']); + insert_inventory($character['ch_id'], $item['it_id'], $item); + $log = $action."||S||".$re['it_id']."||".$item['it_name']."||".$in_id."||".$re_item_order; + } + + $customer_sql .= " , wr_log = '{$log}' "; + + if(!$make_1['it_use_ever']) { delete_inventory($make_1['in_id']); } + if(!$make_2['it_use_ever']) { delete_inventory($make_2['in_id']); } + if(!$make_3['it_use_ever']) { delete_inventory($make_3['in_id']); } + } +} + +?> + diff --git a/AvocadoEdition/skin/board/mmb/write_update.skin.php b/AvocadoEdition/skin/board/mmb/write_update.skin.php new file mode 100644 index 0000000..ebdf710 --- /dev/null +++ b/AvocadoEdition/skin/board/mmb/write_update.skin.php @@ -0,0 +1,78 @@ + + + + +
    + + + + + +
    + + + + diff --git a/AvocadoEdition/skin/board/qna/_common.php b/AvocadoEdition/skin/board/qna/_common.php new file mode 100644 index 0000000..0b106fb --- /dev/null +++ b/AvocadoEdition/skin/board/qna/_common.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/ajax.filter.php b/AvocadoEdition/skin/board/qna/ajax.filter.php new file mode 100644 index 0000000..847846c --- /dev/null +++ b/AvocadoEdition/skin/board/qna/ajax.filter.php @@ -0,0 +1,72 @@ + diff --git a/AvocadoEdition/skin/board/qna/img/a_face.gif b/AvocadoEdition/skin/board/qna/img/a_face.gif new file mode 100644 index 0000000000000000000000000000000000000000..0db9864001b28f14f05f624dec64f1589fd51e4a GIT binary patch literal 241 zcmVr0ZEV@GXMYp literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/btn_cencel.gif b/AvocadoEdition/skin/board/qna/img/btn_cencel.gif new file mode 100644 index 0000000000000000000000000000000000000000..30fe0bb650596f9d98001f94df89c5891a078f6f GIT binary patch literal 140 zcmV;70CWFGNk%w1VJ!d<0FeLy|NsBv0R~0=N>uz?a1r*1pqr0$3JKQ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/btn_close.gif b/AvocadoEdition/skin/board/qna/img/btn_close.gif new file mode 100644 index 0000000000000000000000000000000000000000..ce3d44e617b60492721538922683e85b762930ee GIT binary patch literal 223 zcmZ?wbhEHbbYc);Sj524wQ%nH_wRFZaz1|iaO%{l|Ns9pfPvyq7BH;?B0*{yn3qUw zx%1E9lxFBoi`Qp&|GyW+lae_vW7WExs19b0^Iyadm##Z)ZuqY0folV&RJ*J4#tl#Q z)@+Pjc2lQlTIlW1%NZ-CI4Kq@&r?db&0~A;H(>3oH<9-|-LJoSUvZx0^V#|+i`d+h z{E~u(M!7QS)*z$&jOcRHy5NM!&<^Qd%UNA*g(mandlk;iTQX(B+MuQDHu@RpZr!$B VH+s`<6BaI!0|yTsWaMP91_1N(Vjlni literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/btn_comment_delete.gif b/AvocadoEdition/skin/board/qna/img/btn_comment_delete.gif new file mode 100644 index 0000000000000000000000000000000000000000..45d14b733935b3c8ea435ffbd754c202190ab85a GIT binary patch literal 94 zcmZ?wbhEHbquWDJ4ka y#U)hIhE3hh0?PuIwc)iFMsUXJ5Ij=uk20028kG&~Ui literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/comment.gif b/AvocadoEdition/skin/board/qna/img/comment.gif new file mode 100644 index 0000000000000000000000000000000000000000..508e31e25c363aeaf16e3c1a2929d791773a6067 GIT binary patch literal 185 zcmV;q07m~uNk%w1VM72E0FeLy@9*zqWMu#U{{R30A^8LW00062EC2ui07C#20007t zgpaAq?QevfwAzca)^Ym}f?Y_K;b^96g|4pIzVa7S!ENJ`F5tX>^VxdA0H(H^7<S^xk$o*7nf literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_home.gif b/AvocadoEdition/skin/board/qna/img/e_home.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ffdfd7c4a0604049963c957c858b3952ba07b59 GIT binary patch literal 860 zcmZ?wbhEHb6ldUO_|C{sTwKgB3PwXmEFVlo6A7~1(+nF=@xm0X%cl+*5XTv&9hUqnBN#WU#1i7p{WzmyZ3mY$x@#LUEC F4FE{98J_?E literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_list.gif b/AvocadoEdition/skin/board/qna/img/e_list.gif new file mode 100644 index 0000000000000000000000000000000000000000..fbd70f15ee76b7bcb002796646919f27665f745b GIT binary patch literal 263 zcmV+i0r>t$Nk%w1VHE%#0J8u9+S=N*w6yH(?9kBAkB^VX$H%LytM>Nxe0+SOqN0X| zhU4SozP`Sgn3!{ObN~PUA^8LV00000EC2ui02Kfp000EE@X1N5y*OjBv^|Vs5S=H5 z%<(LSIVgcDEyyrnOVe;g&^U-jz)_+s9E6{v!59c8Op8FlD0B`02BX9XTojLNLsS3| zB!kBHp|DZ{fH2sy3ot5$*28guF9-rX4MBGg2t^ZG4+#VYTNMpA6##k}b{}dQ17{X< z8hmsn3NmkT8V#lt45<`Yc?eGxQwa${1P%%f2~DvkzQ3P)6`;Wrd=AJS$HEfC8OzMh N7|X=cz}F@b06R@HXg~k} literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_mail.gif b/AvocadoEdition/skin/board/qna/img/e_mail.gif new file mode 100644 index 0000000000000000000000000000000000000000..d9525890f0fcbc397e3687b6ccfc7c000bb1e04e GIT binary patch literal 70 zcmZ?wbhEHb6ldUOXkcV0E-wE6|G(l-7DfgJMg|=QAOOiQFv<4xuRQ(sJOjt&E0M}~ XXYB6tjAO2n&77rlWZOGw5e91j%+MB_ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_name.gif b/AvocadoEdition/skin/board/qna/img/e_name.gif new file mode 100644 index 0000000000000000000000000000000000000000..794541be253016215b2e2c849cf612dae970357a GIT binary patch literal 860 zcmZ?wbhEHb6ldUO_|C{sTwKgB3PwXmEFVlo668XEbTEv9H(NOWo9Hx9b8;-kXxP8rp>BRe*xc=W3UN2Q$DwDk0JCT1oE FYXE^l8&?1T literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_pass.gif b/AvocadoEdition/skin/board/qna/img/e_pass.gif new file mode 100644 index 0000000000000000000000000000000000000000..f2e1288e334cf8cd09c2580e22e6244fdb41a602 GIT binary patch literal 73 zcmZ?wbhEHb6ldUOXkcI{E-wE6|G(l-7DfgJMg|=QAOOiQFe&u(uRQ&BKZC_(kLas+ a8l%fg6Q^Z{l-FI{8LG%~{8NqygEask9~iU% literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/e_search.gif b/AvocadoEdition/skin/board/qna/img/e_search.gif new file mode 100644 index 0000000000000000000000000000000000000000..815e4eaa26ee1ae723ce892e88fae7b9b4967306 GIT binary patch literal 197 zcmV;$06PCiNk%w1VH5xt0J8u9$H&Le(9rhw_M)PqR4+S=N_zP|te{{R30A^8LV00000EC2ui02BZh000DX(8)=wy%@8M$!f~MVNEk$ zjM9i_MJTN`Af*rk3%~>ea59UE!N+M3DTPg@5wJ80MU#YpP$&}8OJgAb8I%C1CQ)eE zB%wkRlTc0;3l?D**+>jIvMw0J{XBQBf=ihf2YLP&|Z-1#?2M7Ld2aBhl!^ z7=vu!@JR$J2eH9n8*EZqmi-|149pxKoqnfjRVFK0SO3%3ke|*2xzbZ NoCAUl_&kUJ06XkGYj*$u literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/g_face2.gif b/AvocadoEdition/skin/board/qna/img/g_face2.gif new file mode 100644 index 0000000000000000000000000000000000000000..f4e135abb025be95aa74b8dcc81c4df7bf285ea3 GIT binary patch literal 294 zcmV+>0ondXNk%w1VH^M#0J8u9tE;Qf(9qi2+Q-MohK7csqN234wCwEckB^Vz``ZiOoW|IQkL_3k?eZJ_kn>3Je$oc|{2d4rm|?7+Mbp3=ISW z8FQW(3?vK%N(yLq3{4u21psCN3kV++4Iuyz1FNI8dJP8!E)4>`6T2sb3^a8QArd$~ sj1$F^4+#SyoFF0<3^#Ct7YSSf<^bIkQw9JA4KNn~Psw?{_V*D0J5&N`DgXcg literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/g_face3.gif b/AvocadoEdition/skin/board/qna/img/g_face3.gif new file mode 100644 index 0000000000000000000000000000000000000000..936307b83b771822b08a0e8eec9abaa9ef6de1d9 GIT binary patch literal 276 zcmV+v0qg!pNk%w1VHE%u0J8u9e0+SOqN32y(6qF)$H&L3tE+~FhU4Son3$OC?Cg(^ zkM{QVzP`TN+S+q-bN~PUA^8LV00000EC2ui02Kfi000ER@X1N5y*SI&G$xJ%3|?h~ z;c+z#u~2AeAoRc-V5m??2r!*QgQbW$CJTkag<+rq8%5#KsU%d7p5m2NFaTi0q@X(_ z90>`-urO>F4#5LnI0SYDhQt7j7tVSO4hI5)2Ms%CLPrS$gAWIB1Wp|e97jn3WK$9a zd;mKS4ns$C1qcKcUjbaB4+d2mX>(i?f@uc^SPu!X0tk9MViLIwTnPjOvl71uwR39) a1Vcj%3<0327%bNT);Qn>V(2IU4zf*wal#k`jgJ%1(+~oH76&kJ6#^ICOqHA@ z7*Yvvkr@aaaE}5^nO89lMhR+~O$c2N0}KpoeiaLZhKCal4F?ASa05e?Lj!SeIhz6p XfB`v#qN1BRnQ)Sfs;jK66cGSB_~=-F literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/g_face5.gif b/AvocadoEdition/skin/board/qna/img/g_face5.gif new file mode 100644 index 0000000000000000000000000000000000000000..bdd4ebafabc9725e258b47a733a59d0dc475b0a0 GIT binary patch literal 256 zcmV+b0ssC-Nk%w1VG{rs0J8u9kB^Vg(9o-^tD>T!?Ck7@hK97XwD$J)+ftxr?<1`F_uR)*?1d5KM;6V)*&_d&pQg#T5Qlc=hcBUnSf`M3A z1uljH{2(k8Im)4t4FELi7sD`k7#cZy8!>YYBohT2I4%-28U`O}3mXIl2NFFf0t*F` z8#h}D1_2DE0+F8%3zrlEY#TwZ2@0$(2b&2DW?76AGYXu&Mh*us!W0Dv2A;M z$Ksr*{Py?t+uzuDi2wipA^8LV00000EC2ui02=@i000EL@X0BgVl?ahhI0VMX^24~ zjsk$@NHIq+NI}s#g_AVy#1spYfM;+p5DAb1(W5vf4&H;ISU3a;MMEkf02Y_WQxeTE z2vxzy5qww*v$2@VIWKIP1qMZzFf0KJ2OkRv1W7yvJOmCc4+I4(Yd8cA1`P`VQb-R; zj|qcp3JMMc0SYb)4TGT{0e(>hs3QoW2?k&Z06+%^2tz%WA_)Tw2@4AeNCzTK62DqZ UUI&iOehF$02g=rUeG?G?JFMbiQ~&?~ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/i_write.gif b/AvocadoEdition/skin/board/qna/img/i_write.gif new file mode 100644 index 0000000000000000000000000000000000000000..9f2077e70d7bb9f2bcac8b173d94365bb2dfe7d9 GIT binary patch literal 269 zcmV+o0rLJwNk%w1VHN-$0J8u9hK7c#tE;}gzQ@PM(9qDLqN03!e2?xg!Ik;dnAAuZO1?$j2{OK84U&iAPoU{2xuPy0ssI%PHPzqRSydS3JwKJ zCX5pS25ue&1p*`m0D>lLEGz{jtw9b#vlIgfvbVgwybcn;7{J62EEBK6!okMP!q3dh T&eP4+#}&oa%*ejo84&SetB)hvc#-a#YIc<3YSf2Ss9hNHacrm~YfVG-vZk74F_~+t z%a@gxEvYGAmXWhOK5KPu!Lp>BRoVH=W3$(^)-F#5vJ01I;M1%45R?XpDbYIIv^6{CkD1mha1@*I{RAIK1nQ=WUy;J9?;3y$)GHH z(8%?`zJv&MW0wgDY9E-)IC&(QCAf4NScMLIu!;p)uxJ`^vNG!7=QpI&%h)*r!V8+-RDX? c3$7aIr%L{q9XaPfhJvJRMwg_gkqCn|03!4nq5uE@ literal 0 HcmV?d00001 diff --git a/AvocadoEdition/skin/board/qna/img/icon_new.gif b/AvocadoEdition/skin/board/qna/img/icon_new.gif new file mode 100644 index 0000000000000000000000000000000000000000..0bebd3b49cfb6c7b85f9843693a9002bcc585664 GIT binary patch literal 77 zcmZ?wbhEHbG!7=QpI&%h)%r!V8+-RDX? d3+|z`(+w1LAfO_~r?c0SFET0|5Y3Kta?20a6J31Bf0V$!GwQkbYfs8e-XjK_P|%;2rdX zml)y7Xa=Mg%oYG*hi)-^UWFIT5l>bA^x}(>FlK0~NGg(~in5sA;ml}(kT1%W04|%u zac0{(a~zo*2WMM5XO11z0)Vg)>9%bn+LeCZMnV_OmmvWlBZLktxo0^LgYI%5<~_>+ zebQksVug04O%!yb*UR?y@A>i#pv%fM#yc1w?QemyEC%>fVG2n59WVpXsZ^>0m9C&b zS5u@Zs%fgw=_;B!8XB4!8airpS?GAkBj4T;B}GLgWhGT*WmSfZ4K#T#Zh7i<{_It3{)bsCBM^<$IV7(Ui5kY))3{{Dl1=-Dn3!sYl_%NQit}r{DP{%X zO%LDkBz9Uw`=^`xEREp%p4lw5*RG9xg#B?~#&6eh9>4dqSXMmq;PQ&=Pnx$JI(wtB zB`SIBtiqDAb2p#1I`~JYAg~vkz(jMWMAsnN1Wj$xdd15l5W}Eyy<3AaSQH zVc-^&ht)LMm?k|G=NEW~Yw{$v@65=!0Tgq)Gquo&&Dwn5NP8*vsLO=Ex4@#?g!Xzs zC&=D0_$t(iVNFKx4ta?$w&L`_BS-g z?k>{CiVYlx1O^k$WN)Zy$9vlKz-5Ft9Wr@`g?4nhs7%jXCR6TG03K6;JVhlL5AOgC zWJulKal(69TtRk+H$<*Qlf_||j_X*+?V-uKcw8XMlh7i=1OV&gWGKmici17rfOK#+ ztyhPigjB z$5(=iMJ&q6 z>ct|9#DWxo5EJHPLLItqIG%clj0fXNi8)e{KPJS)iBe2vO~kk?tOHDwgK-Xog22oa zCVc#_%TLG=XGHkMM8K>%oQpfZHz!z9Ajy)pzTot{#W7e1hq4K*ozEIBbJLkdZSv6xu;9e7kHyEj}hDaBiq zArkj+u9`gkA^u$gr~-zIgt)I2q@t{l9H|8BY#6wVmH`{mU%2!nkrXzlzwi}d6{mg+ zm%V+Kcw&GKFT|rsM$6wce99?r!iWrqBLHzGyy0%^cx#YU0OoImd;!pbQ?kBET;C+_ zX=~pku5S|e1C#at$0SbPLm9z-2!L>SA$XUh0=(crE&@q#*k^)JkP2xjyd*LTPHo^Y z`OgR@@RlbhPhUR6pa3dN9{#sK)c%wzm1a3xTMH#tiTICgE1oFRIxjKHnq$Sb2Cg1? zS&6)KOv+5c;27&>@%!;p7EA%(%_7<^m>rzujim|##*4A=@xvo{^YQCQ4#wOpI_%EP&9%z4u@Z?>tT|3jPS$L$HJ8hR2$p1= zP@0&>5=u;9ZZb0jFvaJ(`Z$V>rWQoBKC*RK$mvm;!WV+%} zXW2*@4n2;!b6l;zWx+({uuwrBmJ#D4$i##aXreoZ%kDsbE9tEg+e3xjOQnYdy1*JQ za}OW<5B!qVqY8V~1r$K9*jU5L_;(EH{I>M{TFUAa_o%8ao^yaeA{B|pxw~5bmG|$M zFBK&JP5Z(nJ&eYq&Tv+Y!IuJW*LVZ_3lDEDGGrQM>b{97G``DiB zE^Ie6QYetRb31JKhW+oj4t8?iuk+5{4{w4@R~U2l7Gv<&gAcsi@z0Jdwk?Ze7s2K_ z+c`ON9S5|5h^zozyuz61NO)j@FZKi5KLrmQcJRYY*GvyX_E1N%K`ppUzJNa2fkuvhMW z|2q0-?mzXHf-^E)>sCHmq`NOS58N1`8?-jkvKC^>MqDk zOu?+vval3a>u&D%?Ui@kaHND|rghgSjJMNr+nP!u0D7Dlm~ta+}FDL-1So) z_$hE->*{mYPkG>{z&Q_U%Li@zTQj;1mSddXuT<4)xO3G2xT(6`9DOd@v_8l^%)6;Xd6EK z3J>WSkj}`JX5oB%HJ6c;j?*Z<6@ej!20~f~r&HwgU>QbEd*U=dQwSISQQYP%ekLEM zD3MVpA!`gKNV?Hl*p| zh%j$RyTa9WdP)yEsRu2EEAtQwyhT~#WNXz-OWpt`T%~Yi24J}vm{iINg^MeRVm{Mb zl$n(%90#{;$jXds0d?HBOz32Lj+4DTi))4NzvvAADC`9NhbLaQa>)A;vN}VwE_L&| zmAiSOBDjYI?$seI?&c+}0^l%QL)WSA=9zAUYgaP>D7(_5JX&~r>9J}fz<5@;L%YI% z1au+)p6HRE6`o(0@0dRFtqn}vsXVw7!$&* zqF^f%2vcBn3;6=s>XJbCcQyQ9s`an|C*|!L5*o!{0b`66P`$zcgg2J}Q9}_B;@3k7 z(p7Ik3Q=&85rAmJXYzIrX(*T7d)?4QFp5e9vh6a!J1m09%Mp*2Lx}i;1ZZ&ak^yvq z0WblUaBmhDH~<&m34Fm&5CS4VEEo-Va2Ycbh(Rux2&REqU>;ZumV?z`11JXD!EUf0 z90n&qIXDL{!mYtKz#Y&48o?{j1X@8G+=NO&ln@O>7coT4kUEx zBn1&7Imkq0Ix-I_KvpB0knPAmH0{H{^gc49X%0T<0=BPF5haWyV>N9Gaf~taV=YMp9}nuZ!jEkrF-ZNAzLwJNpe>J)WzbzgP9`V95W>c6Q! z)*xt@Xn1SzG^T45Yn;_+WRMvaj6g;jV;*A{qngpAsjg|O8Ks%0xkmG(W`h<%%Uml^ zD?@9M)_$#(7`ht@43`<6GJMI@WO^|(m@AnT%qAm!qX45EqfJKDMs3Cx z#*xPP#(RwKnb1reO_EKPnVd0cGBq>}Hl1i%YFclmVCHC+YPQ0x((Hq|g?Y63Z1cnB z&n=iRI>E2%(g7DygqPbDO!ox$jqVK|MjnYCMIMhlO+5LYC7#c`26&};?euy(ggrz&`$qb%_Py_C?3dzK>eu9N=Rd*!bO0$}Siq8iy1@Q{yuj^&O+y`q zP8wP@Af(8bOgN_BG!9#~Kj7c1GAc2$+ov$aNL}6&&K-fR^4ou*&BW#{v!CLdXCMURdc@1<lc$33m4y9;<02~fm*@%g2zjPmzFJKE}OfodHI;-RfV>N8&=R(WOuUZPhrujI>C;ns$2VcROUJ8a*+Lx0DjQnWOu^u^BjomY4H>^icW zwR_VZtv&Phg1tF=U+zoTcXR)+{bvq19@u@*?BLo%8i(eVA!XyrnhvKPZa5Nqq~_?* zqi2q}96NN}>iE_ZMkm&s)I7Q9SK6;Ler-QB{#489tkbW{Q_3Ho8FS{&Z!y1JuNYBL zeRkN{^XL4|{Z{E!dFs5|`4d&nRYxy4UO0Tw{$klByGw^I+g(0XZC_n>#o@}4t4>#s z)wtIDTI*3;e$D6Fx$A+~FWwk_qvmGh&0BTxbq%-px1Qh5xc#nvY<=6Esdq_t=iXDj zS9o9le$j&g5B4$AzYO?t?CY?vciS`Jj_S9-NVe1r_?~bs0MFQ{5>SGC z>k&RVfI)WBMShOthwf;1AasQun)ta6v`g@#MEjYplP>URi2S5W1=s{5~rDJYRONLAn@>v8bp4; ze-izD&@16OU6Z&^zE<)Cf)GE!vKJ?Z?^?29U;ftG!*#Eo--G_uY2`Rf|=YnWW*8E-Xoj%E4_ zLWO_hP2B|ScbP6cEd+Jj&Wf}Wl&p^rf4i~vttCpBUQ|(HS)Mv}QH|bI%4yf@zp`6K ztvDr9z>gGxs>bRhziQ(@q5{{ZRx%o$S_}uYgOdHX@*X&*g-p2i$4GCr-7cT8g2Fim zZ^h9bV@vEyJWMBqSJ6+(4Mxcxpv`?u-OTIlK)O7te8%%HvvYq5*!cW{sb5t6@H63) z??0KaO?+bFy$f2K0+TYhZx{M1FF2IH_inL1n{JbjT&sv2dMdkSrRu_PYN%>0=}oEn zt3$fek0_ttx$k`ROYz-9bBzI$ zS7HB@^QL)US|<;^5w$)0)h*T2J9&F=ydIYHs4DKHsdV&EgL|=|3#0D%u6(-wW5DAn zHy>}MWxpZq9vWG)pT(ae993{OwxM9O{hhkiJ00Vmj3^Z&E{}$aO&15YgArx}$0!-y z+V8@er~Br0h0#mXgNKrdzLVps*VPIXwHo&s-gzLeW0|{M%TMIy&#GKs8*ruNdO|zU zOWAf|nC=BO(eR1dlDgBQ#9nU7wv`*a>b$PMS~%MAgqq11=uAP^P^(GpU-k19h2B^KZ;Zjcr19t5RDJ&Q5Ugyx+Kd z*~(knN4#kswEOW6)rijpbN15FNx|3jFt3o;jR99SO9~A|@>Y)^un~P6H@;5$^t%bP zZO7i*B?Y~ovp&asK|NEqY2~n4YJ15RG&B8$2^WH|bsoVU2wl=WsikmAWi8 zl=E($%9VhYyf>Qt9vOnIij8Q*xYnn0ow8oOxS}t9yxvi5_=t5?e)(tTbIts9QI9!J{YHDeJjGixi&ZJF#`v7JXjPZ>h=2tk=)$SNXCY8Bd(Bi~DNN zn721cag0kzXKpOGxhHjq73X4kzOB0V=_J#O=U0jks#YA@p&E7Y<|o>EY@WuNKOV%} zT)XsT*VjoS^nW?BWU)t*#M6mBiu9I3vmzG82@W~#MMjGpUd z1-I0b@v0YUY0PbN+h`GGf2t>14YaWjTHSbM@cw58lh1BQ&5ST}yZ+MdzTVjY6Ep8T z=T&+8@7ouASf*#cHSBVN%cFgZBhPsUEHB9ow`C^Ihu?N;gj5ZR(Z&Aj->b z?uU&vQPG6kcd*NK@gvi$cOEn39oSsoa*sFI$bW4lt#ONwF!_a6PGwzyDolIRTVVzV1X3&vFpG&bi|?`n{ diff --git a/AvocadoEdition/skin/board/qna/list.skin.php b/AvocadoEdition/skin/board/qna/list.skin.php new file mode 100644 index 0000000..5072718 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/list.skin.php @@ -0,0 +1,247 @@ +', 0); + +if($is_member) { + $comment_token = uniqid(time()); + set_session('ss_comment_token', $comment_token); +} + +?> + +
    + + + +
    + +
    +
    + + + + + + +
    + +
    + + +
    +
      + +
    • +
      + + + + + + + + +
      +

      + + NOTICE + + NO. + + + [ ] + + + + D + + D + + + R + + + + + +

      +
      + +
      + + +
      + + + [SECRET]
      + + + + +
      +
      +
      + +
    • + \n"; + ?> + 질문 내역이 없습니다."; } ?> +
    + + + +
    + "; } ?> + >", $write_pages); + $write_pages = preg_replace("/([0-9]*)<\/span>/", "$1", $write_pages); + $write_pages = preg_replace("/([0-9]*)<\/b>/", "$1", $write_pages); + ?> + + "; } ?> +
    + +
    +
    + + + + + + + + diff --git a/AvocadoEdition/skin/board/qna/password.php b/AvocadoEdition/skin/board/qna/password.php new file mode 100644 index 0000000..52a8156 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/password.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/style.css b/AvocadoEdition/skin/board/qna/style.css new file mode 100644 index 0000000..023850f --- /dev/null +++ b/AvocadoEdition/skin/board/qna/style.css @@ -0,0 +1,83 @@ +@charset "utf-8"; + + +/** Notice Box **/ +.board-notice { width: 264px; padding: 10px; margin: 0 auto; text-align: center; box-sizing: border-box; } + + + +#page_board_content { padding: 0 10px; } + + + +.qna-box { overflow: hidden; } + +.ui-option { clear: both; padding-bottom: 10px; font-weight: 800; letter-spacing: 1px; } +.ui-write-box { margin: 0 auto; width: 100%; overflow: hidden; } +.ui-write-box textarea { width: 100%; height: 100px; padding: 10px; box-sizing: border-box; } +.ui-control { padding: 10px 0 0; overflow: hidden; text-align: right; } + +.ui-write-area.top { margin-bottom: 20px; } + +.ui-qna-list { position: relative; clear: both; } +.ui-qna-list li { position: relative; padding: 15px 0; } +.ui-qna-list li p { clear: both; margin: 0 0 10px; line-height: 1.5em; overflow: hidden; } +.ui-qna-list li p i { position: relative; font-style: normal; padding-right: 10px; margin-right: 5px; } +.ui-qna-list li p em { font-style: normal; margin-right: 20px; } +.ui-qna-list li p strong a { display: inline-block; font-size:9px; font-family: 'Dotum'; padding: 2px 5px; font-weight: normal; } +.ui-qna-list li p span.date { float: right; } +.ui-qna-list li .qna-content { padding: 15px; line-height: 1.8em; } +.ui-qna-list li .qna-comment-content { padding: 15px; line-height: 1.8em; } + +.ui-qna-list li ul { margin-left: 80px; padding-top: 15px; } + +@media all and (max-width: 460px) { + .ui-qna-list li ul { margin-left: 0px; } +} + +.ui-qna-list li ul li { padding: 0; } +.ui-qna-list li ul li p { padding-top: 10px; } +.ui-qna-list li ul li strong { float: right; } + +.ui-qna-list .ui-qna-list-password label { padding-right: 10px; } +.ui-qna-list .ui-qna-list-password label.blur { text-shadow: none; } +.ui-qna-list .ui-qna-list-password input { position: relative; z-index: 1; } +.ui-qna-list .ui-qna-list-password button { + height: 28px; line-height: 28px; padding: 0 25px; + font-family: 'Dotum'; margin-left: -5px; border-left-width: 0; + +} + +@media all and (max-width: 370px) { + .ui-qna-list .ui-qna-list-password { position: relative; padding-right: 90px; } + .ui-qna-list .ui-qna-list-password .ui-submit { position: absolute; top: 0; right: 0; width: 90px; } + .ui-qna-list .ui-qna-list-password input { width: 100%; } +} + +.ui-qna-list li div.ui-write-area { padding: 0; margin-left: 80px; background: transparent; background: none; margin-bottom: 10px; border: none; } +.ui-qna-list li div.ui-write-area button { white-space:nowrap; height: 28px; line-height: 28px; padding: 0 25px; margin-top: 10px; } +.ui-qna-list li div.ui-write-area textarea { + width: 100%; + height: 100px; + padding: 10px; + box-sizing: border-box; + border: none; + word-break: break-all; +} +.ui-qna-list .no-data { text-align: center; line-height: 100px; padding-bottom: 50px; } + +.search-box { clear: both; float: right; margin-bottom: 10px; } + + +@media all and (max-width: 535px) { + .ui-control button { display: block; clear: both; width: 100%; margin-top: 10px; } +} +@media all and (max-width: 435px) { + .ui-control input[type="text"], + .ui-control input[type="password"] { display: block; clear: both; width: 100%; margin-top: 10px; } + .ui-qna-list { padding: 10px 0; } +} + +@media all and (max-width: 380px) { + .ui-qna-list .ui-qna-list-password label { display: none; } +} \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/view.skin.php b/AvocadoEdition/skin/board/qna/view.skin.php new file mode 100644 index 0000000..85a70a1 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/view.skin.php @@ -0,0 +1,7 @@ + diff --git a/AvocadoEdition/skin/board/qna/view_comment.php b/AvocadoEdition/skin/board/qna/view_comment.php new file mode 100644 index 0000000..5f810ad --- /dev/null +++ b/AvocadoEdition/skin/board/qna/view_comment.php @@ -0,0 +1,119 @@ += $board['bo_comment_level']) + $is_comment_write = true; + +// 코멘트 출력 +$sql = " select * from {$write_table} where wr_parent = '{$wr_id}' and wr_is_comment = 1 order by wr_comment desc, wr_comment_reply "; +$result = sql_query($sql); +for ($i=0; $c_row=sql_fetch_array($result); $i++) +{ + $list[$i] = $c_row; + + //$list[$i]['name'] = get_sideview($c_row['mb_id'], cut_str($c_row['wr_name'], 20, ''), $c_row['wr_email'], $c_row['wr_homepage']); + + $tmp_name = get_text(cut_str($c_row['wr_name'], $config['cf_cut_name'])); // 설정된 자리수 만큼만 이름 출력 + if ($board['bo_use_sideview']) + $list[$i]['name'] = get_sideview($c_row['mb_id'], $tmp_name, $c_row['wr_email'], $c_row['wr_homepage']); + else + $list[$i]['name'] = ''.$tmp_name.''; + + + + // 공백없이 연속 입력한 문자 자르기 (way 보드 참고. way.co.kr) + //$list[$i]['content'] = eregi_replace("[^ \n<>]{130}", "\\0\n", $c_row['wr_content']); + + $list[$i]['content'] = $list[$i]['content1']= '비밀글 입니다.'; + if (!strstr($c_row['wr_option'], 'secret') || + $is_admin || + ($write['mb_id']==$member['mb_id'] && $member['mb_id']) || + ($c_row['mb_id']==$member['mb_id'] && $member['mb_id'])) { + $list[$i]['content1'] = $c_row['wr_content']; + $list[$i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $list[$i]['content'] = search_font($stx, $list[$i]['content']); + } else { + $ss_name = 'ss_secret_comment_'.$bo_table.'_'.$list[$i]['wr_id']; + + if(!get_session($ss_name)) + $list[$i]['content'] = '댓글내용 확인'; + else { + $list[$i]['content'] = conv_content($c_row['wr_content'], 0, 'wr_content'); + $list[$i]['content'] = search_font($stx, $list[$i]['content']); + } + } + + $list[$i]['datetime'] = substr($c_row['wr_datetime'],2,14); + + // 관리자가 아니라면 중간 IP 주소를 감춘후 보여줍니다. + $list[$i]['ip'] = $c_row['wr_ip']; + if (!$is_admin) + $list[$i]['ip'] = preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", G5_IP_DISPLAY, $c_row['wr_ip']); + + $list[$i]['is_reply'] = false; + $list[$i]['is_edit'] = false; + $list[$i]['is_del'] = false; + if ($is_comment_write || $is_admin) + { + $token = ''; + + if ($member['mb_id']) + { + if ($c_row['mb_id'] == $member['mb_id'] || $is_admin) + { + set_session('ss_delete_comment_'.$c_row['wr_id'].'_token', $token = uniqid(time())); + $list[$i]['del_link'] = './delete_comment.php?bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&token='.$token.'&page='.$page.$qstr; + $list[$i]['is_edit'] = true; + $list[$i]['is_del'] = true; + } + } + else + { + if (!$c_row['mb_id']) { + $list[$i]['del_link'] = './password.php?w=x&bo_table='.$bo_table.'&comment_id='.$c_row['wr_id'].'&page='.$page.$qstr; + $list[$i]['is_del'] = true; + } + } + + if (strlen($c_row['wr_comment_reply']) < 5) + $list[$i]['is_reply'] = true; + } + + // 05.05.22 + // 답변있는 코멘트는 수정, 삭제 불가 + if ($i > 0 && !$is_admin) + { + if ($c_row['wr_comment_reply']) + { + $tmp_comment_reply = substr($c_row['wr_comment_reply'], 0, strlen($c_row['wr_comment_reply']) - 1); + if ($tmp_comment_reply == $list[$i-1]['wr_comment_reply']) + { + $list[$i-1]['is_edit'] = false; + $list[$i-1]['is_del'] = false; + } + } + } +} + +// 코멘트수 제한 설정값 +if ($is_admin) +{ + $comment_min = $comment_max = 0; +} +else +{ + $comment_min = (int)$board['bo_comment_min']; + $comment_max = (int)$board['bo_comment_max']; +} + +include($board_skin_path.'/view_comment.skin.php'); + +?> \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/view_comment.skin.php b/AvocadoEdition/skin/board/qna/view_comment.skin.php new file mode 100644 index 0000000..271295a --- /dev/null +++ b/AvocadoEdition/skin/board/qna/view_comment.skin.php @@ -0,0 +1,84 @@ + + + + + + +
      + + + +
    • + +
      + + * "; + $str = $list[$i]['content']; + if (strstr($list[$i]['wr_option'], "secret")) + $str = "$str"; + + $str = preg_replace("/\[\\]/i", "", $str); + $str = preg_replace("/\[\\]/i", "", $str); + $str = preg_replace("/\[\]*\>[^\s]*\<\/a\>\]/i", "", $str); + echo $str; + ?> +
      +

      +   + + D "; } ?> + +

      +
    • + +
    + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/view_skin_js.php b/AvocadoEdition/skin/board/qna/view_skin_js.php new file mode 100644 index 0000000..b3689c5 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/view_skin_js.php @@ -0,0 +1,11 @@ + diff --git a/AvocadoEdition/skin/board/qna/write.php b/AvocadoEdition/skin/board/qna/write.php new file mode 100644 index 0000000..72d4612 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/write.php @@ -0,0 +1,420 @@ + 0) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_write_point'] < 0 && !$is_admin) { + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 글쓰기('.number_format($board['bo_write_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 글쓰기 해 주십시오.'); + } + } + + $title_msg = '글쓰기'; +} else if ($w == 'u') { + // 김선용 1.00 : 글쓰기 권한과 수정은 별도로 처리되어야 함 + //if ($member['mb_level'] < $board['bo_write_level']) { + if($member['mb_id'] && $write['mb_id'] == $member['mb_id']) { + ; + } else if ($member['mb_level'] < $board['bo_write_level']) { + if ($member['mb_id']) { + alert('글을 수정할 권한이 없습니다.'); + } else { + alert('글을 수정할 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + } + + $len = strlen($write['wr_reply']); + if ($len < 0) $len = 0; + $reply = substr($write['wr_reply'], 0, $len); + + // 원글만 구한다. + $sql = " select count(*) as cnt from {$write_table} + where wr_reply like '{$reply}%' + and wr_id <> '{$write['wr_id']}' + and wr_num = '{$write['wr_num']}' + and wr_is_comment = 0 "; + $row = sql_fetch($sql); + if ($row['cnt'] && !$is_admin) + alert('이 글과 관련된 답변글이 존재하므로 수정 할 수 없습니다.\\n\\n답변글이 있는 원글은 수정할 수 없습니다.'); + + // 코멘트 달린 원글의 수정 여부 + $sql = " select count(*) as cnt from {$write_table} + where wr_parent = '{$wr_id}' + and mb_id <> '{$member['mb_id']}' + and wr_is_comment = 1 "; + $row = sql_fetch($sql); + if ($board['bo_count_modify'] && $row['cnt'] >= $board['bo_count_modify'] && !$is_admin) + alert('이 글과 관련된 댓글이 존재하므로 수정 할 수 없습니다.\\n\\n댓글이 '.$board['bo_count_modify'].'건 이상 달린 원글은 수정할 수 없습니다.'); + + $title_msg = '글수정'; +} else if ($w == 'r') { + if ($member['mb_level'] < $board['bo_reply_level']) { + if ($member['mb_id']) + alert('글을 답변할 권한이 없습니다.'); + else + alert('답변글을 작성할 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', './login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + $tmp_point = isset($member['mb_point']) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_write_point'] < 0 && !$is_admin) + alert('보유하신 포인트('.number_format($member['mb_point']).')가 없거나 모자라서 글답변('.number_format($board['bo_comment_point']).')가 불가합니다.\\n\\n포인트를 적립하신 후 다시 글답변 해 주십시오.'); + + //if (preg_match("/[^0-9]{0,1}{$wr_id}[\r]{0,1}/",$board['bo_notice'])) + if (in_array((int)$wr_id, $notice_array)) + alert('공지에는 답변 할 수 없습니다.'); + + //---------- + // 4.06.13 : 비밀글을 타인이 열람할 수 있는 오류 수정 (헐랭이, 플록님께서 알려주셨습니다.) + // 코멘트에는 원글의 답변이 불가하므로 + if ($write['wr_is_comment']) + alert('정상적인 접근이 아닙니다.'); + + // 비밀글인지를 검사 + if (strstr($write['wr_option'], 'secret')) { + if ($write['mb_id']) { + // 회원의 경우는 해당 글쓴 회원 및 관리자 + if (!($write['mb_id'] == $member['mb_id'] || $is_admin)) + alert('비밀글에는 자신 또는 관리자만 답변이 가능합니다.'); + } else { + // 비회원의 경우는 비밀글에 답변이 불가함 + if (!$is_admin) + alert('비회원의 비밀글에는 답변이 불가합니다.'); + } + } + //---------- + + // 게시글 배열 참조 + $reply_array = &$write; + + // 최대 답변은 테이블에 잡아놓은 wr_reply 사이즈만큼만 가능합니다. + if (strlen($reply_array['wr_reply']) == 10) + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 10단계 까지만 가능합니다.'); + + $reply_len = strlen($reply_array['wr_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = 'A'; + $end_reply_char = 'Z'; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } else { + $begin_reply_char = 'Z'; + $end_reply_char = 'A'; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_reply, {$reply_len}, 1)) as reply from {$write_table} where wr_num = '{$reply_array['wr_num']}' and SUBSTRING(wr_reply, {$reply_len}, 1) <> '' "; + } + if ($reply_array['wr_reply']) $sql .= " and wr_reply like '{$reply_array['wr_reply']}%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) + $reply_char = $begin_reply_char; + else if ($row['reply'] == $end_reply_char) // A~Z은 26 입니다. + alert('더 이상 답변하실 수 없습니다.\\n\\n답변은 26개 까지만 가능합니다.'); + else + $reply_char = chr(ord($row['reply']) + $reply_number); + + $reply = $reply_array['wr_reply'] . $reply_char; + + $title_msg = '글답변'; + + $write['wr_subject'] = 'Re: '.$write['wr_subject']; +} + +// 그룹접근 가능 +if (!empty($group['gr_use_access'])) { + if ($is_guest) { + alert("접근 권한이 없습니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.", 'login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + if ($is_admin == 'super' || $group['gr_admin'] == $member['mb_id'] || $board['bo_admin'] == $member['mb_id']) { + ; // 통과 + } else { + // 그룹접근 + $sql = " select gr_id from {$g5['group_member_table']} where gr_id = '{$board['gr_id']}' and mb_id = '{$member['mb_id']}' "; + $row = sql_fetch($sql); + if (!$row['gr_id']) + alert('접근 권한이 없으므로 글쓰기가 불가합니다.\\n\\n궁금하신 사항은 관리자에게 문의 바랍니다.'); + } +} + +// 본인확인을 사용한다면 +if ($config['cf_cert_use'] && !$is_admin) { + // 인증된 회원만 가능 + if ($board['bo_use_cert'] != '' && $is_guest) { + alert('이 게시판은 본인확인 하신 회원님만 글쓰기가 가능합니다.\\n\\n회원이시라면 로그인 후 이용해 보십시오.', 'login.php?'.$qstr.'&url='.urlencode($_SERVER['SCRIPT_NAME'].'?bo_table='.$bo_table)); + } + + if ($board['bo_use_cert'] == 'cert' && !$member['mb_certify']) { + alert('이 게시판은 본인확인 하신 회원님만 글쓰기가 가능합니다.\\n\\n회원정보 수정에서 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'adult' && !$member['mb_adult']) { + alert('이 게시판은 본인확인으로 성인인증 된 회원님만 글쓰기가 가능합니다.\\n\\n성인인데 글쓰기가 안된다면 회원정보 수정에서 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-cert' && $member['mb_certify'] != 'hp') { + alert('이 게시판은 휴대폰 본인확인 하신 회원님만 글읽기가 가능합니다.\\n\\n회원정보 수정에서 휴대폰 본인확인을 해주시기 바랍니다.', G5_URL); + } + + if ($board['bo_use_cert'] == 'hp-adult' && (!$member['mb_adult'] || $member['mb_certify'] != 'hp')) { + alert('이 게시판은 휴대폰 본인확인으로 성인인증 된 회원님만 글읽기가 가능합니다.\\n\\n현재 성인인데 글읽기가 안된다면 회원정보 수정에서 휴대폰 본인확인을 다시 해주시기 바랍니다.', G5_URL); + } +} + +// 글자수 제한 설정값 +if ($is_admin || $board['bo_use_dhtml_editor']) +{ + $write_min = $write_max = 0; +} +else +{ + $write_min = (int)$board['bo_write_min']; + $write_max = (int)$board['bo_write_max']; +} + +$g5['title'] = ((G5_IS_MOBILE && $board['bo_mobile_subject']) ? $board['bo_mobile_subject'] : $board['bo_subject']).' '.$title_msg; + +$is_notice = false; +$notice_checked = ''; +if ($is_admin && $w != 'r') { + $is_notice = true; + + if ($w == 'u') { + // 답변 수정시 공지 체크 없음 + if ($write['wr_reply']) { + $is_notice = false; + } else { + if (in_array((int)$wr_id, $notice_array)) { + $notice_checked = 'checked'; + } + } + } +} + +$is_html = false; +if ($member['mb_level'] >= $board['bo_html_level']) + $is_html = true; + +$is_secret = $board['bo_use_secret']; + +$is_mail = false; +if ($config['cf_email_use'] && $board['bo_use_email']) + $is_mail = true; + +$recv_email_checked = ''; +if ($w == '' || strstr($write['wr_option'], 'mail')) + $recv_email_checked = 'checked'; + +$is_name = false; +$is_password = false; +$is_email = false; +$is_homepage = false; +if ($is_guest || ($is_admin && $w == 'u' && $member['mb_id'] != $write['mb_id'])) { + $is_name = true; + $is_password = true; + $is_email = true; + $is_homepage = true; +} + +$is_category = false; +$category_option = ''; +if ($board['bo_use_category']) { + $ca_name = ""; + if (isset($write['ca_name'])) + $ca_name = $write['ca_name']; + $category_option = get_category_option($bo_table, $ca_name); + $is_category = true; +} + +$is_link = false; +if ($member['mb_level'] >= $board['bo_link_level']) { + $is_link = true; +} + +$is_file = false; +if ($member['mb_level'] >= $board['bo_upload_level']) { + $is_file = true; +} + +$is_file_content = false; +if ($board['bo_use_file_content']) { + $is_file_content = true; +} + +$file_count = (int)$board['bo_upload_count']; + +$name = ""; +$email = ""; +$homepage = ""; +if ($w == "" || $w == "r") { + if ($is_member) { + if (isset($write['wr_name'])) { + $name = get_text(cut_str(stripslashes($write['wr_name']),20)); + } + $email = get_email_address($member['mb_email']); + $homepage = get_text(stripslashes($member['mb_homepage'])); + } +} + +$html_checked = ""; +$html_value = ""; +$secret_checked = ""; + +if ($w == '') { + $password_required = 'required'; +} else if ($w == 'u') { + $password_required = ''; + + if (!$is_admin) { + if (!($is_member && $member['mb_id'] == $write['mb_id'])) { + if (!check_password($wr_password, $write['wr_password'])) { + alert('비밀번호가 틀립니다.'); + } + } + } + + $name = get_text(cut_str(stripslashes($write['wr_name']),20)); + $email = get_email_address($write['wr_email']); + $homepage = get_text(stripslashes($write['wr_homepage'])); + + for ($i=1; $i<=G5_LINK_COUNT; $i++) { + $write['wr_link'.$i] = get_text($write['wr_link'.$i]); + $link[$i] = $write['wr_link'.$i]; + } + + if (strstr($write['wr_option'], 'html1')) { + $html_checked = 'checked'; + $html_value = 'html1'; + } else if (strstr($write['wr_option'], 'html2')) { + $html_checked = 'checked'; + $html_value = 'html2'; + } + + if (strstr($write['wr_option'], 'secret')) { + $secret_checked = 'checked'; + } + + $file = get_file($bo_table, $wr_id); + if($file_count < $file['count']) + $file_count = $file['count']; +} else if ($w == 'r') { + if (strstr($write['wr_option'], 'secret')) { + $is_secret = true; + $secret_checked = 'checked'; + } + + $password_required = "required"; + + for ($i=1; $i<=G5_LINK_COUNT; $i++) { + $write['wr_link'.$i] = get_text($write['wr_link'.$i]); + } +} + +set_session('ss_bo_table', $_REQUEST['bo_table']); +set_session('ss_wr_id', $_REQUEST['wr_id']); + +$subject = ""; +if (isset($write['wr_subject'])) { + $subject = str_replace("\"", """, get_text(cut_str($write['wr_subject'], 255), 0)); +} + +$content = ''; +if ($w == '') { + $content = $board['bo_insert_content']; +} else if ($w == 'r') { + if (!strstr($write['wr_option'], 'html')) { + $content = "\n\n\n > " + ."\n > " + ."\n > ".str_replace("\n", "\n> ", get_text($write['wr_content'], 0)) + ."\n > " + ."\n > "; + + } +} else { + $content = get_text($write['wr_content'], 0); +} + +$upload_max_filesize = number_format($board['bo_upload_size']) . ' 바이트'; + +$width = $board['bo_table_width']; +if ($width <= 100) + $width .= '%'; +else + $width .= 'px'; + +$captcha_html = ''; +$captcha_js = ''; +if ($is_guest) { + $captcha_html = captcha_html(); + $captcha_js = chk_captcha_js(); +} + +$is_dhtml_editor = false; +$is_dhtml_editor_use = false; +$editor_content_js = ''; +if(!is_mobile() || defined('G5_IS_MOBILE_DHTML_USE') && G5_IS_MOBILE_DHTML_USE) + $is_dhtml_editor_use = true; + +// 모바일에서는 G5_IS_MOBILE_DHTML_USE 설정에 따라 DHTML 에디터 적용 +if ($config['cf_editor'] && $is_dhtml_editor_use && $board['bo_use_dhtml_editor'] && $member['mb_level'] >= $board['bo_html_level']) { + $is_dhtml_editor = true; + + if(is_file(G5_EDITOR_PATH.'/'.$config['cf_editor'].'/autosave.editor.js')) + $editor_content_js = ''.PHP_EOL; +} +$editor_html = editor_html('wr_content', $content, $is_dhtml_editor); +$editor_js = ''; +$editor_js .= get_editor_js('wr_content', $is_dhtml_editor); +$editor_js .= chk_editor_js('wr_content', $is_dhtml_editor); + +// 임시 저장된 글 수 +$autosave_count = autosave_count($member['mb_id']); + +$action_url = https_url(G5_BBS_DIR)."/write_update.php"; + +echo ''; +include_once ($board_skin_path.'/write.skin.php'); + +?> \ No newline at end of file diff --git a/AvocadoEdition/skin/board/qna/write.skin.php b/AvocadoEdition/skin/board/qna/write.skin.php new file mode 100644 index 0000000..6ed2486 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/write.skin.php @@ -0,0 +1,86 @@ +'."\n".''; + } + + if ($is_html) { + if ($is_dhtml_editor) { + $option_hidden .= ''; + } else { + //$option .= "\n".''."\n".''; + } + } + + if ($is_secret) { + if ($is_admin || $is_secret==1) { + $option .= "\n".''."\n".''; + } else { + $option_hidden .= ''; + } + } + + if ($is_mail) { + $option .= "\n".''."\n".''; + } +} + +echo $option_hidden; + +?> +
    + + + + + + + + + + + + + + +
    + +
    + +
    + +    + + + + /> + + +
    +
    + + diff --git a/AvocadoEdition/skin/board/qna/write_comment_update.php b/AvocadoEdition/skin/board/qna/write_comment_update.php new file mode 100644 index 0000000..c31673c --- /dev/null +++ b/AvocadoEdition/skin/board/qna/write_comment_update.php @@ -0,0 +1,342 @@ + 50) { + alert("내용에 올바르지 않은 코드가 다수 포함되어 있습니다."); + exit; +} + +@include_once("$board_skin_path/write_comment_update.head.skin.php"); + +$g5['title'] = $wr_subject . "코멘트입력"; + +$w = $_POST["w"]; +$wr_name = strip_tags($_POST["wr_name"]); +$wr_email = strip_tags($_POST["wr_email"]); + +// 비회원의 경우 이름이 누락되는 경우가 있음 +if (!$is_member) +{ + if (!trim($wr_name)) + alert("이름은 필히 입력하셔야 합니다."); +} + +if ($w == "c" || $w == "cu") +{ + if ($member['mb_level'] < $board['bo_comment_level']) + alert("코멘트를 쓸 권한이 없습니다."); +} +else + alert("w 값이 제대로 넘어오지 않았습니다."); + +// 세션의 시간 검사 +// 4.00.15 - 코멘트 수정시 연속 게시물 등록 메시지로 인한 오류 수정 +if ($w == "c" && $_SESSION["ss_datetime"] >= ($g5['server_time'] - $config['cf_delay_sec']) && !$is_admin) + alert("너무 빠른 시간내에 게시물을 연속해서 올릴 수 없습니다."); + +set_session("ss_datetime", $g5['server_time']); + +// 동일내용 연속 등록 불가 +$sql = " select MD5(CONCAT(wr_ip, wr_subject, wr_content)) as prev_md5 from $write_table "; +if ($w == "cu") + $sql .= " where wr_id <> '$comment_id' "; +$sql .= " order by wr_id desc limit 1 "; +$row = sql_fetch($sql); +$curr_md5 = md5($_SERVER['REMOTE_ADDR'].$wr_subject.$wr_content); +// 코멘트 수정의 경우에는 동일한 내용을 등록할 수 없는 오류 수정 +//if ($row[prev_md5] == $curr_md5 && !$is_admin) +if ($row['prev_md5'] == $curr_md5 && $w != 'cu' && !$is_admin) + alert("동일한 내용을 연속해서 등록할 수 없습니다."); + +$wr = get_write($write_table, $wr_id); +if (!$wr['wr_id']) + alert("글이 존재하지 않습니다.\\n\\n글이 삭제되었거나 이동하였을 수 있습니다."); + +// 자동등록방지 검사 +//include_once ("./norobot_check.inc.php"); + +if (!$is_member) { + if ($w=='' || $w=='c') { + $key = get_session("captcha_keystring"); + session_unregister("captcha_keystring"); + if (!($key && $key == $_POST['wr_key'])) { + alert("정상적인 접근이 아닌것 같습니다."); + } + } +} + + +// "인터넷옵션 > 보안 > 사용자정의수준 > 스크립팅 > Action 스크립팅 > 사용 안 함" 일 경우의 오류 처리 +// 이 옵션을 사용 안 함으로 설정할 경우 어떤 스크립트도 실행 되지 않습니다. +//if (!trim($_POST["wr_content"])) die ("내용을 입력하여 주십시오."); + +if ($member['mb_id']) +{ + $mb_id = $member['mb_id']; + // 4.00.13 - 실명 사용일때 코멘트에 별명으로 입력되던 오류를 수정 + $wr_name = $board['bo_use_name'] ? $member['mb_name'] : $member['mb_nick']; + $wr_password = $member['mb_password']; + $wr_email = $member['mb_email']; + $wr_homepage = $member['mb_homepage']; +} +else +{ + $mb_id = ""; + $wr_password = sql_password($wr_password); +} + +if ($w == "c") // 코멘트 입력 +{ + /* + if ($member['mb_point'] + $board['bo_comment_point'] < 0 && !$is_admin) + alert("보유하신 포인트(".number_format($member['mb_point']).")가 없거나 모자라서 코멘트쓰기(".number_format($board['bo_comment_point']).")가 불가합니다.\\n\\n포인트를 적립하신 후 다시 코멘트를 써 주십시오."); + */ + // 코멘트쓰기 포인트설정시 회원의 포인트가 음수인 경우 코멘트를 쓰지 못하던 버그를 수정 (곱슬최씨님) + $tmp_point = ($member['mb_point'] > 0) ? $member['mb_point'] : 0; + if ($tmp_point + $board['bo_comment_point'] < 0 && !$is_admin) + alert("보유하신 포인트(".number_format($member['mb_point']).")가 없거나 모자라서 코멘트쓰기(".number_format($board['bo_comment_point']).")가 불가합니다.\\n\\n포인트를 적립하신 후 다시 코멘트를 써 주십시오."); + + // 코멘트 답변 + if ($comment_id) + { + $sql = " select wr_id, wr_comment, wr_comment_reply from $write_table + where wr_id = '$comment_id' "; + $reply_array = sql_fetch($sql); + if (!$reply_array['wr_id']) + alert("답변할 코멘트가 없습니다.\\n\\n답변하는 동안 코멘트가 삭제되었을 수 있습니다."); + + $tmp_comment = $reply_array['wr_comment']; + + if (strlen($reply_array['wr_comment_reply']) == 5) + alert("더 이상 답변하실 수 없습니다.\\n\\n답변은 5단계 까지만 가능합니다."); + + $reply_len = strlen($reply_array['wr_comment_reply']) + 1; + if ($board['bo_reply_order']) { + $begin_reply_char = "A"; + $end_reply_char = "Z"; + $reply_number = +1; + $sql = " select MAX(SUBSTRING(wr_comment_reply, $reply_len, 1)) as reply + from $write_table + where wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and SUBSTRING(wr_comment_reply, $reply_len, 1) <> '' "; + } + else + { + $begin_reply_char = "Z"; + $end_reply_char = "A"; + $reply_number = -1; + $sql = " select MIN(SUBSTRING(wr_comment_reply, $reply_len, 1)) as reply + from $write_table + where wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and SUBSTRING(wr_comment_reply, $reply_len, 1) <> '' "; + } + if ($reply_array['wr_comment_reply']) + $sql .= " and wr_comment_reply like '$reply_array['wr_comment_reply']%' "; + $row = sql_fetch($sql); + + if (!$row['reply']) + $reply_char = $begin_reply_char; + else if ($row['reply'] == $end_reply_char) // A~Z은 26 입니다. + alert("더 이상 답변하실 수 없습니다.\\n\\n답변은 26개 까지만 가능합니다."); + else + $reply_char = chr(ord($row['reply']) + $reply_number); + + $tmp_comment_reply = $reply_array['wr_comment_reply'] . $reply_char; + } + else + { + $sql = " select max(wr_comment) as max_comment from $write_table + where wr_parent = '$wr_id' and wr_is_comment = 1 "; + $row = sql_fetch($sql); + //$row['max_comment'] -= 1; + $row['max_comment'] += 1; + $tmp_comment = $row['max_comment']; + $tmp_comment_reply = ""; + } + + $sql = " insert into $write_table + set ca_name = '$wr['ca_name']', + wr_option = '$wr_secret', + wr_num = '$wr['wr_num']', + wr_reply = '', + wr_parent = '$wr_id', + wr_is_comment = '1', + wr_comment = '$tmp_comment', + wr_comment_reply = '$tmp_comment_reply', + wr_subject = '$wr_subject', + wr_content = '$wr_content', + mb_id = '$mb_id', + wr_password = '$wr_password', + wr_name = '$wr_name', + wr_email = '$wr_email', + wr_homepage = '$wr_homepage', + wr_datetime = '$g5['time_ymdhis']', + wr_last = '', + wr_ip = '$_SERVER[REMOTE_ADDR]', + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10' "; + sql_query($sql); + + $comment_id = mysql_insert_id(); + + // 원글에 코멘트수 증가 & 마지막 시간 반영 + sql_query(" update $write_table set wr_comment = wr_comment + 1, wr_last = '$g5['time_ymdhis']' where wr_id = '$wr_id' "); + + // 새글 INSERT + //sql_query(" insert into $g5['board_new_table'] ( bo_table, wr_id, wr_parent, bn_datetime ) values ( '$bo_table', '$comment_id', '$wr_id', '$g5['time_ymdhis']' ) "); + sql_query(" insert into $g5['board_new_table'] ( bo_table, wr_id, wr_parent, bn_datetime, mb_id ) values ( '$bo_table', '$comment_id', '$wr_id', '$g5['time_ymdhis']', '$member['mb_id']' ) "); + + // 코멘트 1 증가 + sql_query(" update $g5['board_table'] set bo_count_comment = bo_count_comment + 1 where bo_table = '$bo_table' "); + + // 포인트 부여 + insert_point($member['mb_id'], $board['bo_comment_point'], "{$board['bo_subject']} {$wr_id}-{$comment_id} 코멘트쓰기", $bo_table, $comment_id, '코멘트'); + + // 메일발송 사용 + if ($config['cf_email_use'] && $board['bo_use_email']) + { + // 관리자의 정보를 얻고 + $super_admin = get_admin("super"); + $group_admin = get_admin("group"); + $board_admin = get_admin("board"); + + $wr_subject = get_text(stripslashes($wr['wr_subject'])); + $wr_content = nl2br(get_text(stripslashes("----- 원글 -----\n\n$wr['wr_subject']\n\n\n----- 코멘트 -----\n\n$wr_content"))); + + $warr = array( ""=>"입력", "u"=>"수정", "r"=>"답변", "c"=>"코멘트", "cu"=>"코멘트 수정" ); + $str = $warr[$w]; + + $subject = "'{$board['bo_subject']}' 게시판에 {$str}글이 올라왔습니다."; + // 4.00.15 - 메일로 보내는 코멘트의 바로가기 링크 수정 + $link_url = "{$g5['url']}/{$g5['bbs']}/board.php?bo_table=$bo_table&wr_id=$wr_id&$qstr#c_{$comment_id}"; + + include_once("{$g5['path']}/lib/mailer.lib.php"); + + ob_start(); + include_once ("./write_update_mail.php"); + $content = ob_get_contents(); + ob_end_clean(); + + $array_email = array(); + // 게시판관리자에게 보내는 메일 + if ($config['cf_email_wr_board_admin']) $array_email[] = $board_admin['mb_email']; + // 게시판그룹관리자에게 보내는 메일 + if ($config['cf_email_wr_group_admin']) $array_email[] = $group_admin['mb_email']; + // 최고관리자에게 보내는 메일 + if ($config['cf_email_wr_super_admin']) $array_email[] = $super_admin['mb_email']; + + // 옵션에 메일받기가 체크되어 있고, 게시자의 메일이 있다면 + if (strstr($wr['wr_option'], "mail") && $wr['wr_email']) { + // 원글 메일발송에 체크가 되어 있다면 + if ($config['cf_email_wr_write']) $array_email[] = $wr['wr_email']; + + // 코멘트 쓴 모든이에게 메일 발송이 되어 있다면 (자신에게는 발송하지 않는다) + if ($config['cf_email_wr_comment_all']) { + $sql = " select distinct wr_email from $write_table + where wr_email not in ( '$wr['wr_email']', '$member['mb_email']', '' ) + and wr_parent = '$wr_id' "; + $result = sql_query($sql); + while ($row=sql_fetch_array($result)) + $array_email[] = $row['wr_email']; + } + } + + // 중복된 메일 주소는 제거 + $unique_email = array_unique($array_email); + for ($i=0; $i= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert("그룹관리자의 권한보다 높은 회원의 코멘트이므로 수정할 수 없습니다."); + } else + alert("자신이 관리하는 그룹의 게시판이 아니므로 코멘트를 수정할 수 없습니다."); + } else if ($is_admin == "board") { // 게시판관리자이면 + $mb = get_member($comment['mb_id']); + if ($member['mb_id'] == $board['bo_admin']) { // 자신이 관리하는 게시판인가? + if ($member['mb_level'] >= $mb['mb_level']) // 자신의 레벨이 크거나 같다면 통과 + ; + else + alert("게시판관리자의 권한보다 높은 회원의 코멘트이므로 수정할 수 없습니다."); + } else + alert("자신이 관리하는 게시판이 아니므로 코멘트를 수정할 수 없습니다."); + } else if ($member['mb_id']) { + if ($member['mb_id'] != $comment['mb_id']) + alert("자신의 글이 아니므로 수정할 수 없습니다."); + } + + $sql = " select count(*) as cnt from $write_table + where wr_comment_reply like '$comment_reply%' + and wr_id <> '$comment_id' + and wr_parent = '$wr_id' + and wr_comment = '$tmp_comment' + and wr_is_comment = 1 "; + $row = sql_fetch($sql); + if ($row['cnt'] && !$is_admin) + alert("이 코멘트와 관련된 답변코멘트가 존재하므로 수정 할 수 없습니다."); + + $sql_ip = ""; + if (!$is_admin) + $sql_ip = " , wr_ip = '{$_SERVER['REMOTE_ADDR']}' "; + + $sql_secret = ""; + if ($wr_secret) + $sql_secret = " , wr_option = '$wr_secret' "; + + $sql = " update $write_table + set wr_subject = '$wr_subject', + wr_content = '$wr_content', + wr_1 = '$wr_1', + wr_2 = '$wr_2', + wr_3 = '$wr_3', + wr_4 = '$wr_4', + wr_5 = '$wr_5', + wr_6 = '$wr_6', + wr_7 = '$wr_7', + wr_8 = '$wr_8', + wr_9 = '$wr_9', + wr_10 = '$wr_10', + wr_option = '$wr_option' + $sql_ip + $sql_secret + where wr_id = '$comment_id' "; + sql_query($sql); +} + +// 사용자 코드 실행 +@include_once("$board_skin_path/write_comment_update.skin.php"); +@include_once("$board_skin_path/write_comment_update.tail.skin.php"); + +goto_url("./board.php?bo_table=$bo_table&wr_id=$wr['wr_parent']&page=$page" . $qstr . "&cwin=$cwin#c_{$comment_id}"); +?> diff --git a/AvocadoEdition/skin/board/qna/write_comment_update.skin.php b/AvocadoEdition/skin/board/qna/write_comment_update.skin.php new file mode 100644 index 0000000..c07ae47 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/write_comment_update.skin.php @@ -0,0 +1,6 @@ + diff --git a/AvocadoEdition/skin/board/qna/write_update.skin.php b/AvocadoEdition/skin/board/qna/write_update.skin.php new file mode 100644 index 0000000..5b16622 --- /dev/null +++ b/AvocadoEdition/skin/board/qna/write_update.skin.php @@ -0,0 +1,6 @@ + diff --git a/AvocadoEdition/skin/connect/basic/connect.skin.php b/AvocadoEdition/skin/connect/basic/connect.skin.php new file mode 100644 index 0000000..5584944 --- /dev/null +++ b/AvocadoEdition/skin/connect/basic/connect.skin.php @@ -0,0 +1,9 @@ +', 0); +?> + + diff --git a/AvocadoEdition/skin/connect/basic/current_connect.skin.php b/AvocadoEdition/skin/connect/basic/current_connect.skin.php new file mode 100644 index 0000000..95044c5 --- /dev/null +++ b/AvocadoEdition/skin/connect/basic/current_connect.skin.php @@ -0,0 +1,46 @@ +', 0); +?> + + +
    + + + + + + + + + + + + + + + ".$location.""; + else $display_location = $location; + ?> + + + + + + "; + ?> + +
    번호이름위치
    현재 접속자가 없습니다.
    +
    + \ No newline at end of file diff --git a/AvocadoEdition/skin/connect/basic/style.css b/AvocadoEdition/skin/connect/basic/style.css new file mode 100644 index 0000000..55cfd4e --- /dev/null +++ b/AvocadoEdition/skin/connect/basic/style.css @@ -0,0 +1 @@ +@charset "utf-8"; \ No newline at end of file diff --git a/AvocadoEdition/skin/content/basic/content.skin.php b/AvocadoEdition/skin/content/basic/content.skin.php new file mode 100644 index 0000000..274bdbd --- /dev/null +++ b/AvocadoEdition/skin/content/basic/content.skin.php @@ -0,0 +1,6 @@ +', 0); +?> + + \ No newline at end of file diff --git a/AvocadoEdition/skin/content/basic/style.css b/AvocadoEdition/skin/content/basic/style.css new file mode 100644 index 0000000..761fb00 --- /dev/null +++ b/AvocadoEdition/skin/content/basic/style.css @@ -0,0 +1,4 @@ +@charset "utf-8"; + +/* 내용관리 */ +.ctt_admin {position: absolute; top: 10px; right: 10px; } diff --git a/AvocadoEdition/skin/faq/basic/list.skin.php b/AvocadoEdition/skin/faq/basic/list.skin.php new file mode 100644 index 0000000..13fb649 --- /dev/null +++ b/AvocadoEdition/skin/faq/basic/list.skin.php @@ -0,0 +1,136 @@ +', 0); + +if ($admin_href) + echo ''; +?> + + +
    +
    diff --git a/AvocadoEdition/theme/basic/head.sub.php b/AvocadoEdition/theme/basic/head.sub.php new file mode 100644 index 0000000..61ac30c --- /dev/null +++ b/AvocadoEdition/theme/basic/head.sub.php @@ -0,0 +1,124 @@ +if(parent && parent!=this) location.href='./main.php';"; +} ?> + +'> + + + + + + +'.PHP_EOL; + echo ''.PHP_EOL; + echo ''.PHP_EOL; +} else { + echo ''.PHP_EOL; + echo ''.PHP_EOL; +} + +if($config['cf_add_meta']) + echo $config['cf_add_meta'].PHP_EOL; +?> + + + + + + + + + + + + + + + +<?php echo $g5_head_title; ?> +'.PHP_EOL; + echo ''.PHP_EOL; +} else { + echo ''.PHP_EOL; + if(!$config['cf_7']) { + echo ''; + } + echo ''.PHP_EOL; +} +?> + + + + + + + + + + + + + + + + + + + + +'.PHP_EOL; // overflow scroll 감지 +} +if(!defined('G5_IS_ADMIN')) + echo $config['cf_add_script']; +?> + + + + diff --git a/AvocadoEdition/theme/basic/index.php b/AvocadoEdition/theme/basic/index.php new file mode 100644 index 0000000..7ed5633 --- /dev/null +++ b/AvocadoEdition/theme/basic/index.php @@ -0,0 +1,34 @@ +', 0); +?> + + +
    + +
    + + + +
    + +
    + + + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/inventory/item.skin.php b/AvocadoEdition/theme/basic/inventory/item.skin.php new file mode 100644 index 0000000..81d04fd --- /dev/null +++ b/AvocadoEdition/theme/basic/inventory/item.skin.php @@ -0,0 +1,47 @@ + + + +
    +
    + +
    +
    +
    +

    + + +

    +
    +
    + +
    + +
    + +
    + + +
    +

    +

    By.

    +
    + +
    +
    +
    + + + +
    \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/inventory/list.skin.php b/AvocadoEdition/theme/basic/inventory/list.skin.php new file mode 100644 index 0000000..329ee94 --- /dev/null +++ b/AvocadoEdition/theme/basic/inventory/list.skin.php @@ -0,0 +1,30 @@ + + + + diff --git a/AvocadoEdition/theme/basic/main.php b/AvocadoEdition/theme/basic/main.php new file mode 100644 index 0000000..b14af2a --- /dev/null +++ b/AvocadoEdition/theme/basic/main.php @@ -0,0 +1,16 @@ +', 0); +include_once(G5_PATH."/intro.php"); +?> + + +THEME BASIC MAIN + + + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/member/list.skin.php b/AvocadoEdition/theme/basic/member/list.skin.php new file mode 100644 index 0000000..9bee245 --- /dev/null +++ b/AvocadoEdition/theme/basic/member/list.skin.php @@ -0,0 +1,52 @@ +', 0); +?> + +
    + {$side['si_name']}
    "; + } + ?> +
    +
      + +
    • +
      + +
      + + + +
      +
      +
    • + 등록된 멤버가 없습니다."; + } + ?> +
    +
    + +
    + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/member/ready_list.skin.php b/AvocadoEdition/theme/basic/member/ready_list.skin.php new file mode 100644 index 0000000..6e69b71 --- /dev/null +++ b/AvocadoEdition/theme/basic/member/ready_list.skin.php @@ -0,0 +1,94 @@ +', 0); +?> + + + + +
    +
    + +
    + +
    + +
    + +
      + +
    • +
      + +
      +

      + + [] + +

      + + + + + + +
      +
      +
    • + + +대기자가 없습니다."; + } + +?> +
    + +
    + +
    + +
    diff --git a/AvocadoEdition/theme/basic/member/viewer.skin.php b/AvocadoEdition/theme/basic/member/viewer.skin.php new file mode 100644 index 0000000..6f8a96d --- /dev/null +++ b/AvocadoEdition/theme/basic/member/viewer.skin.php @@ -0,0 +1,269 @@ +', 0); + +?> + +
    + + + + +
    + +
    + 캐릭터 전신 +
    + + +
    + 캐릭터 흉상 +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    + +
    + +
    + +
    + + +
    + + + + + +
    + + + + +
    +

    + STATUS + + / + +

    +
    +
    + +
    +
    +
    +

    + + + +

    +
    +
    + +
    +
    + + + +
    +

    + TITLE +

    +
    +
    + + + 보유중인 타이틀이 없습니다.
    "; + } + ?> +
    +
    + + + +
    +

    + INVENTORY + + + + + +

    +
    + +
    + + + + + +
    +

    STORY

    +
    +
      + +
    • +
      + + + +
      +
      +
      + +
      +
      +
      +
      + +
      + +
        + ', $relation[$i]['rm_link']); + for($j=0; $j < count($link_list); $j++) { + $r_row = $link_list[$j]; + if(!$r_row) continue; + ?> +
      1. + +
      2. + +
      +
    • + +
    +
    + + +
    + 오너 : +
    + +
    +
    + + + + diff --git a/AvocadoEdition/theme/basic/readme.txt b/AvocadoEdition/theme/basic/readme.txt new file mode 100644 index 0000000..fbcead3 --- /dev/null +++ b/AvocadoEdition/theme/basic/readme.txt @@ -0,0 +1,8 @@ +Theme Name: 샘플 +Theme URI: +Maker: Avocado +Maker URI: https://avocado-edition-rout.postype.com/ +Version: 1.0.0 +Detail: 샘플 테마는 기본적인 부분만을 제공하는 테마입니다. +License: GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 +License URI: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/screenshot.png b/AvocadoEdition/theme/basic/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..59a78de57b165dbe6caca757802c7ade849c4c09 GIT binary patch literal 9544 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 BOE~}l literal 0 HcmV?d00001 diff --git a/AvocadoEdition/theme/basic/shop/shop.item.skin.php b/AvocadoEdition/theme/basic/shop/shop.item.skin.php new file mode 100644 index 0000000..f9bfe92 --- /dev/null +++ b/AvocadoEdition/theme/basic/shop/shop.item.skin.php @@ -0,0 +1,38 @@ + + + +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + 구매하기 + + +
    + +
    +

    + 오류가 발생했습니다. 다시 한번 선택해 주시길 바랍니다. +

    +
    + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/shop/shop.result.skin.php b/AvocadoEdition/theme/basic/shop/shop.result.skin.php new file mode 100644 index 0000000..93eeb85 --- /dev/null +++ b/AvocadoEdition/theme/basic/shop/shop.result.skin.php @@ -0,0 +1,7 @@ + + +
    +

    +
    \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/shop/shop.skin.php b/AvocadoEdition/theme/basic/shop/shop.skin.php new file mode 100644 index 0000000..dc10e79 --- /dev/null +++ b/AvocadoEdition/theme/basic/shop/shop.skin.php @@ -0,0 +1,57 @@ +', 0); +?> + +
    +
    + +
    + +
    +
    +
    + +
    + + +
    + + + +
    +
    +
    + + + diff --git a/AvocadoEdition/theme/basic/skin/board/basic/img/btn_cmt.png b/AvocadoEdition/theme/basic/skin/board/basic/img/btn_cmt.png new file mode 100644 index 0000000000000000000000000000000000000000..0a58a1bcc31a1076f3d7e81677e5d5e3c5368c14 GIT binary patch literal 2942 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 literal 0 HcmV?d00001 diff --git a/AvocadoEdition/theme/basic/skin/board/basic/img/chk.png b/AvocadoEdition/theme/basic/skin/board/basic/img/chk.png new file mode 100644 index 0000000000000000000000000000000000000000..2841a67f35ff08993eeea940005cae936c288483 GIT binary patch literal 1070 zcmbVLPiWIn7>^W&jt!~|VZ*~CLvUb|ytGZ5u)3vvi7VJy+KN4hEKOe5uqH1iZ?@af zgKR_aB;rX?@Hh}Jf&)SD;6d~zcoaMfBIs?tbnWyob}%G)|GwYv_kG{{zU}Jr<;n4x zagO6A%S))n#tHVFIyuJvW3N6m*f33vCase;?O7q_bceJsD0|i_u3^jBxb+^-b6leB zHk!0qxuV&`6Rg-q=z9S}bKLwwKd|gIOhF5;x_*KG{`w6MT&KWa&sL;LP{JK|X*0z2 z&Elzi8bgjT2IMu9FL5YMIWQBCf zmLLR*BEU>mQQ$=&OHdXi_9`iu(Xxsr=fLpcnOf+ywHh*qT5MI|JCp{RDE4|ip_dj& zxGF+bRbviWPBDvAwBb{$pYo&G5d*@J9l8N^i4S5%t3}pnfoGl`gy030$|12I4HLyu zCibmBgn}e`UL4oJI-)iF*Nr2sqsB&n#Tt&tdT6uzXwQzoEO*BX#fHoq?P}<6$ z*y|qlX&DuGb|N^gqh$>_hw`e4RNXZ45UQDsgdohxvZ0y~=_8J#usI~bqG=S7lu;lw z^2KyMZOX-T5oS~EOv95)}!P)C3R5*?k!n+p<5#P)MyC$^eFYCCJBrmIqG%>jwJ_G{xc_Veu5 z#jQAWP!J%HdO@nz3)6NOVw&KBgf?wEY|<+2Gzp zZWvXsjsgvb2uNHuV+#-hS>|9)l4W=thyoOOfetwXbE+h(VjgrJmTC)~DYd4TJG$tu z$TkQGRGx3OT3jp3;c%LVilQVOqL`r)nP|=@R-Eyp{w{-#B0F>g;$j~pjMgNcB}JB6 zy5WKsRI8iBe$)vR4H+L>0S`HW_q@cfwsb^l=wCCol#a}~0P!^x;n~op`IzeOf@$nt zuP70u)~FwaE=`Kn)UiG5A)i$AB1`{pj_atpSSU%^ykdyDZpaWSc}3E6L&y$7S%iAN z%dr(UFNkGhP=bb5rkOBgB_|sN&42|#l$3%5yV!~!5zDtxSFcO;cCf;0v8om#i{Q}2 zxY@0M(FP_sYTy89V=_28?)naHMaPo#Yj(%|n)SFQ}KF1&I4^p9)r40+qu`-VqO{Ie{7=ulpRaz~dziVu@U_dE z@9i+Z%7zmHT-vpKD_-jR(5WiB{UD9aj5$M`YxQgL!;>dU#a?KyY4qt7h+l6u0fDD)j3## zs=j>g3pjyc(YjHo`qjcIQL{}#4P}VHbPyWDCXNM;sx3et)Zm<9rSUr--N1pNr}0^? zKouMb&KuJ!E-bIiRJ4@^P0;aUlVBnc5rGMP6$EC(^28vGw|GUg4v$G3v_$-cG`?$8 zwNM0-?Lxp2Y+R#g8t^zO4bM?AdlBe3b&@PS7 z`@SQRWV6{Mnk-?vb0jSYLdd}|aU>Dw@VN3VXzs*A5g485yV!NfQ)lnxS7UY0odgf6dre+N&%(kSsyZUUW5-kNQXljAD0p zMWGn6gWv%C^kp)3@s-+ z9Q$EYaze^72|-a(3{5M1O5t-7olWxW6eA0CqJzy_p08RO?C3R+-ZnOMSF9+xQ1xxM zV%v>Q1r+CP-}dHh2S{ZejLjOBZa2O0Fg?58%Fs2Ipg!f=CTPW1H1^TYGLpieLFE*w z<+qfjWQOAs$?TNGq*8brtN)*vk;oV_ERO#aOXmnxV7S~XeYDwY9%!MCaZzh@eLb$B zw)#CUXDh*XwX-*4eCFEl`uXS%34ZL|`lT~wV9|lXA+TnNa zo$a~x<>${SoA*8Q&{Fl#htaJ_=33vl@pEK@y0BK~4)lWS$8+y=y?q7irm&Y^kj{@; R(%cf16Zrr$W z{rdHjCr{3vJ$vQKmCv3%n>1@!i5WK)~q>x{P^O< zi?3e2x^LgUUAuPu`Sa)6wQGO>{=Iqg=C5DBwt~R}F!=xfKLeG3;!hSv1_pHo9guk- zKQXWs9GJXe!Gr(?hAx*t0V{byl?6c)-Q>=>GF;f9(9+?}ED$k=Bf9zd1Wy$s_Wnkn z84PU88y&a=9iSXMhSSOWmH3xI$C literal 0 HcmV?d00001 diff --git a/AvocadoEdition/theme/basic/skin/board/basic/img/icon_reply.gif b/AvocadoEdition/theme/basic/skin/board/basic/img/icon_reply.gif new file mode 100644 index 0000000000000000000000000000000000000000..7fe2c65580ed22e254718fdd45ed93efb554672d GIT binary patch literal 1187 zcmZ?wbhEHbCgqow*eU^C z3h_d2fv+#z;Jjizu!r=L^Ke6^lgE!9KDdAH?w#AWZr-?l?dp}w zmo8p7f9~v=)2B|JIDYKtk;8`$9@xKc@1EVecJA1|ZR?iJn>KD(zi#cC)vH#nSiWrO zlEsS_E|@=W?wr}PX3m&CZR(WClO|5+@9XX9?&|DlZ)CJqCAJzX7bElmw|HB}X5B}D~!IawKLDM<-&F;Nj=AwdCtK3*Pf zE=~@1HdYp9CPoGZ#h)xdl954&0SG`P4+E1_OY=;&S8qgOKCNk!;0vz)T^YHC++&YW4WV8MX{2Y_l09y~a2-n^qnkN*GvpMgq1@h1x-1A{t)4#+%^ zpBUJp4@};0iP6RF&=XgqlMO2KpR9E8oa7XAR_$b`iXzA51f4?;er$&r12dHQSe%^| zeYK<-8VnLWIhYwLop{)I>Km)nnc11!o1El48(8?6rcGz!XW`>+oY%', 0); +?> + + +
    + + + + + + + +
    + + + + + + + + + + + + +
    +
    + Total + 페이지 +
    + +
      +
    • 관리자
    • +
    • RSS
    • +
    • + +
    • +
    • 글쓰기
    • + +
    • + + +
        +
      • +
      • +
      • +
      + +
    • + +
    +
    + + +
    + + + + + + + + + + + + + + + + + + + "> + + + + + + + + + + + + + + + '; } ?> + +
    목록
    + + + 번호제목글쓴이조회 추천 비추천 날짜
    + + + + 공지'; + else if ($wr_id == $list[$i]['wr_id']) + echo "열람중"; + else + echo $list[$i]['num']; + ?> + + + + +
    + + + + + + N새글"; + // if ($list[$i]['file']['count']) { echo '<'.$list[$i]['file']['count'].'>'; } + if (isset($list[$i]['icon_hot'])) echo rtrim($list[$i]['icon_hot']); + if (isset($list[$i]['icon_file'])) echo rtrim($list[$i]['icon_file']); + if (isset($list[$i]['icon_link'])) echo rtrim($list[$i]['icon_link']); + ?> + 댓글 +
    +
    게시물이 없습니다.
    +
    + + + + + +
    + + + +
    + +
    + + +
    +
    +

    검색

    +
    + + + + + + +
    + + +
    + +
    +
    +
    +
    + + +
    + + + + + + + + + diff --git a/AvocadoEdition/theme/basic/skin/board/basic/style.css b/AvocadoEdition/theme/basic/skin/board/basic/style.css new file mode 100644 index 0000000..a0c85f8 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/board/basic/style.css @@ -0,0 +1,341 @@ +@charset "utf-8"; + +/* 게시판 목록 */ +#bo_list {position:relative;margin-bottom:20px} +#bo_list:after {display:block;visibility:hidden;clear:both;content:""} +#bo_list .td_board {width:120px;text-align:center} +#bo_list .td_chk {width:30px;text-align:center;border-top:1px solid #ecf0f1;border-bottom:1px solid #ecf0f1} +#bo_list .td_date {width:60px;text-align:center} +#bo_list .td_datetime {width:60px;text-align:center} +#bo_list .td_group {width:100px;text-align:center} +#bo_list .td_mb_id {width:100px;text-align:center} +#bo_list .td_mng {width:80px;text-align:center} +#bo_list .td_name {width:90px;text-align:left;padding:10px 0} +#bo_list .td_nick {width:100px;text-align:center} +#bo_list .td_num {width:50px;text-align:center} +#bo_list .td_num2 {width:50px;text-align:center} +#bo_list .td_numbig {width:80px;text-align:center} +#bo_list .txt_active {color:#5d910b} +#bo_list .txt_expired {color:#ccc} +#bo_list tbody tr {border-left:2px solid transparent} +#bo_list tbody tr:hover {border-left:2px solid #253dbe} +#bo_list tbody .even td {background:#fbfbfb} + +#bo_cate {margin:25px 0} +#bo_cate h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_cate ul {zoom:1} +#bo_cate ul:after {display:block;visibility:hidden;clear:both;content:""} +#bo_cate li {display:inline-block;padding:2px} +#bo_cate a {display:block;line-height:28px;padding:5px 15px;border-radius:30px;border:1px solid #d6e9ff;color:#6794d3} +#bo_cate a:focus, #bo_cate a:hover, #bo_cate a:active {text-decoration:none;background:#3a8afd;color:#fff} +#bo_cate #bo_cate_on {z-index:2;background:#3a8afd;color:#fff;font-weight:bold;border:1px solid #3a8afd; +-webkit-box-shadow:inset 0 2px 5px rgb(33, 135, 202); +-moz-box-shadow:inset 0 2px 5px rgb(33, 135, 202); +box-shadow:inset 0 2px 5px rgb(33, 135, 202)} +.td_subject img {margin-left:5px} + +/* 게시판 목록 공통 */ +.selec_chk {position:absolute;top:0;left:0;width:0;height:0;opacity:0;outline:0;z-index:-1;overflow:hidden} +.chk_box {position:relative} +.chk_box input[type="checkbox"] + label {position:relative;color:#676e70} +.chk_box input[type="checkbox"] + label:hover {color:#2172f8} +.chk_box input[type="checkbox"] + label span {float:left;width:15px;height:15px;display:block;background:#fff;border:1px solid #d0d4df;border-radius:3px} +.write_div .chk_box input[type="checkbox"] + label, .bo_vc_w .chk_box input[type="checkbox"] + label {padding-left:20px} +.write_div .chk_box input[type="checkbox"] + label span, .bo_vc_w .chk_box input[type="checkbox"] + label span {position:absolute;top:2px;left:0;width:15px;height:15px;display:block;margin:0;background:#fff;border:1px solid #d0d4df;border-radius:3px} +.chk_box input[type="checkbox"]:checked + label {color:#000} +.chk_box input[type="checkbox"]:checked + label span {background:url(./img/chk.png) no-repeat 50% 50% #3a8afd;border-color:#1471f6;border-radius:3px} + + +#bo_btn_top {margin:10px 0} +#bo_btn_top:after {display:block;visibility:hidden;clear:both;content:""} +.bo_fx {margin-bottom:5px;float:right;zoom:1} +.bo_fx:after {display:block;visibility:hidden;clear:both;content:""} +.bo_fx ul {margin:0;padding:0;list-style:none} +#bo_list_total {float:left;line-height:34px;font-size:0.92em;color:#4e546f} + +.btn_bo_user {float:right;margin:0;padding:0;list-style:none} +.btn_bo_user li {float:left;width:40px;text-align:center;margin-left:5px;background:#fff} +.btn_bo_user > li {position:relative} +.btn_bo_adm {float:left} +.btn_bo_adm li {float:left;margin-right:5px} +.btn_bo_adm input {padding:0 8px;border:0;background:#d4d4d4;color:#666;text-decoration:none;vertical-align:middle} +.bo_notice td {background:#fff6fa !important;border-bottom:1px solid #f8e6ee} +.bo_notice td a {font-weight:bold} +.bo_notice .notice_icon {display:inline-block;line-height:25px;border-radius:5px;font-weight:bold;color:#f9267f} + +.more_opt {display:none;position:absolute;top:45px;right:0;background:#fff;border:1px solid #b8bfc4;z-index:999} +.more_opt:before {content:"";position:absolute;top:-8px;right:13px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #b8bfc4 transparent} +.more_opt:after {content:"";position:absolute;top:-6px;right:13px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #fff transparent} +.more_opt li {border-bottom:1px solid #f1f1f1;padding:10px;float:inherit;width:90px;margin:0;color:#6b757c;text-align:left} +.more_opt li:last-child {border-bottom:0} +.more_opt li button, .more_opt li a {width:100%;border:0;background:#fff;color:#6b757c} +.more_opt li:hover a, +.more_opt li:hover button {color:#000} +.more_opt li i {float:right;line-height:20px} + +.td_num strong {color:#000} +.bo_cate_link {float:left;display:inline-block;margin-right:10px;background:#e2eaf6;color:#3a8afd;font-weight:normal !important;height:20px;line-height:10px;padding:5px 8px;border-radius:5px;font-size:0.95em} /* 글제목줄 분류스타일 */ +.bo_cate_link:hover {text-decoration:none} +.bo_tit {display:block;color:#000;font-weight:bold} +.bo_current {color:#e8180c} +#bo_list .profile_img img {border-radius:50%} +#bo_list .cnt_cmt {background:#e9eff5;color:#3a8afd;font-size:11px;height:16px;line-height:16px;padding:0 5px;border-radius:3px;vertical-align:middle} + +#bo_list .bo_tit .title_icon {margin-right:2px} +#bo_list .bo_tit .fa-heart {color:#ff0000} +#bo_list .bo_tit .fa-lock {display:inline-block;line-height:14px;width:16px;font-size:0.833em;color:#4f818c;background:#cbe3e8;text-align:center;border-radius:2px;font-size:12px;border:1px solid #cbe3e8;vertical-align:middle} +#bo_list .bo_tit .new_icon {display:inline-block;width:16px;line-height:16px;font-size:0.833em;color:#23db79;background:#b9ffda;text-align:center;border-radius:2px;margin-left:2px;font-weight:bold;vertical-align:middle} +#bo_list .bo_tit .hot_icon {display:inline-block;width:16px;line-height:16px;font-size:0.833em;color:#ff0000;background:#ffb9b9;text-align:center;border-radius:2px;vertical-align:middle} +#bo_list .bo_tit .fa-caret-right {color:#bbb} +#bo_list .bo_tit .fa-download {display:inline-block;width:16px;line-height:16px;font-size:0.833em;color:#daae37;background:#ffefb9;text-align:center;border-radius:2px;margin-left:5px;vertical-align:middle} +#bo_list .bo_tit .fa-link {display:inline-block;width:16px;line-height:16px;font-size:0.833em;color:#b451fd;background:#edd3fd;text-align:center;border-radius:2px;margin-left:5px;vertical-align:middle} + +.bo_sch_wrap {display:none;width:100%;height:100%;position:fixed;top:0;left:0;z-index:999} +.bo_sch {position:absolute;top:50%;left:50%;background:#fff;text-align:left;width:330px;max-height:300px;margin-left:-125px;margin-top:-180px;overflow-y:auto;border-radius:5px;-webkit-box-shadow:1px 1px 18px rgba(0,0,0,0.2);-moz-box-shadow:1px 1px 18px rgba(0,0,0,0.2);box-shadow:1px 1px 18px rgba(0,0,0,0.2);border:1px solid #dde7e9;background:#fff;border-radius:3px} +.bo_sch:after {display:block;visibility:hidden;clear:both;content:""} +.bo_sch h3 {padding:15px;border-bottom:1px solid #e8e8e8} +.bo_sch legend {background:red} +.bo_sch form {padding:15px;display:block} +.bo_sch select {border:0;width:100%;height:40px;border:1px solid #d0d3db;border-radius:2px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075); +-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075); +box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075)} +.bo_sch .sch_bar {display:inline-block;width:100%;clear:both;margin-top:15px;border:1px solid #d0d3db;border-radius:2px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075); +-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075); +box-shadow:inset 0 1px 1px rgba(0, 0, 0, .075)} +.bo_sch .sch_input {width:250px;height:38px;border:0;padding:0;background-color:transparent;float:left} +.bo_sch .sch_btn {height:38px;float:right;color:#656565;background:none;border:0;width:40px;font-size:15px} +.bo_sch .bo_sch_cls {position:absolute;right:0;top:0;color:#b5b8bb;border:0;padding:12px 15px;font-size:16px;background:#fff} +.bo_sch_bg {background:#000;background:rgba(0,0,0,0.1);width:100%;height:100%} + +/* 게시판 쓰기 */ +#char_count_desc {display:block;margin:0 0 5px;padding:0} +#char_count_wrap {margin:5px 0 0;text-align:right} +#char_count {font-weight:bold} + +#autosave_wrapper {position:relative} +#autosave_pop {display:none;z-index:10;position:absolute !important;top:34px;right:0;width:350px;height:auto !important;height:180px;max-height:180px;border:1px solid #565656;background:#fff; +-webkit-box-shadow:2px 2px 3px 0px rgba(0,0,0,0.2); +-moz-box-shadow:2px 2px 3px 0px rgba(0,0,0,0.2); +box-shadow:2px 2px 3px 0px rgba(0,0,0,0.2)} +#autosave_pop:before {content:"";position:absolute;top:-8px;right:45px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #000 transparent} +#autosave_pop:after {content:"";position:absolute;top:-7px;right:45px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #fff transparent} +html.no-overflowscrolling #autosave_pop {height:auto;max-height:10000px !important} /* overflow 미지원 기기 대응 */ +#autosave_pop strong {position:absolute;font-size:0;line-height:0;overflow:hidden} +#autosave_pop div {text-align:center;margin:0 !important} +#autosave_pop button {margin:0;padding:0;border:0} +#autosave_pop ul {padding:15px;border-top:1px solid #e9e9e9;list-style:none;overflow-y:scroll;height:130px;border-bottom:1px solid #e8e8e8} +#autosave_pop li {padding:8px 5px;border-bottom:1px solid #fff;background:#eee;zoom:1} +#autosave_pop li:after {display:block;visibility:hidden;clear:both;content:""} +#autosave_pop a {display:block;float:left} +#autosave_pop span {display:block;float:right;font-size:0.92em;font-style:italic;color:#999} +.autosave_close {cursor:pointer;width:100%;height:30px;background:none;color:#888;font-weight:bold;font-size:0.92em} +.autosave_close:hover {background:#f3f3f3;color:#3597d9} +.autosave_content {display:none} +.autosave_del {background:url(./img/close_btn.png) no-repeat 50% 50%;text-indent:-999px;overflow:hidden;height:20px;width:20px} + +/* 게시판 읽기 */ +#bo_v {margin-bottom:20px;background:#fff;box-sizing:border-box} + +#bo_v_table {position:absolute;top:0;right:16px;margin:0;padding:0 5px;height:25px;background:#ff3061;color:#fff;font-weight:bold;line-height:2.2em} + +#bo_v_title {} +#bo_v_title .bo_v_cate {display:inline-block;line-height:20px;background:#e2eaf6;color:#3a8afd;padding:0 10px;border-radius:3px;} +#bo_v_title .bo_v_tit {display:block;font-size:2em;margin:5px 0 0;word-break:break-all} + +#bo_v_info {margin:0;border-bottom:1px solid #f1f1f1;color:#666} +#bo_v_info:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_info h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} + +#bo_v_info .profile_info {margin:20px 0 10px;display:inline-block;float:left} +#bo_v_info .profile_info .pf_img {float:left;margin-right:10px} +#bo_v_info .profile_info .pf_img img {border-radius:50%;width:50px;height:50px} +#bo_v_info .profile_info .profile_info_ct {float:left;padding:5px 0;line-height:18px} + +#bo_v_info strong {display:inline-block;margin:0 10px 0 0;font-weight:normal} +#bo_v_info .sv_member, +#bo_v_info .sv_guest, +#bo_v_info .member, +#bo_v_info .guest {font-weight:bold} +#bo_v_info .profile_img {display:none} +#bo_v_info .sv_member {color:#000} +#bo_v_info .if_date {margin:0;color:#888} + +#bo_v_file h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_v_file ul {margin:0;list-style:none} +#bo_v_file li {padding:15px;position:relative;margin:10px 0;border:1px solid #dfdfdf;border-radius:5px; +-webkit-box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%); +-moz-box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%); +box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%)} +#bo_v_file li i {float:left;color:#b2b2b2;font-size:2.35em;margin-right:20px} +#bo_v_file a {float:left;display:block;text-decoration:none;word-wrap:break-word;color:#000} +#bo_v_file a:focus, #bo_v_file li:hover a, #bo_v_file a:active {text-decoration:underline;color:#3a8afd} +#bo_v_file img {float:left;margin:0 10px 0 0} +#bo_v_file .bo_v_file_cnt {color:#b2b2b2;font-size:0.92em} +#bo_v_file li:hover {border-color:#bed4f4;color:#bed4f4} +#bo_v_file li:hover i {color:#3a8afd} +#bo_v_file li:hover .bo_v_file_cnt {color:#99c2fc} + + +#bo_v_link h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_v_file ul {margin:0;list-style:none} +#bo_v_link li {padding:15px;position:relative;margin:10px 0;border:1px solid #dfdfdf;border-radius:5px; +-webkit-box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%); +-moz-box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%); +box-shadow:1px 1px 5px 0px hsl(232, 36%, 96%)} +#bo_v_link li i {float:left;color:#b2b2b2;font-size:2.35em;margin-right:20px} +#bo_v_link a {float:left;display:block;text-decoration:none;word-wrap:break-word;color:#000} +#bo_v_link a:focus, #bo_v_link li:hover a, #bo_v_link a:active {text-decoration:underline;color:#3a8afd} +#bo_v_link .bo_v_link_cnt {color:#b2b2b2;font-size:0.92em} +#bo_v_link li:hover {border-color:#bed4f4;color:#bed4f4} +#bo_v_link li:hover i {color:#3a8afd} +#bo_v_link li:hover .bo_v_link_cnt {color:#99c2fc} + +#bo_v_top {zoom:1} +#bo_v_top:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_top h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_v_top ul {padding:0;list-style:none;word-break:break-all;background:#fff} + +#bo_v_bot {zoom:1} +#bo_v_bot:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_bot h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_v_bot ul {padding:0;list-style:none} + +.bo_v_com {margin:20px 0;float:right} +.bo_v_com > li {position:relative;float:left;margin-left:5px} + +.bo_v_nb {position:relative;margin:20px 0;clear:both;text-align:left} +.bo_v_nb:after {display:block;visibility:hidden;clear:both;content:""} +.bo_v_nb li {border-top:1px solid #f1f1f1;padding:13px} +.bo_v_nb li:last-child {border-bottom:1px solid #f1f1f1} +.bo_v_nb li:hover {background:#f6f6f6} +.bo_v_nb li i {font-size:13px;color:#b3b3b3} +.bo_v_nb li .nb_tit {display:inline-block;padding-right:20px;color:#b3b3b3} +.bo_v_nb li .nb_date {float:right;color:#b3b3b3} + +#bo_v_atc {min-height:200px;height:auto !important;height:200px} +#bo_v_atc_title {position:absolute;font-size:0;line-height:0;overflow:hidden} + +#bo_v_img {width:100%;overflow:hidden;zoom:1} +#bo_v_img:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_img a.view_image {display:block} +#bo_v_img img {margin-bottom:20px;max-width:100%;height:auto} + +#bo_v_con {margin:10px 0 30px;width:100%;line-height:1.7em;min-height:200px;word-break:break-all;overflow:hidden} +#bo_v_con a {color:#000;text-decoration:underline} +#bo_v_con img {max-width:100%;height:auto} + +#bo_v_act {margin-bottom:30px;text-align:center} +#bo_v_act .bo_v_act_gng {position:relative} +#bo_v_act a {margin-right:5px;vertical-align:middle;color:#4a5158} +#bo_v_act a:hover {background-color:#fff;color:#ff484f;border-color:#ff484f} +#bo_v_act i {font-size:1.4em;margin-right:5px} +#bo_v_act_good, #bo_v_act_nogood {display:none;position:absolute;top:30px;left:0;z-index:9999;padding:10px 0;width:165px;background:#ff3061;color:#fff;text-align:center} +#bo_v_act .bo_v_good {display:inline-block;border:1px solid #dedede;width:70px;line-height:46px;border-radius:30px} +#bo_v_act .bo_v_nogood {display:inline-block;border:1px solid #dedede;width:70px;line-height:46px;border-radius:30px} + +#bo_v_sns {padding:0;list-style:none;zoom:1;float:left;display:inline-block} +#bo_v_sns:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_sns li {float:left;width:135px;margin-right:5px;text-align:left} +#bo_v_sns li a {height:35px;line-height:35px;text-align:center;border-radius:5px;color:#fff;font-size:0.95em} +#bo_v_sns li img {vertical-align:middle;margin-right:5px} +#bo_v_sns li .sns_f {display:block;background:#3b5997} +#bo_v_sns li .sns_t {display:block;background:#09aeee} +#bo_v_sns li .sns_g {display:block;background:#ea4026} +#bo_v_sns li .sns_k {display:block;background:#fbe300} + +#bo_v_share {position:relative;padding:20px 0} +#bo_v_share:after {display:block;visibility:hidden;clear:both;content:""} +#bo_v_share .btn {padding:0 10px;color:#555;font-weight:normal;font-size:1em;width:80px;line-height:35px;height:35px;border-color:#d5d5d5;border-radius:5px} +#bo_v_share .btn:hover {background:#fff} +#bo_v_share .btn i {margin-right:5px;color:#4b5259;vertical-align:middle} + +/* 게시판 댓글 */ +.cmt_btn {width:100%;text-align:left;border:0;border-bottom:1px solid #f0f0f0;background:#fff;font-weight:bold;margin:30px 0 0px;padding:0 0 15px} +.cmt_btn span.total {position:relative;display:inline-block;margin-right:5px;font-size:1em;color:#3a8afd} +.cmt_btn span.cmt_more {float:right;display:inline-block;width:15px;height:10px;background:url(./img/btn_cmt.png) no-repeat right 2px;margin-top:5px} +.cmt_btn_op span.cmt_more {background-position:right -8px} +.cmt_btn b {font-size:1.2em;color:#000} +.cmt_btn span.total:after {position:absolute;bottom:-17px;left:0;display:inline-block;background:#3a8afd;content:"";width:100%;height:2px} +#bo_vc {} +#bo_vc h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc article {margin:20px 0;position:relative;border-bottom:1px solid #f0f0f0} +#bo_vc article:after {display:block;visibility:hidden;clear:both;content:""} +#bo_vc article .profile_img img {border-radius:50%} +#bo_vc article .pf_img {float:left;margin-right:10px} +#bo_vc article .pf_img img {border-radius:50%;width:50px;height:50px} +#bo_vc article .cm_wrap {float:left;max-width:870px;width:90%} +#bo_vc header {position:relative;width:100%} +#bo_vc header:after {display:block;visibility:hidden;clear:both;content:""} +#bo_vc header .profile_img {display:none} +#bo_vc header .icon_reply {position:absolute;top:15px;left:-20px} +#bo_vc .member, #bo_vc .guest, #bo_vc .sv_member, #bo_vc .sv_guest {font-weight:bold} +.bo_vc_hdinfo {color:#777} +#bo_vc h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#bo_vc .cmt_contents {line-height:1.8em;padding:0 0 20px} +#bo_vc p a {text-decoration:underline} +#bo_vc p a.s_cmt {text-decoration:underline;color:#ed6479} +#bo_vc_empty {margin:0;padding:80px 0 !important;color:#777;text-align:center} +#bo_vc #bo_vc_winfo {float:left} +#bo_vc .bo_vl_opt {position:absolute;top:0;right:0} + +.bo_vc_act {display:none;position:absolute;right:0;top:40px;width:58px;text-align:right;border:1px solid #b8bfc4;margin:0;list-style:none;background:#fff;zoom:1;z-index:9999} +.bo_vc_act:before {content:"";position:absolute;top:-8px;right:5px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #b8bfc4 transparent} +.bo_vc_act:after {content:"";position:absolute;top:-6px;right:5px;width:0;height:0;border-style:solid;border-width:0 6px 8px 6px;border-color:transparent transparent #fff transparent} +.bo_vc_act li {border-bottom:1px solid #f0f0f0} +.bo_vc_act li:last-child {border-bottom:0} +.bo_vc_act li a {display:inline-block;padding:10px 15px} +.bo_vc_act li a:hover {color:#3a8afd} + +.bo_vc_w {position:relative;margin:10px 0;display:block} +.bo_vc_w:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w h2 {position:absolute;font-size:0;line-height:0;overflow:hidden} +.bo_vc_w #char_cnt {display:block;margin:0 0 5px} +.bo_vc_w textarea {border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;width:100%;height:120px; +-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1); +-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1); +box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1)} +#wr_secret {} +.bo_vc_w_info {margin:10px 0;float:left} +.bo_vc_w_info:after {display:block;visibility:hidden;clear:both;content:""} +.bo_vc_w_info .frm_input {float:left;margin-right:5px} +.bo_vc_w_info #captcha {padding-top:10px;display:block;clear:both} +.bo_vc_w .btn_confirm {clear:both;margin-top:10px} +.bo_vc_w .btn_confirm label {display:inline-block;margin-right:10px;border-radius:3px;font-size:1.5em;text-align:center} +.bo_vc_w .btn_submit {height:45px;padding:0 20px;border-radius:3px;font-weight:bold;font-size:1.083em} +.bo_vc_w .btn_confirm .secret_cm label {font-size:1em !important} +.bo_vc_w_wr:after {display:block;visibility:hidden;clear:both;content:""} +.secret_cm {display:inline-block;float:left} + +#bo_vc_send_sns {display:inline-block;float:left} +#bo_vc_sns {display:inline-block;margin:0;padding:0;list-style:none;zoom:1} +#bo_vc_sns:after {display:block;visibility:hidden;clear:both;content:""} +#bo_vc_sns li {float:left;margin:0 5px 0 0} +#bo_vc_sns .sns_li_f {border-radius:3px;background:#3a589b;height:40px;line-height:40px;padding:0 0 0 10px} +#bo_vc_sns .sns_li_t {border-radius:3px;background:#00aced;height:40px;line-height:40px;padding:0 0 0 10px} +#bo_vc_sns .sns_li_off {background:#bbb} +#bo_vc_sns a {display:inline-block;padding:0 15px 0 5px} +#bo_vc_sns input {margin:0 5px 0 0} + +/*글쓰기*/ +#bo_w .bo_v_option li {display:inline-block;float:left;text-align:left;margin:0 5px 0 0} +#bo_w .bo_v_option li label {vertical-align:baseline} +#bo_w .bo_v_option .chk_box input[type="checkbox"] + label span {margin-left:0;margin-right:5px} +#bo_w .write_div {margin:10px 0;position:relative} +#bo_w .write_div:after {display:block;visibility:hidden;clear:both;content:""} +#bo_w .bo_w_info:after {display:block;visibility:hidden;clear:both;content:""} +#bo_w .bo_w_info .frm_input {float:left;margin-bottom:1%} +#bo_w #wr_password, #bo_w #wr_homepage {margin-left:1%} +#bo_w .wr_content.smarteditor2 iframe {background:#fff} +#bo_w .bo_w_tit {position:relative} +#bo_w .bo_w_tit .frm_input {padding-right:120px} +#bo_w .bo_w_tit #btn_autosave {position:absolute;top:5px;right:5px;line-height:30px;height:30px} +#bo_w .bo_w_link label {position:absolute;top:1px;left:1px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;font-size:1.2em;text-align:center;color:#b2b2b2} +#bo_w .bo_w_link .frm_input {padding-left:50px} +#bo_w .bo_w_flie .lb_icon {position:absolute;top:0px;left:0px;border-radius:3px 0 0 3px;height:38px;line-height:38px;width:40px;font-size:1.2em;text-align:center;color:#b2b2b2} +#bo_w .bo_w_flie .frm_file {padding-left:50px;margin-top:3px} +#bo_w .bo_w_flie .file_wr {position:relative;border:1px solid #ccc;background:#fff;color:#000;vertical-align:middle;border-radius:3px;padding:5px;height:40px;margin:0} +#bo_w .bo_w_flie .frm_input {margin:10px 0 0} +#bo_w .bo_w_flie .file_del {position:absolute;top:10px;right:10px;font-size:0.92em;color:#7d7d7d} +#bo_w .bo_w_select select {border:1px solid #d0d3db;width:100%;height:40px;border-radius:3px} +#bo_w .btn_submit {padding:0 20px;font-size:1.167em} +#bo_w .btn_cancel {border-radius:3px;font-size:1.167em} \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/skin/board/basic/view.skin.php b/AvocadoEdition/theme/basic/skin/board/basic/view.skin.php new file mode 100644 index 0000000..a063c14 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/board/basic/view.skin.php @@ -0,0 +1,300 @@ +', 0); +?> + + + + + +
    +
    +

    + + + + + +

    +
    + +
    +

    페이지 정보

    +
    +
    +
    + 작성자
    + 댓글 + 조회 + 작성일 +
    +
    + + +
    + + + + + +
    + +
    + +
    +

    본문

    +
    + + 스크랩 +
    + + \n"; + + foreach($view['file'] as $view_file) { + echo get_file_thumbnail($view_file); + } + + echo "\n"; + } + ?> + + +
    + + + +

    + + + + +
    + + + 추천 + + + + + + 비추천 + + + +
    + +
    + 추천 + 비추천 +
    + + +
    + + + + + +
    +

    첨부파일

    +
      + +
    • + + + () + +
      + 회 다운로드 | DATE : +
    • + +
    +
    + + + + + + + + + + +
      +
    • 이전글
    • +
    • 다음글
    • +
    + + + +
    + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/skin/board/basic/view_comment.skin.php b/AvocadoEdition/theme/basic/skin/board/basic/view_comment.skin.php new file mode 100644 index 0000000..dbd1356 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/board/basic/view_comment.skin.php @@ -0,0 +1,352 @@ + + + + + +
    +

    댓글목록

    + \]/i", "", $comment); + $cmt_sv = $cmt_amt - $i + 1; // 댓글 헤더 z-index 재설정 ie8 이하 사이드뷰 겹침 문제 해결 + $c_reply_href = $comment_common_url.'&c_id='.$comment_id.'&w=c#bo_vc_w'; + $c_edit_href = $comment_common_url.'&c_id='.$comment_id.'&w=cu#bo_vc_w'; + $is_comment_reply_edit = ($list[$i]['is_reply'] || $list[$i]['is_edit'] || $list[$i]['is_del']) ? 1 : 0; + ?> + +
    style="margin-left:px;border-top-color:#e0e0e0"> +
    + +
    + +
    +

    님의 댓글의 댓글

    + + + 아이피 + () + + 작성일 + + +
    + + +
    +

    + 비밀글 + +

    + + +
    + + + + " id="secret_comment_"> + +
    + +
    + + +
    + + +
    + +

    등록된 댓글이 없습니다.

    + +
    + + + + + + + + + + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/skin/board/basic/write.skin.php b/AvocadoEdition/theme/basic/skin/board/basic/write.skin.php new file mode 100644 index 0000000..429c8da --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/board/basic/write.skin.php @@ -0,0 +1,255 @@ +', 0); +?> + +
    +

    + + +
    + + + + + + + + + + + + '.PHP_EOL.''; + } + if ($is_html) { + if ($is_dhtml_editor) { + $option_hidden .= ''; + } else { + $option .= PHP_EOL.'
  • '.PHP_EOL.'
  • '; + } + } + if ($is_secret) { + if ($is_admin || $is_secret==1) { + $option .= PHP_EOL.'
  • '.PHP_EOL.'
  • '; + } else { + $option_hidden .= ''; + } + } + if ($is_mail) { + $option .= PHP_EOL.'
  • '.PHP_EOL.'
  • '; + } + } + echo $option_hidden; + ?> + + +
    + + +
    + + +
    + + + + + + + + class="frm_input half_input " placeholder="비밀번호"> + + + + + + + + + + + + +
    + + +
    + 옵션 +
      + +
    +
    + + +
    + + +
    + + + + + +
    + 임시 저장된 글 목록 +
      +
      +
      + +
      + +
      + +
      + +
      + + +

      이 게시판은 최소 글자 이상, 최대 글자 이하까지 글을 쓰실 수 있습니다.

      + + + + +
      글자
      + +
      + +
      + + + + + + +
      +
      + + +
      + + + + + + + + + + +
      + + + + +
      + +
      + + +
      + 취소 + +
      +
      + + +
      + \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/skin/content/basic/content.skin.php b/AvocadoEdition/theme/basic/skin/content/basic/content.skin.php new file mode 100644 index 0000000..ce54fc4 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/content/basic/content.skin.php @@ -0,0 +1,17 @@ +', 0); +?> + +
      +
      +

      +
      + +
      + +
      + +
      \ No newline at end of file diff --git a/AvocadoEdition/theme/basic/skin/content/basic/style.css b/AvocadoEdition/theme/basic/skin/content/basic/style.css new file mode 100644 index 0000000..769ab33 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/content/basic/style.css @@ -0,0 +1,10 @@ +@charset "utf-8"; + +/* 내용관리 */ +#ctt {margin:10px 0;padding:20px;background:#fff} +.ctt_admin {text-align:right} +#ctt header h1 {position:absolute;font-size:0;line-height:0;overflow:hidden} +#ctt_con {padding:10px 0;line-height:1.6em} +#ctt_con img{max-width:100%;height:auto} +.ctt_img {text-align:center} + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/basic/img/chk.png b/AvocadoEdition/theme/basic/skin/outlogin/basic/img/chk.png new file mode 100644 index 0000000000000000000000000000000000000000..2841a67f35ff08993eeea940005cae936c288483 GIT binary patch literal 1070 zcmbVLPiWIn7>^W&jt!~|VZ*~CLvUb|ytGZ5u)3vvi7VJy+KN4hEKOe5uqH1iZ?@af zgKR_aB;rX?@Hh}Jf&)SD;6d~zcoaMfBIs?tbnWyob}%G)|GwYv_kG{{zU}Jr<;n4x zagO6A%S))n#tHVFIyuJvW3N6m*f33vCase;?O7q_bceJsD0|i_u3^jBxb+^-b6leB zHk!0qxuV&`6Rg-q=z9S}bKLwwKd|gIOhF5;x_*KG{`w6MT&KWa&sL;LP{JK|X*0z2 z&Elzi8bgjT2IMu9FL5YMIWQBCf zmLLR*BEU>mQQ$=&OHdXi_9`iu(Xxsr=fLpcnOf+ywHh*qT5MI|JCp{RDE4|ip_dj& zxGF+bRbviWPBDvAwBb{$pYo&G5d*@J9l8N^i4S5%t3}pnfoGl`gy030$|12I4HLyu zCibmBgn}e`UL4oJI-)iF*Nr2sqsB&n#Tt&tdT6uzXwQzoEO*BX#fHoq?P}<6$ z*y|qlX&DuGb|N^gqh$>_hw`e4RNXZ45UQDsgdohxvZ0y~=_8J#usI~bqG=S7lu;lw z^2KyMZOX-T5oS~#3k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+nA0*tB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxSU1_g&``n5OwZ87 z)XdCKN5ROz&`93^h|F{iO{`4Ktc=VRpg;*|TTx1yRgjAt)Gi>;Rw<*Tq`*pFzr4I$ zuiRKKzbIYb(9+TpWQLKEE>MMTab;dfVufyAu`kBtHuNWFoz#!AFNG#Ad)HBe}%?0@jth%@)C>7xhtg4GcDhpEegHnt0 zON)|$@sXws(+mtd{1$-}0$pR}Uz7=ql*AmD{N&Qy)VvZ;7h5Huj9yA+ij|9zg`=sl zxuvU-i;Jt7p`oR@rKz)vtAVkTp_!4Pi#f~;YKL?fq0y6ST@{2R_ z3lyA#%@j1kGxJjN%ZoKZ(F5_VOKMSOS!#+~QGTuhIDD-#vDj~9Xk=_^>f-8b;A#o- zx09KXo1>GNqlu-PldFZLkrGsI3OQk>4|I$^C~+Vq7MKt)1%jCHqz~l4Gf!$BFvk=D zv&J8V)!!Ky7;`;c978H@felA3TEtw6(oF`I;3I+c-SU#CMTFjgnwiI zk>8_wanZq~3o2{}O;S#%^XZ5kPjOT~v-y4Pi4UJ!zMrf8zUTKlYjZgkM;)fv>(^hK zdMv(}u{G+Vi1W6WC0Vz(>6~7ExpPj$v{DNhp2H`ef1adrlrf|=&u+f5@1Yy^9gA+{ zZP(oJ_@hVPzE=&m-?o`f(dufddSWuyZ?VJn+fOV1>E@cvemMK_#~;tdIV}1vo9IsT zX!yO)UWV`dbK?r5nIbHWeoKR{zn*$$U5M7vq=^Nymd!uEJag8A{^O5}b_QIW_wIYO zNsE$H(AO&4*=Hvu?7llmobh', 0); +?> + + +
      +
      +

      회원로그인

      + 회원가입 +
      +
      +
      +
      + + + + + + +
      +
      +
      + + +
      + +
      + + +
      +
      +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/basic/outlogin.skin.2.php b/AvocadoEdition/theme/basic/skin/outlogin/basic/outlogin.skin.2.php new file mode 100644 index 0000000..aeaea03 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/basic/outlogin.skin.2.php @@ -0,0 +1,52 @@ +', 0); +?> + + +
      +
      +

      나의 회원정보

      + + + + + 정보수정 + 관리자 +
      + + +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/basic/style.css b/AvocadoEdition/theme/basic/skin/outlogin/basic/style.css new file mode 100644 index 0000000..ea13569 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/basic/style.css @@ -0,0 +1,64 @@ +@charset "utf-8"; + +/* 아웃로그인 스킨 */ +.ol {position:relative;border:1px solid #dde7e9;margin-bottom:15px;border-radius:3px} +.ol h2 {width:117px;float:left;padding:15px 0;text-align:center} +.ol .join {width:116px;float:left;padding:15px 0;text-align:center;background:#f7f7f7;color:#6e6e6e} +.ol #ol_be_cate:after {display:block;visibility:hidden;clear:both;content:""} +.ol form {padding:20px} +.ol a.btn_admin {display:inline-block;padding:0 10px;height:25px;text-decoration:none;line-height:25px;vertical-align:middle} /* 관리자 전용 버튼 */ +.ol a.btn_admin:focus, .ol a.btn_admin:hover {text-decoration:none} +.ol .login-sns{padding-bottom:0px} + +#ol_before {} +#ol_before:after {display:block;visibility:hidden;clear:both;content:""} +#ol_before .ol_wr {position:relative;margin-bottom:5px} +#ol_id {display:block;width:100%;border:1px solid #d0d3db;padding:0 10px;height:35px;margin-bottom:5px;border-radius:3px} +#ol_pw {display:block;width:100%;border:1px solid #d0d3db;padding:0 10px;height:35px;margin-bottom:5px;border-radius:3px} +#ol_submit {width:100%;height:35px;background:#3a8afd;border-left:1px solid #ccc;color:#fff;font-weight:bold;font-size:1.167em;border-radius:3px} +#ol_svc {float:right;line-height:20px} +#ol_svc a {display:inline-block;border:1px solid #d5d9dd;color:#3a8afd;border-radius:2px;padding:2px 5px} +#ol_auto {float:left;line-height:20px;margin-top:5px} +#ol_auto label {color:#555;vertical-align:baseline} +#ol_auto input {width:13px;height:13px} +.ol_auto_wr:after {display:block;visibility:hidden;clear:both;content:""} +#sns_login {margin-top:0 !important;border-top:0 !important} +#sns_login h3 {position:absolute;font-size:0;line-height:0;overflow:hidden} + +#ol_after {} +#ol_after_hd {position:relative;padding:10px;padding-left:80px;height:80px} +#ol_after_hd strong {display:block;margin:5px 0 10px} +#ol_after_hd .profile_img {position:absolute;top:15px;left:15px;display:inline-block} +#ol_after_hd .profile_img img {border:1px solid #bbb;border-radius:50%;width:50px;height:50px} +#ol_after_hd .profile_img a {text-align:center;font-size:17px;width:30px;line-height:30px;color:#777} +#ol_after_info {display:inline-block;height:28px;line-height:22px;border:1px solid #d5d9dd;color:#3a8afd;border-radius:2px;padding:2px 5px} +#ol_after h2 {margin:0;padding:0;width:1px;height:1px;font-size:0;line-height:0;overflow:hidden} +#ol_after_hd .btn_admin {border-radius:3px;height:28px;line-height:28px;vertical-align:baseline} +#ol_after_hd .btn_b04 {line-height:23px;padding:0 5px} +#ol_after_private {zoom:1} +#ol_after_private:after {display:block;visibility:hidden;clear:both;content:""} +#ol_after_private li {text-align:left;position:relative;text-align:left} +#ol_after_private li:first-child a {border-left:0} +#ol_after_private a {display:block;color:#465168;line-height:18px;padding:10px 10px 10px 20px} +#ol_after_private a strong {display:inline-block;float:right;max-width:87px;overflow:hidden;white-space:nowrap;text-overflow:clip;color:#3a8afd;padding:0 5px;border-radius:15px;font-size:0.92em} +#ol_after_private a:hover strong {background:#4b8bff} +#ol_after_private li a:hover {color:#4b8bff;background:#f7f7f7} +#ol_after_private li a:hover:after {position:absolute;left:-1px;top:0;width:2px;height:38px;background:#3a8afd;content:""} +#ol_after_private li i {width:25px;color:#8c9eb0;margin-right:5px} +#ol_after_private li:hover i {color:#3a8afd} +#ol_after_private .win_point:hover strong {background:#37bc9b;color:#fff} +#ol_after_private .win_memo:hover strong {background:#8cc152;color:#fff} +#ol_after_private .win_scrap:hover strong {background:#ff8b77;color:#fff} + +#ol_after_logout {text-align:center;font-weight:bold;display:block;padding:15px 0;color:#a0a0a1;border-top:1px solid #dde7e9} +#ol_after_logout:hover {color:#3c8bfd} +#ol_after_memo {margin-right:1px} +#ol_after_pt {margin-right:1px} + +.selec_chk {position:absolute;top:0;left:0;width:0;height:0;opacity:0;outline:0;z-index:-1;overflow:hidden} +.chk_box {position:relative} +.chk_box input[type="checkbox"] + label {padding-left:20px;color:#676e70} +.chk_box input[type="checkbox"] + label:hover{color:#2172f8} +.chk_box input[type="checkbox"] + label span {position:absolute;top:2px;left:0;width:15px;height:15px;display:block;margin:0;background:#fff;border:1px solid #d0d4df;border-radius:3px} +.chk_box input[type="checkbox"]:checked + label {color:#000} +.chk_box input[type="checkbox"]:checked + label span {background:url(./img/chk.png) no-repeat 50% 50% #3a8afd;border-color:#1471f6;border-radius:3px} diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/img/chk.png b/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/img/chk.png new file mode 100644 index 0000000000000000000000000000000000000000..2841a67f35ff08993eeea940005cae936c288483 GIT binary patch literal 1070 zcmbVLPiWIn7>^W&jt!~|VZ*~CLvUb|ytGZ5u)3vvi7VJy+KN4hEKOe5uqH1iZ?@af zgKR_aB;rX?@Hh}Jf&)SD;6d~zcoaMfBIs?tbnWyob}%G)|GwYv_kG{{zU}Jr<;n4x zagO6A%S))n#tHVFIyuJvW3N6m*f33vCase;?O7q_bceJsD0|i_u3^jBxb+^-b6leB zHk!0qxuV&`6Rg-q=z9S}bKLwwKd|gIOhF5;x_*KG{`w6MT&KWa&sL;LP{JK|X*0z2 z&Elzi8bgjT2IMu9FL5YMIWQBCf zmLLR*BEU>mQQ$=&OHdXi_9`iu(Xxsr=fLpcnOf+ywHh*qT5MI|JCp{RDE4|ip_dj& zxGF+bRbviWPBDvAwBb{$pYo&G5d*@J9l8N^i4S5%t3}pnfoGl`gy030$|12I4HLyu zCibmBgn}e`UL4oJI-)iF*Nr2sqsB&n#Tt&tdT6uzXwQzoEO*BX#fHoq?P}<6$ z*y|qlX&DuGb|N^gqh$>_hw`e4RNXZ45UQDsgdohxvZ0y~=_8J#usI~bqG=S7lu;lw z^2KyMZOX-T5oS~', 0); +?> + + +
      +

      회원로그인

      +
      +
      + + + + + +
      + + +
      + + + +
      +
      +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/outlogin.skin.2.php b/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/outlogin.skin.2.php new file mode 100644 index 0000000..3639e61 --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/outlogin.skin.2.php @@ -0,0 +1,43 @@ +', 0); +?> + + + + + +
      +

      회원정보

      + + +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/style.css b/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/style.css new file mode 100644 index 0000000..85440cc --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/shop_basic/style.css @@ -0,0 +1,44 @@ +@charset "utf-8"; + +/* 아웃로그인 스킨 */ +.ol {position:relative} +.ol h2 {margin:0;padding:0;width:1px;height:1px;font-size:0;line-height:0;overflow:hidden} + +.ol a.btn_admin {display:inline-block;padding:0 10px;height:25px;background:#d13f4a;color:#fff;text-decoration:none;line-height:25px;vertical-align:middle} /* 관리자 전용 버튼 */ +.ol a.btn_admin:focus, .ol a.btn_admin:hover {text-decoration:none} + +#ol_before {} +#ol_before fieldset {position:relative} +#ol_id {display:block;width:100%;margin:5px 0 10px} +.ol_idlabel {color:#333} +#ol_pw {display:block;width:100%;margin:5px 0} +.ol_pwlabel {color:#333} +#auto_login {} +#auto_login_label {letter-spacing:-0.1em} +#ol_submit {width:100%;height:40px;border:0;border-radius:3px;color:#fff;font-weight:bold} +#ol_before a {letter-spacing:-0.15em} +#ol_svc {text-align:center;margin:10px 0 0} +#ol_svc a {display:inline-block;color:#333;margin:0 5px} +#ol_auto {position:relative;margin:5px 0;font-size:0.92em;color:#555} +#ol_auto label {letter-spacing:-0.1em} +#ol_auto input {width:13px;height:13px;vertical-align:bottom} + +.btn_member_mn {min-width:150px;padding:5px 0;border:0;background:transparent;color:#fff;text-align:center} +.btn_member_mn .profile_img {display:inline-block;margin-right:5px} +.btn_member_mn .profile_img img {border-radius:50%} +.btn_member_mn .profile_name {display:inline-block;max-width:70px;line-height:34px;vertical-align: bottom;text-overflow:ellipsis;overflow:hidden;white-space:nowrap} +.btn_member_mn i {display:inline-block;margin-left:5px;font-size:1.2em;font-weight:bold} +.btn_member_mn_on {background:#fff;color:#000;border:1px solid #d0d0d0;border-bottom:0} +.member_mn {display:none;position:absolute;left:0;width:150px;background:#fff;z-index:99;border:1px solid #d0d0d0;border-top:0} + +#ol_after {} +#ol_after_private {text-align:left} +#ol_after_private:after {display:block;visibility:hidden;clear:both;content:""} +#ol_after_private li {margin-bottom:1px;position:relative} +#ol_after_private li:hover a {background:#f7f7f7} +#ol_after_private a {display:block;color:#444;padding:10px 15px;line-height:20px} +#ol_after_private a strong {float:right;display:inline-block;color:#fff;overflow:hidden;white-space:nowrap;text-overflow:clip;padding:0 5px;border-radius:15px;font-weight:normal;font-size:0.92em} +#ol_after_private .win_point strong {background:#37bc9b} +#ol_after_private .win_coupon strong {background:#a352c1} +#ol_after_private .win_memo strong {background:#ff8b77} +#ol_after_logout {display:block;font-size:1.083em;line-height:45px;text-align:center;color:#3a8afd;border-top:1px solid #f6f6f6} diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_side/img/chk.png b/AvocadoEdition/theme/basic/skin/outlogin/shop_side/img/chk.png new file mode 100644 index 0000000000000000000000000000000000000000..2841a67f35ff08993eeea940005cae936c288483 GIT binary patch literal 1070 zcmbVLPiWIn7>^W&jt!~|VZ*~CLvUb|ytGZ5u)3vvi7VJy+KN4hEKOe5uqH1iZ?@af zgKR_aB;rX?@Hh}Jf&)SD;6d~zcoaMfBIs?tbnWyob}%G)|GwYv_kG{{zU}Jr<;n4x zagO6A%S))n#tHVFIyuJvW3N6m*f33vCase;?O7q_bceJsD0|i_u3^jBxb+^-b6leB zHk!0qxuV&`6Rg-q=z9S}bKLwwKd|gIOhF5;x_*KG{`w6MT&KWa&sL;LP{JK|X*0z2 z&Elzi8bgjT2IMu9FL5YMIWQBCf zmLLR*BEU>mQQ$=&OHdXi_9`iu(Xxsr=fLpcnOf+ywHh*qT5MI|JCp{RDE4|ip_dj& zxGF+bRbviWPBDvAwBb{$pYo&G5d*@J9l8N^i4S5%t3}pnfoGl`gy030$|12I4HLyu zCibmBgn}e`UL4oJI-)iF*Nr2sqsB&n#Tt&tdT6uzXwQzoEO*BX#fHoq?P}<6$ z*y|qlX&DuGb|N^gqh$>_hw`e4RNXZ45UQDsgdohxvZ0y~=_8J#usI~bqG=S7lu;lw z^2KyMZOX-T5oS~', 0); +?> + + +
      +
      +

      회원로그인

      + 회원가입 +
      +
      +
      +
      + + + + + + +
      +
      +
      + + +
      + +
      + + +
      +
      +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_side/outlogin.skin.2.php b/AvocadoEdition/theme/basic/skin/outlogin/shop_side/outlogin.skin.2.php new file mode 100644 index 0000000..abbc07b --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/shop_side/outlogin.skin.2.php @@ -0,0 +1,70 @@ +', 0); + +// 쿠폰 +$cp_count = 0; +$sql = " select cp_id + from {$g5['g5_shop_coupon_table']} + where mb_id IN ( '{$member['mb_id']}', '전체회원' ) + and cp_start <= '".G5_TIME_YMD."' + and cp_end >= '".G5_TIME_YMD."' "; +$res = sql_query($sql); + +for($k=0; $cp=sql_fetch_array($res); $k++) { + if(!is_used_coupon($member['mb_id'], $cp['cp_id'])) + $cp_count++; +} +?> + + +
      +
      +

      나의 회원정보

      + + + 관리자 + + + 정보수정 + 로그아웃 +
      + +
      + + + diff --git a/AvocadoEdition/theme/basic/skin/outlogin/shop_side/style.css b/AvocadoEdition/theme/basic/skin/outlogin/shop_side/style.css new file mode 100644 index 0000000..67d0f6d --- /dev/null +++ b/AvocadoEdition/theme/basic/skin/outlogin/shop_side/style.css @@ -0,0 +1,64 @@ +@charset "utf-8"; + +/* 아웃로그인 스킨 */ +.s_ol {position:relative;border-bottom:1px solid #f6f6f6} +.s_ol h2 {width:115px;float:left;padding:15px 0;text-align:center} +.s_ol .join {width:114px;float:left;padding:15px 0;text-align:center;background:#f7f7f7;color:#6e6e6e} +.s_ol #s_ol_be_cate:after {display:block;visibility:hidden;clear:both;content:""} +.s_ol form {padding:20px} +.s_ol a.btn_admin {display:inline-block;padding:0 10px;height:25px;text-decoration:none;line-height:25px;vertical-align:middle} /* 관리자 전용 버튼 */ +.s_ol a.btn_admin:focus, .s_ol a.btn_admin:hover {text-decoration:none} + +#s_ol_before {} +#s_ol_before:after {display:block;visibility:hidden;clear:both;content:""} +#s_ol_before .s_ol_wr {position:relative;margin-bottom:5px} +#ol_id {display:block;width:100%;border:1px solid #d0d3db;padding:0 10px;height:35px;margin-bottom:5px;border-radius:3px} +#ol_pw {display:block;width:100%;border:1px solid #d0d3db;padding:0 10px;height:35px;margin-bottom:5px;border-radius:3px} +#ol_submit {width:100%;height:35px;background:#3a8afd;border-left:1px solid #ccc;color:#fff;font-weight:bold;font-size:1.167em;border-radius:3px} +#ol_svc {float:right;margin-top:5px;line-height:20px} +#ol_svc a {display:inline-block;border:1px solid #d5d9dd;color:#3a8afd;border-radius:2px;padding:2px 5px} +#ol_auto {float:left;line-height:20px;margin-top:5px} +#ol_auto label {color:#555;vertical-align:baseline} +#ol_auto input {width:13px;height:13px} +.ol_auto_wr:after {display:block;visibility:hidden;clear:both;content:""} +#sns_login {margin-top:0 !important;border-top:0 !important} +#sns_login h3 {position:absolute;font-size:0;line-height:0;overflow:hidden} + +#s_ol_after {border-bottom:1px solid #f6f6f6} +#s_ol_after_hd {position:relative;padding:10px;padding-left:80px;height:80px} +#s_ol_after_hd strong {display:block;margin:5px 0 10px} +#s_ol_after_hd .profile_img {position:absolute;top:15px;left:15px;display:inline-block} +#s_ol_after_hd .profile_img img {border-radius:50%;width:50px;height:50px} +#s_ol_after_hd .btn_admin {position:absolute;right:0;bottom:0;width:20px;height:20px;line-height:20px;padding:0;text-align:center;border-radius:50%;background:#000;vertical-align:baseline} + +#s_ol_after_info {display:inline-block;height:28px;line-height:22px;border:1px solid #d5d9dd;color:#3a8afd;border-radius:2px;padding:2px 5px} +#s_ol_after h2 {margin:0;padding:0;width:1px;height:1px;font-size:0;line-height:0;overflow:hidden} +#s_ol_after_hd .btn_b04 {line-height:23px;padding:0 5px} +#s_ol_after_private {zoom:1} +#s_ol_after_private:after {display:block;visibility:hidden;clear:both;content:""} +#s_ol_after_private li {text-align:left;position:relative;text-align:left} +#s_ol_after_private li:first-child a {border-left:0} +#s_ol_after_private a {display:block;background:#fff;color:#465168;line-height:18px;padding:10px 20px 10px 25px} +#s_ol_after_private a strong {display:inline-block;float:right;max-width:87px;overflow:hidden;white-space:nowrap;text-overflow:clip;color:#3a8afd;padding:0 5px;border-radius:15px;font-size:0.92em} +#s_ol_after_private a:hover strong {background:#4b8bff} +#s_ol_after_private li a:hover {color:#4b8bff;background:#f7f7f7} +#s_ol_after_private li a:hover:after {position:absolute;left:0;top:0;width:2px;height:38px;background:#3a8afd;content:""} +#s_ol_after_private li i {width:25px;color:#8c9eb0;margin-right:5px} +#s_ol_after_private li:hover i {color:#3a8afd} +#s_ol_after_private .win_point:hover strong {background:#37bc9b;color:#fff} +#s_ol_after_private .win_memo:hover strong {background:#ff8b77;color:#fff} +#s_ol_after_private .win_scrap:hover strong {background:#8cc152;color:#fff} +#s_ol_after_private .win_coupon:hover strong {background:#a352c1;color:#fff} + +#s_ol_after_logout {display:inline-block;height:28px;line-height:22px;border:1px solid #d5d9dd;color:#8a8a8a;border-radius:2px;padding:2px 5px} +#s_ol_after_logout:hover {color:#3c8bfd} +#ol_after_memo {margin-right:1px} +#ol_after_pt {margin-right:1px} + +.selec_chk {position:absolute;top:0;left:0;width:0;height:0;opacity:0;outline:0;z-index:-1;overflow:hidden} +.chk_box {position:relative} +.chk_box input[type="checkbox"] + label {padding-left:20px;color:#676e70} +.chk_box input[type="checkbox"] + label:hover{color:#2172f8} +.chk_box input[type="checkbox"] + label span {position:absolute;top:2px;left:0;width:15px;height:15px;display:block;margin:0;background:#fff;border:1px solid #d0d4df;border-radius:3px} +.chk_box input[type="checkbox"]:checked + label {color:#000} +.chk_box input[type="checkbox"]:checked + label span {background:url(./img/chk.png) no-repeat 50% 50% #3a8afd;border-color:#1471f6;border-radius:3px} diff --git a/AvocadoEdition/theme/basic/tail.php b/AvocadoEdition/theme/basic/tail.php new file mode 100644 index 0000000..430ad23 --- /dev/null +++ b/AvocadoEdition/theme/basic/tail.php @@ -0,0 +1,35 @@ + +
      + +